1
0
Fork 0
mirror of https://github.com/zeldaret/oot.git synced 2025-07-04 06:54:33 +00:00

Merge branch 'main' into doc_pause_menu

This commit is contained in:
Dragorn421 2024-02-05 22:34:08 +01:00
commit 740535129d
No known key found for this signature in database
GPG key ID: 381AEBAF3D429335
200 changed files with 28572 additions and 8184 deletions

View file

@ -7,6 +7,7 @@ BreakBeforeBraces: Attach
SpaceAfterCStyleCast: false SpaceAfterCStyleCast: false
Cpp11BracedListStyle: false Cpp11BracedListStyle: false
IndentCaseLabels: true IndentCaseLabels: true
IndentPPDirectives: None
BinPackArguments: true BinPackArguments: true
BinPackParameters: true BinPackParameters: true
AlignAfterOpenBracket: Align AlignAfterOpenBracket: Align
@ -18,6 +19,8 @@ AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false AllowShortLoopsOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: false AllowShortFunctionsOnASingleLine: false
AllowShortEnumsOnASingleLine: false
AlignEscapedNewlines: Left AlignEscapedNewlines: Left
AlignTrailingComments: true AlignTrailingComments: true
SortIncludes: false SortIncludes: false
TypenameMacros: ['BAD_RETURN']

22
Jenkinsfile vendored
View file

@ -4,6 +4,26 @@ pipeline {
} }
stages { stages {
stage('Check formatting (full)') {
when {
branch 'main'
}
steps {
echo 'Checking formatting on all files...'
sh 'python3 tools/check_format.py'
}
}
stage('Check formatting (modified)') {
when {
not {
branch 'main'
}
}
steps {
echo 'Checking formatting on modified files...'
sh 'python3 tools/check_format.py --verbose --compare-to origin/main'
}
}
stage('Setup') { stage('Setup') {
steps { steps {
sh 'cp /usr/local/etc/roms/baserom_oot.z64 baseroms/gc-eu-mq-dbg/baserom.z64' sh 'cp /usr/local/etc/roms/baserom_oot.z64 baseroms/gc-eu-mq-dbg/baserom.z64'
@ -25,7 +45,7 @@ pipeline {
} }
} }
steps { steps {
sh 'make -j' sh 'make -j RUN_CC_CHECK=0'
} }
} }
stage('Report Progress') { stage('Report Progress') {

129
Makefile
View file

@ -16,9 +16,13 @@ ORIG_COMPILER := 0
COMPILER := ido COMPILER := ido
# Target game version. Currently only the following version is supported: # Target game version. Currently only the following version is supported:
# gc-eu-mq-dbg GameCube Europe/PAL Master Quest Debug (default) # gc-eu-mq-dbg GameCube Europe/PAL Master Quest Debug (default)
# The following versions are work-in-progress and not yet matching:
# gc-eu-mq GameCube Europe/PAL Master Quest
VERSION := gc-eu-mq-dbg VERSION := gc-eu-mq-dbg
# Number of threads to extract and compress with # Number of threads to extract and compress with
N_THREADS := $(shell nproc) N_THREADS := $(shell nproc)
# Check code syntax with host compiler
RUN_CC_CHECK := 1
CFLAGS ?= CFLAGS ?=
CPPFLAGS ?= CPPFLAGS ?=
@ -47,19 +51,35 @@ ifeq ($(NON_MATCHING),1)
endif endif
# Version-specific settings # Version-specific settings
ifeq ($(VERSION),gc-eu-mq-dbg) ifeq ($(VERSION),gc-eu-mq)
OPTFLAGS := -O2 DEBUG := 0
CFLAGS += -DNON_MATCHING
CPPFLAGS += -DNON_MATCHING
COMPARE := 0
else ifeq ($(VERSION),gc-eu-mq-dbg)
DEBUG := 1
else else
$(error Unsupported version $(VERSION)) $(error Unsupported version $(VERSION))
endif endif
PROJECT_DIR := $(dir $(realpath $(firstword $(MAKEFILE_LIST)))) PROJECT_DIR := $(dir $(realpath $(firstword $(MAKEFILE_LIST))))
BUILD_DIR := build/$(VERSION) BUILD_DIR := build/$(VERSION)
EXPECTED_DIR := expected/$(BUILD_DIR)
BASEROM_DIR := baseroms/$(VERSION)
VENV := .venv VENV := .venv
MAKE = make MAKE = make
CFLAGS += -DOOT_DEBUG CPPFLAGS += -fno-dollars-in-identifiers -P
CPPFLAGS += -DOOT_DEBUG -fno-dollars-in-identifiers -P
ifeq ($(DEBUG),1)
CFLAGS += -DOOT_DEBUG=1
CPPFLAGS += -DOOT_DEBUG=1
OPTFLAGS := -O2
else
CFLAGS += -DNDEBUG -DOOT_DEBUG=0
CPPFLAGS += -DNDEBUG -DOOT_DEBUG=0
OPTFLAGS := -O2 -g3
endif
ifeq ($(OS),Windows_NT) ifeq ($(OS),Windows_NT)
DETECTED_OS=windows DETECTED_OS=windows
@ -147,7 +167,7 @@ endif
ifeq ($(COMPILER),ido) ifeq ($(COMPILER),ido)
# Have CC_CHECK pretend to be a MIPS compiler # Have CC_CHECK pretend to be a MIPS compiler
MIPS_BUILTIN_DEFS := -D_MIPS_ISA_MIPS2=2 -D_MIPS_ISA=_MIPS_ISA_MIPS2 -D_ABIO32=1 -D_MIPS_SIM=_ABIO32 -D_MIPS_SZINT=32 -D_MIPS_SZLONG=32 -D_MIPS_SZPTR=32 MIPS_BUILTIN_DEFS := -D_MIPS_ISA_MIPS2=2 -D_MIPS_ISA=_MIPS_ISA_MIPS2 -D_ABIO32=1 -D_MIPS_SIM=_ABIO32 -D_MIPS_SZINT=32 -D_MIPS_SZLONG=32 -D_MIPS_SZPTR=32
CC_CHECK = gcc -fno-builtin -fsyntax-only -funsigned-char -std=gnu90 -D_LANGUAGE_C -DNON_MATCHING $(MIPS_BUILTIN_DEFS) $(INC) $(CHECK_WARNINGS) CC_CHECK = gcc -fno-builtin -fsyntax-only -funsigned-char -std=gnu90 -D_LANGUAGE_C -DNON_MATCHING -DOOT_DEBUG=1 $(MIPS_BUILTIN_DEFS) $(INC) $(CHECK_WARNINGS)
ifeq ($(shell getconf LONG_BIT), 32) ifeq ($(shell getconf LONG_BIT), 32)
# Work around memory allocation bug in QEMU # Work around memory allocation bug in QEMU
export QEMU_GUEST_BASE := 1 export QEMU_GUEST_BASE := 1
@ -156,17 +176,23 @@ ifeq ($(COMPILER),ido)
CC_CHECK += -m32 CC_CHECK += -m32
endif endif
else else
CC_CHECK = @: RUN_CC_CHECK := 0
endif endif
OBJDUMP_FLAGS := -d -r -z -Mreg-names=32 OBJDUMP_FLAGS := -d -r -z -Mreg-names=32
DISASM_DATA_DIR := tools/disasm/$(VERSION)
DISASM_FLAGS += --custom-suffix _unknown --sequential-label-names --no-use-fpccsr --no-cop0-named-registers
DISASM_FLAGS += --config-dir $(DISASM_DATA_DIR) --symbol-addrs $(DISASM_DATA_DIR)/functions.txt --symbol-addrs $(DISASM_DATA_DIR)/variables.txt
#### Files #### #### Files ####
# ROM image # ROM image
ROMC := oot-$(VERSION)-compressed.z64 ROM := $(BUILD_DIR)/oot-$(VERSION).z64
ROM := oot-$(VERSION).z64 ROMC := $(ROM:.z64=-compressed.z64)
ELF := $(ROM:.z64=.elf) ELF := $(ROM:.z64=.elf)
MAP := $(ROM:.z64=.map)
LDSCRIPT := $(ROM:.z64=.ld)
# description of ROM segments # description of ROM segments
SPEC := spec SPEC := spec
@ -185,16 +211,23 @@ ASSET_FILES_OUT := $(foreach f,$(ASSET_FILES_XML:.xml=.c),$f) \
UNDECOMPILED_DATA_DIRS := $(shell find data -type d) UNDECOMPILED_DATA_DIRS := $(shell find data -type d)
BASEROM_SEGMENTS_DIR := $(BASEROM_DIR)/segments
BASEROM_BIN_FILES := $(wildcard $(BASEROM_SEGMENTS_DIR)/*)
# source files # source files
C_FILES := $(filter-out %.inc.c,$(foreach dir,$(SRC_DIRS) $(ASSET_BIN_DIRS),$(wildcard $(dir)/*.c))) C_FILES := $(filter-out %.inc.c,$(foreach dir,$(SRC_DIRS) $(ASSET_BIN_DIRS),$(wildcard $(dir)/*.c)))
S_FILES := $(foreach dir,$(SRC_DIRS) $(UNDECOMPILED_DATA_DIRS),$(wildcard $(dir)/*.s)) S_FILES := $(foreach dir,$(SRC_DIRS) $(UNDECOMPILED_DATA_DIRS),$(wildcard $(dir)/*.s))
BASEROM_BIN_FILES := $(wildcard baseroms/$(VERSION)/segments/*)
O_FILES := $(foreach f,$(S_FILES:.s=.o),$(BUILD_DIR)/$f) \ O_FILES := $(foreach f,$(S_FILES:.s=.o),$(BUILD_DIR)/$f) \
$(foreach f,$(C_FILES:.c=.o),$(BUILD_DIR)/$f) \ $(foreach f,$(C_FILES:.c=.o),$(BUILD_DIR)/$f) \
$(foreach f,$(BASEROM_BIN_FILES),$(BUILD_DIR)/baserom/$(notdir $f).o) $(foreach f,$(BASEROM_BIN_FILES),$(BUILD_DIR)/baserom/$(notdir $f).o)
OVL_RELOC_FILES := $(shell $(CPP) $(CPPFLAGS) $(SPEC) | $(SPEC_REPLACE_VARS) | grep -o '[^"]*_reloc.o' ) OVL_RELOC_FILES := $(shell $(CPP) $(CPPFLAGS) $(SPEC) | $(SPEC_REPLACE_VARS) | grep -o '[^"]*_reloc.o' )
DISASM_BASEROM := $(BASEROM_DIR)/baserom-decompressed.z64
DISASM_DATA_FILES := $(wildcard $(DISASM_DATA_DIR)/*.csv) $(wildcard $(DISASM_DATA_DIR)/*.txt)
DISASM_S_FILES := $(shell test -e $(PYTHON) && $(PYTHON) tools/disasm/list_generated_files.py -o $(EXPECTED_DIR) --config-dir $(DISASM_DATA_DIR))
DISASM_O_FILES := $(DISASM_S_FILES:.s=.o)
# Automatic dependency files # Automatic dependency files
# (Only asm_processor dependencies and reloc dependencies are handled for now) # (Only asm_processor dependencies and reloc dependencies are handled for now)
DEP_FILES := $(O_FILES:.o=.asmproc.d) $(OVL_RELOC_FILES:.o=.d) DEP_FILES := $(O_FILES:.o=.asmproc.d) $(OVL_RELOC_FILES:.o=.d)
@ -209,14 +242,41 @@ TEXTURE_FILES_OUT := $(foreach f,$(TEXTURE_FILES_PNG:.png=.inc.c),$(BUILD_DIR)/$
$(shell mkdir -p $(BUILD_DIR)/baserom $(BUILD_DIR)/assets/text $(foreach dir,$(SRC_DIRS) $(UNDECOMPILED_DATA_DIRS) $(ASSET_BIN_DIRS),$(BUILD_DIR)/$(dir))) $(shell mkdir -p $(BUILD_DIR)/baserom $(BUILD_DIR)/assets/text $(foreach dir,$(SRC_DIRS) $(UNDECOMPILED_DATA_DIRS) $(ASSET_BIN_DIRS),$(BUILD_DIR)/$(dir)))
ifeq ($(COMPILER),ido) ifeq ($(COMPILER),ido)
$(BUILD_DIR)/src/boot/stackcheck.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/__osMalloc.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/code_800FC620.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/code_800FCE80.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/code_800FD970.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/gfxprint.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/jpegutils.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/jpegdecoder.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/load.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/loadfragment2.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/logutils.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/mtxuty-cvt.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/padsetup.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/padutils.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/printutils.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/relocation.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/sleep.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/system_malloc.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/fault.o: CFLAGS += -trapuv $(BUILD_DIR)/src/code/fault.o: CFLAGS += -trapuv
$(BUILD_DIR)/src/code/fault.o: OPTFLAGS := -O2 -g3 $(BUILD_DIR)/src/code/fault.o: OPTFLAGS := -O2 -g3
$(BUILD_DIR)/src/code/fault_drawer.o: CFLAGS += -trapuv $(BUILD_DIR)/src/code/fault_drawer.o: CFLAGS += -trapuv
$(BUILD_DIR)/src/code/fault_drawer.o: OPTFLAGS := -O2 -g3 $(BUILD_DIR)/src/code/fault_drawer.o: OPTFLAGS := -O2 -g3
$(BUILD_DIR)/src/code/ucode_disas.o: OPTFLAGS := -O2 -g3 $(BUILD_DIR)/src/code/ucode_disas.o: OPTFLAGS := -O2 -g3
ifeq ($(DEBUG),1)
$(BUILD_DIR)/src/code/fmodf.o: OPTFLAGS := -g $(BUILD_DIR)/src/code/fmodf.o: OPTFLAGS := -g
$(BUILD_DIR)/src/code/__osMemset.o: OPTFLAGS := -g $(BUILD_DIR)/src/code/__osMemset.o: OPTFLAGS := -g
$(BUILD_DIR)/src/code/__osMemmove.o: OPTFLAGS := -g $(BUILD_DIR)/src/code/__osMemmove.o: OPTFLAGS := -g
else
$(BUILD_DIR)/src/code/fmodf.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/__osMemset.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/code/__osMemmove.o: OPTFLAGS := -O2
endif
$(BUILD_DIR)/src/audio/%.o: OPTFLAGS := -O2 $(BUILD_DIR)/src/audio/%.o: OPTFLAGS := -O2
@ -227,8 +287,14 @@ $(BUILD_DIR)/src/audio/general.o: CFLAGS += -signed
$(BUILD_DIR)/src/audio/sfx.o: CFLAGS += -use_readwrite_const $(BUILD_DIR)/src/audio/sfx.o: CFLAGS += -use_readwrite_const
$(BUILD_DIR)/src/audio/sequence.o: CFLAGS += -use_readwrite_const $(BUILD_DIR)/src/audio/sequence.o: CFLAGS += -use_readwrite_const
ifeq ($(DEBUG),1)
$(BUILD_DIR)/src/libultra/libc/absf.o: OPTFLAGS := -O2 -g3 $(BUILD_DIR)/src/libultra/libc/absf.o: OPTFLAGS := -O2 -g3
$(BUILD_DIR)/src/libultra/libc/sqrt.o: OPTFLAGS := -O2 -g3 $(BUILD_DIR)/src/libultra/libc/sqrt.o: OPTFLAGS := -O2 -g3
else
$(BUILD_DIR)/src/libultra/libc/absf.o: OPTFLAGS := -O2
$(BUILD_DIR)/src/libultra/libc/sqrt.o: OPTFLAGS := -O2
endif
$(BUILD_DIR)/src/libultra/libc/ll.o: OPTFLAGS := -O1 $(BUILD_DIR)/src/libultra/libc/ll.o: OPTFLAGS := -O1
$(BUILD_DIR)/src/libultra/libc/ll.o: MIPS_VERSION := -mips3 -32 $(BUILD_DIR)/src/libultra/libc/ll.o: MIPS_VERSION := -mips3 -32
$(BUILD_DIR)/src/libultra/libc/llcvt.o: OPTFLAGS := -O1 $(BUILD_DIR)/src/libultra/libc/llcvt.o: OPTFLAGS := -O1
@ -268,17 +334,17 @@ all: rom compress
rom: $(ROM) rom: $(ROM)
ifneq ($(COMPARE),0) ifneq ($(COMPARE),0)
@md5sum $(ROM) @md5sum $(ROM)
@md5sum -c baseroms/$(VERSION)/checksum.md5 @md5sum -c $(BASEROM_DIR)/checksum.md5
endif endif
compress: $(ROMC) compress: $(ROMC)
ifneq ($(COMPARE),0) ifneq ($(COMPARE),0)
@md5sum $(ROMC) @md5sum $(ROMC)
@md5sum -c baseroms/$(VERSION)/checksum-compressed.md5 @md5sum -c $(BASEROM_DIR)/checksum-compressed.md5
endif endif
clean: clean:
$(RM) -r $(ROMC) $(ROM) $(ELF) $(BUILD_DIR) $(RM) -r $(BUILD_DIR)
assetclean: assetclean:
$(RM) -r $(ASSET_BIN_DIRS) $(RM) -r $(ASSET_BIN_DIRS)
@ -287,19 +353,26 @@ assetclean:
$(RM) -r .extracted-assets.json $(RM) -r .extracted-assets.json
distclean: clean assetclean distclean: clean assetclean
$(RM) -r baseroms/$(VERSION)/segments $(RM) -r $(BASEROM_SEGMENTS_DIR)
$(MAKE) -C tools distclean $(MAKE) -C tools distclean
venv: venv:
test -d $(VENV) || python3 -m venv $(VENV) # Create the virtual environment if it doesn't exist.
# Delete the virtual environment directory if creation fails.
test -d $(VENV) || python3 -m venv $(VENV) || { rm -rf $(VENV); false; }
$(PYTHON) -m pip install -U pip $(PYTHON) -m pip install -U pip
$(PYTHON) -m pip install -U -r requirements.txt $(PYTHON) -m pip install -U -r requirements.txt
setup: venv setup: venv
$(MAKE) -C tools $(MAKE) -C tools
$(PYTHON) tools/decompress_baserom.py $(VERSION) $(PYTHON) tools/decompress_baserom.py $(VERSION)
$(PYTHON) extract_baserom.py $(PYTHON) tools/extract_baserom.py $(BASEROM_DIR)/baserom-decompressed.z64 -o $(BASEROM_SEGMENTS_DIR) --dmadata-start `cat $(BASEROM_DIR)/dmadata_start.txt` --dmadata-names $(BASEROM_DIR)/dmadata_names.txt
# TODO: for now, we only extract assets from the Debug ROM
ifeq ($(VERSION),gc-eu-mq-dbg)
$(PYTHON) extract_assets.py -j$(N_THREADS) $(PYTHON) extract_assets.py -j$(N_THREADS)
endif
disasm: $(DISASM_O_FILES)
run: $(ROM) run: $(ROM)
ifeq ($(N64_EMULATOR),) ifeq ($(N64_EMULATOR),)
@ -308,7 +381,7 @@ endif
$(N64_EMULATOR) $< $(N64_EMULATOR) $<
.PHONY: all rom compress clean assetclean distclean venv setup run .PHONY: all rom compress clean assetclean distclean venv setup disasm run
.DEFAULT_GOAL := rom .DEFAULT_GOAL := rom
#### Various Recipes #### #### Various Recipes ####
@ -317,12 +390,11 @@ $(ROM): $(ELF)
$(ELF2ROM) -cic 6105 $< $@ $(ELF2ROM) -cic 6105 $< $@
$(ROMC): $(ROM) $(ELF) $(BUILD_DIR)/compress_ranges.txt $(ROMC): $(ROM) $(ELF) $(BUILD_DIR)/compress_ranges.txt
# note: $(BUILD_DIR)/compress_ranges.txt should only be used for nonmatching builds. it works by chance for matching builds too though $(PYTHON) tools/compress.py --in $(ROM) --out $@ --dmadata-start `./tools/dmadata_start.sh $(NM) $(ELF)` --compress `cat $(BUILD_DIR)/compress_ranges.txt` --threads $(N_THREADS)
$(PYTHON) tools/compress.py --in $(ROM) --out $@ --dma-range `./tools/dmadata_range.sh $(NM) $(ELF)` --compress `cat $(BUILD_DIR)/compress_ranges.txt` --threads $(N_THREADS)
$(PYTHON) -m ipl3checksum sum --cic 6105 --update $@ $(PYTHON) -m ipl3checksum sum --cic 6105 --update $@
$(ELF): $(TEXTURE_FILES_OUT) $(ASSET_FILES_OUT) $(O_FILES) $(OVL_RELOC_FILES) $(BUILD_DIR)/ldscript.txt $(BUILD_DIR)/undefined_syms.txt $(ELF): $(TEXTURE_FILES_OUT) $(ASSET_FILES_OUT) $(O_FILES) $(OVL_RELOC_FILES) $(LDSCRIPT) $(BUILD_DIR)/undefined_syms.txt
$(LD) -T $(BUILD_DIR)/undefined_syms.txt -T $(BUILD_DIR)/ldscript.txt --no-check-sections --accept-unknown-input-arch --emit-relocs -Map $(BUILD_DIR)/z64.map -o $@ $(LD) -T $(LDSCRIPT) -T $(BUILD_DIR)/undefined_syms.txt --no-check-sections --accept-unknown-input-arch --emit-relocs -Map $(MAP) -o $@
## Order-only prerequisites ## Order-only prerequisites
# These ensure e.g. the O_FILES are built before the OVL_RELOC_FILES. # These ensure e.g. the O_FILES are built before the OVL_RELOC_FILES.
@ -339,13 +411,13 @@ $(O_FILES): | asset_files
$(BUILD_DIR)/$(SPEC): $(SPEC) $(BUILD_DIR)/$(SPEC): $(SPEC)
$(CPP) $(CPPFLAGS) $< | $(SPEC_REPLACE_VARS) > $@ $(CPP) $(CPPFLAGS) $< | $(SPEC_REPLACE_VARS) > $@
$(BUILD_DIR)/ldscript.txt: $(BUILD_DIR)/$(SPEC) $(LDSCRIPT): $(BUILD_DIR)/$(SPEC)
$(MKLDSCRIPT) $< $@ $(MKLDSCRIPT) $< $@
$(BUILD_DIR)/undefined_syms.txt: undefined_syms.txt $(BUILD_DIR)/undefined_syms.txt: undefined_syms.txt
$(CPP) $(CPPFLAGS) $< > $@ $(CPP) $(CPPFLAGS) $< > $@
$(BUILD_DIR)/baserom/%.o: baseroms/$(VERSION)/segments/% $(BUILD_DIR)/baserom/%.o: $(BASEROM_SEGMENTS_DIR)/%
$(OBJCOPY) -I binary -O elf32-big $< $@ $(OBJCOPY) -I binary -O elf32-big $< $@
$(BUILD_DIR)/data/%.o: data/%.s $(BUILD_DIR)/data/%.o: data/%.s
@ -387,18 +459,24 @@ $(BUILD_DIR)/src/code/z_game_dlftbls.o: include/tables/gamestate_table.h
$(BUILD_DIR)/src/code/z_scene_table.o: include/tables/scene_table.h include/tables/entrance_table.h $(BUILD_DIR)/src/code/z_scene_table.o: include/tables/scene_table.h include/tables/entrance_table.h
$(BUILD_DIR)/src/%.o: src/%.c $(BUILD_DIR)/src/%.o: src/%.c
ifneq ($(RUN_CC_CHECK),0)
$(CC_CHECK) $< $(CC_CHECK) $<
endif
$(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $< $(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $<
@$(OBJDUMP) $(OBJDUMP_FLAGS) $@ > $(@:.o=.s) @$(OBJDUMP) $(OBJDUMP_FLAGS) $@ > $(@:.o=.s)
$(BUILD_DIR)/src/libultra/libc/ll.o: src/libultra/libc/ll.c $(BUILD_DIR)/src/libultra/libc/ll.o: src/libultra/libc/ll.c
ifneq ($(RUN_CC_CHECK),0)
$(CC_CHECK) $< $(CC_CHECK) $<
endif
$(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $< $(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $<
$(PYTHON) tools/set_o32abi_bit.py $@ $(PYTHON) tools/set_o32abi_bit.py $@
@$(OBJDUMP) $(OBJDUMP_FLAGS) $@ > $(@:.o=.s) @$(OBJDUMP) $(OBJDUMP_FLAGS) $@ > $(@:.o=.s)
$(BUILD_DIR)/src/libultra/libc/llcvt.o: src/libultra/libc/llcvt.c $(BUILD_DIR)/src/libultra/libc/llcvt.o: src/libultra/libc/llcvt.c
ifneq ($(RUN_CC_CHECK),0)
$(CC_CHECK) $< $(CC_CHECK) $<
endif
$(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $< $(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $<
$(PYTHON) tools/set_o32abi_bit.py $@ $(PYTHON) tools/set_o32abi_bit.py $@
@$(OBJDUMP) $(OBJDUMP_FLAGS) $@ > $(@:.o=.s) @$(OBJDUMP) $(OBJDUMP_FLAGS) $@ > $(@:.o=.s)
@ -416,6 +494,13 @@ $(BUILD_DIR)/assets/%.bin.inc.c: assets/%.bin
$(BUILD_DIR)/assets/%.jpg.inc.c: assets/%.jpg $(BUILD_DIR)/assets/%.jpg.inc.c: assets/%.jpg
$(ZAPD) bren -eh -i $< -o $@ $(ZAPD) bren -eh -i $< -o $@
$(EXPECTED_DIR)/.disasm: $(DISASM_DATA_FILES)
$(PYTHON) tools/disasm/disasm.py $(DISASM_FLAGS) $(DISASM_BASEROM) -o $(EXPECTED_DIR) --split-functions $(EXPECTED_DIR)/functions
touch $@
$(EXPECTED_DIR)/%.o: $(EXPECTED_DIR)/.disasm
$(AS) $(ASFLAGS) $(@:.o=.s) -o $@
-include $(DEP_FILES) -include $(DEP_FILES)
# Print target for debugging # Print target for debugging

View file

@ -127,16 +127,16 @@ Make sure your path to the project is not too long, otherwise this process may e
make make
``` ```
If all goes well, a new ROM called "oot-gc-eu-mq-dbg.z64" should be built and the following text should be printed: If all goes well, a new ROM should be built at `build/gc-eu-mq-dbg/oot-gc-eu-mq-dbg.z64`, and the following text printed:
```bash ```bash
oot-gc-eu-mq-dbg.z64: OK build/gc-eu-mq-dbg/oot-gc-eu-mq-dbg.z64: OK
``` ```
If you instead see the following: If you instead see the following:
```bash ```bash
oot-gc-eu-mq-dbg.z64: FAILED build/gc-eu-mq-dbg/oot-gc-eu-mq-dbg.z64: FAILED
md5sum: WARNING: 1 computed checksum did NOT match md5sum: WARNING: 1 computed checksum did NOT match
``` ```

View file

@ -1 +1 @@
5831385a7f216370cdbea55616b12fed oot-gc-eu-mq-dbg-compressed.z64 9704bc98c20c20319cc1633fe02b6fc7 build/gc-eu-mq-dbg/oot-gc-eu-mq-dbg-compressed.z64

View file

@ -1 +1 @@
f0b7f35375f9cc8ca1b2d59d78e35405 oot-gc-eu-mq-dbg.z64 f0b7f35375f9cc8ca1b2d59d78e35405 build/gc-eu-mq-dbg/oot-gc-eu-mq-dbg.z64

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
0x12f70

View file

@ -0,0 +1 @@
1618403427e4344a57833043db5ce3c3 build/gc-eu-mq/oot-gc-eu-mq-compressed.z64

View file

@ -0,0 +1 @@
1a438f4235f8038856971c14a798122a build/gc-eu-mq/oot-gc-eu-mq.z64

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
0x07170

2728
diff.py

File diff suppressed because it is too large Load diff

1
diff.py Symbolic link
View file

@ -0,0 +1 @@
./tools/asm-differ/diff.py

View file

@ -1,6 +1,10 @@
def add_custom_arguments(parser):
parser.add_argument("-v", "--oot-version", help="OOT version", default="gc-eu-mq-dbg")
def apply(config, args): def apply(config, args):
config['mapfile'] = 'build/gc-eu-mq-dbg/z64.map' version = args.oot_version
config['myimg'] = 'oot-gc-eu-mq-dbg.z64' config['mapfile'] = f'build/{version}/oot-{version}.map'
config['baseimg'] = 'baseroms/gc-eu-mq-dbg/baserom-decompressed.z64' config['myimg'] = f'build/{version}/oot-{version}.z64'
config['makeflags'] = [] config['baseimg'] = f'baseroms/{version}/baserom-decompressed.z64'
config['makeflags'] = [f'VERSION={version}']
config['source_directories'] = ['src', 'include', 'spec'] config['source_directories'] = ['src', 'include', 'spec']

126
docs/retail_versions.md Normal file
View file

@ -0,0 +1,126 @@
# Decompiling retail versions
The next decompilation target for OOT is the PAL GameCube Master Quest ROM
(`gc-eu-mq`), because it is the retail version that is most similar to the Debug
ROM. Unfortunately there are still a lot of differences, many of which are
register or stack allocation differences because retail ROMs were built with
different compiler flags. However, once this version is done, future
retail versions should be much easier, as the changes between retail versions are
small in comparison.
Instead of `cp`ing a matching build into `expected/`, the target ROM is disassembled as `.s` files then
reassembled as `.o` files directly into `expected/build/gc-eu-mq` for diff tools.
This allows us to make progress matching code in parallel with solving other
problems (such as the build system, ROM organization, and BSS ordering). The
files in `tools/disasm/gc-eu-mq` say how to split the source files and where the
functions and variables are in the target ROM, and these may need to be updated
if there are mistakes or if function names change due to documentation work.
Unfortunately, the disassembly is not perfect, so a "correct" decompilation might
still show diffs with data symbols. We might improve this later, but these data
diffs are fine to ignore for now.
For register and stack allocation differences, often the code can be tweaked so
that it matches both the retail ROM while continuing to match the Debug ROM (for
example, by reordering assignments or moving a local variable declaration inside
an `if` block). Since retail MM versions use the same compiler flags as retail
OOT, checking MM decomp for similar code can help.
We can disable code that was removed in retail builds by adding
`#if OOT_DEBUG ... #endif` or `if (OOT_DEBUG) { ... }` around these parts of the
code. In order to keep the code readable, we should try to minimize the amount of
`#if` noise whenever possible.
## Setup
1. Copy your target PAL GameCube Master Quest ROM (non-debug) to
`baseroms/gc-eu-mq/baserom.z64`
1. Extract assets and ROM files **from the Debug ROM** by running
```sh
make setup -jN
```
if necessary, where `N` is the number of cores on your machine.
1. Build the non-matching test ROM by running
```sh
make setup -jN VERSION=gc-eu-mq
make -jN VERSION=gc-eu-mq
```
where `N` is the number of cores on your machine. This will build into
`build/gc-eu-mq` and produce `build/gc-eu-mq/oot-gc-eu-mq.z64`.
If you later want to delete all output files, run
```sh
make clean VERSION=gc-eu-mq
```
1. Disassemble the target ROM by running
```sh
make disasm -jN VERSION=gc-eu-mq
```
where `N` is the number of cores on your machine. The outputs will be written to
`expected/build/gc-eu-mq`.
Note that if you need to copy a matching build for the Debug ROM, you can use
```sh
mkdir -p expected/build
cp -r build/gc-eu-mq-dbg expected/build
```
to avoid clobbering the disassembly.
## Diff Tools
Note that many tools will require activating the Python virtual environment
in your terminal session. To do this, run:
```sh
source .venv/bin/activate
```
### retail_progress.py
Running `./retail_progress.py path/to/file.c` will attempt to figure out which functions
in a file still need to match for `gc-eu-mq`. To get an overview of diffs for
all files, run `./retail_progress.py` with no arguments.
### asm-differ / diff.py
To diff assembly for a single function in `gc-eu-mq`, run e.g.
```sh
./diff.py -mwo3 -v gc-eu-mq Math3D_CylTriVsIntersect
```
The `-v` flag tells `diff.py` to compare between `build/gc-eu-mq` and
`expected/build/gc-eu-mq`, and to use `make VERSION=gc-eu-mq` when rebuilding.
You may also want to diff the Debug ROM in another terminal with
```sh
./diff.py -mwo3 Math3D_CylTriVsIntersect
```
to ensure any changes still match there.
### Permuter and decomp.me
Disassembly for individual functions is written to
`expected/build/gc-eu-mq/functions`, so to get a [decomp.me](https://decomp.me/) scratch you can run
e.g.
```sh
decomp-permuter/import.py \
src/code/sys_math3d.c \
expected/build/gc-eu-mq/functions/src/code/sys_math3d/Math3D_CylTriVsIntersect.s \
VERSION=gc-eu-mq --decompme
```

View file

@ -41,7 +41,7 @@ You can create a `.vscode/c_cpp_properties.json` file with `C/C++: Edit Configur
{ {
"configurations": [ "configurations": [
{ {
"name": "Linux", "name": "N64 oot-gc-eu-mq-dbg",
"compilerPath": "${default}", // Needs to not be "" for -m32 to work "compilerPath": "${default}", // Needs to not be "" for -m32 to work
"compilerArgs": [ "compilerArgs": [
"-m32" // Removes integer truncation warnings with gbi macros "-m32" // Removes integer truncation warnings with gbi macros
@ -51,11 +51,12 @@ You can create a `.vscode/c_cpp_properties.json` file with `C/C++: Edit Configur
"${workspaceFolder}/**", "${workspaceFolder}/**",
"src", "src",
"build/gc-eu-mq-dbg", "build/gc-eu-mq-dbg",
"include" "include",
"include/libc"
], ],
"defines": [ "defines": [
"_LANGUAGE_C", // For gbi.h "_LANGUAGE_C", // For gbi.h
"OOT_DEBUG" // If targeting a debug version "OOT_DEBUG=1" // If targeting a debug version
], ],
"cStandard": "gnu89", // C89 + some GNU extensions from C99 like C++ comments "cStandard": "gnu89", // C89 + some GNU extensions from C99 like C++ comments
"cppStandard": "${default}" // Only ZAPD uses C++, so doesn't really matter "cppStandard": "${default}" // Only ZAPD uses C++, so doesn't really matter

File diff suppressed because it is too large Load diff

View file

@ -30,17 +30,17 @@ def firstDiffMain():
parser = argparse.ArgumentParser(description="Find the first difference(s) between the built ROM and the base ROM.") parser = argparse.ArgumentParser(description="Find the first difference(s) between the built ROM and the base ROM.")
parser.add_argument("-c", "--count", type=int, default=5, help="find up to this many instruction difference(s)") parser.add_argument("-c", "--count", type=int, default=5, help="find up to this many instruction difference(s)")
parser.add_argument("-v", "--version", help="Which version should be processed", default="gc-eu-mq-dbg") parser.add_argument("-v", "--oot-version", help="Which version should be processed", default="gc-eu-mq-dbg")
parser.add_argument("-a", "--add-colons", action='store_true', help="Add colon between bytes" ) parser.add_argument("-a", "--add-colons", action='store_true', help="Add colon between bytes" )
args = parser.parse_args() args = parser.parse_args()
buildFolder = Path("build") / args.version buildFolder = Path("build") / args.oot_version
BUILTROM = Path(f"oot-{args.version}.z64") BUILTROM = buildFolder / f"oot-{args.oot_version}.z64"
BUILTMAP = buildFolder / "z64.map" BUILTMAP = buildFolder / f"oot-{args.oot_version}.map"
EXPECTEDROM = Path(f"baseroms/{args.version}/baserom-decompressed.z64") EXPECTEDROM = Path(f"baseroms/{args.oot_version}/baserom-decompressed.z64")
EXPECTEDMAP = "expected" / BUILTMAP EXPECTEDMAP = "expected" / BUILTMAP
mapfile_parser.frontends.first_diff.doFirstDiff(BUILTMAP, EXPECTEDMAP, BUILTROM, EXPECTEDROM, args.count, mismatchSize=True, addColons=args.add_colons, bytesConverterCallback=decodeInstruction) mapfile_parser.frontends.first_diff.doFirstDiff(BUILTMAP, EXPECTEDMAP, BUILTROM, EXPECTEDROM, args.count, mismatchSize=True, addColons=args.add_colons, bytesConverterCallback=decodeInstruction)

537
include/audiothread_cmd.h Normal file
View file

@ -0,0 +1,537 @@
#ifndef AUDIOTHREAD_CMD_H
#define AUDIOTHREAD_CMD_H
/**
* Audio thread commands to safely transfer information/requests/data
* from the external graph thread to the internal audio thread
*/
typedef enum {
// Channel Commands
/* 0x00 */ AUDIOCMD_OP_NOOP,
/* 0x01 */ AUDIOCMD_OP_CHANNEL_SET_VOL_SCALE,
/* 0x02 */ AUDIOCMD_OP_CHANNEL_SET_VOL,
/* 0x03 */ AUDIOCMD_OP_CHANNEL_SET_PAN,
/* 0x04 */ AUDIOCMD_OP_CHANNEL_SET_FREQ_SCALE,
/* 0x05 */ AUDIOCMD_OP_CHANNEL_SET_REVERB_VOLUME,
/* 0x06 */ AUDIOCMD_OP_CHANNEL_SET_IO,
/* 0x07 */ AUDIOCMD_OP_CHANNEL_SET_PAN_WEIGHT,
/* 0x08 */ AUDIOCMD_OP_CHANNEL_SET_MUTE,
/* 0x09 */ AUDIOCMD_OP_CHANNEL_SET_MUTE_BEHAVIOR,
/* 0x0A */ AUDIOCMD_OP_CHANNEL_SET_VIBRATO_DEPTH,
/* 0x0B */ AUDIOCMD_OP_CHANNEL_SET_VIBRATO_RATE,
/* 0x0C */ AUDIOCMD_OP_CHANNEL_SET_COMB_FILTER_SIZE,
/* 0x0D */ AUDIOCMD_OP_CHANNEL_SET_COMB_FILTER_GAIN,
/* 0x0E */ AUDIOCMD_OP_CHANNEL_SET_STEREO,
// SeqPlayer Commands
/* 0x41 */ AUDIOCMD_OP_SEQPLAYER_FADE_VOLUME_SCALE = 0x41,
/* 0x46 */ AUDIOCMD_OP_SEQPLAYER_SET_IO = 0x46,
/* 0x47 */ AUDIOCMD_OP_SEQPLAYER_SET_TEMPO,
/* 0x48 */ AUDIOCMD_OP_SEQPLAYER_SET_TRANSPOSITION,
/* 0x49 */ AUDIOCMD_OP_SEQPLAYER_CHANGE_TEMPO,
/* 0x4A */ AUDIOCMD_OP_SEQPLAYER_FADE_TO_SET_VOLUME,
/* 0x4B */ AUDIOCMD_OP_SEQPLAYER_FADE_TO_SCALED_VOLUME,
/* 0x4C */ AUDIOCMD_OP_SEQPLAYER_RESET_VOLUME,
/* 0x4D */ AUDIOCMD_OP_SEQPLAYER_SET_BEND,
/* 0x4E */ AUDIOCMD_OP_SEQPLAYER_CHANGE_TEMPO_SEQTICKS,
// Global Commands
/* 0x81 */ AUDIOCMD_OP_GLOBAL_SYNC_LOAD_SEQ_PARTS = 0x81,
/* 0x82 */ AUDIOCMD_OP_GLOBAL_INIT_SEQPLAYER,
/* 0x83 */ AUDIOCMD_OP_GLOBAL_DISABLE_SEQPLAYER,
/* 0x85 */ AUDIOCMD_OP_GLOBAL_INIT_SEQPLAYER_SKIP_TICKS = 0x85,
/* 0x90 */ AUDIOCMD_OP_GLOBAL_SET_CHANNEL_MASK = 0x90,
/* 0xE0 */ AUDIOCMD_OP_GLOBAL_SET_DRUM_FONT = 0xE0,
/* 0xE1 */ AUDIOCMD_OP_GLOBAL_SET_SFX_FONT,
/* 0xE2 */ AUDIOCMD_OP_GLOBAL_SET_INSTRUMENT_FONT,
/* 0xE3 */ AUDIOCMD_OP_GLOBAL_POP_PERSISTENT_CACHE,
/* 0xF0 */ AUDIOCMD_OP_GLOBAL_SET_SOUND_MODE = 0xF0,
/* 0xF1 */ AUDIOCMD_OP_GLOBAL_MUTE,
/* 0xF2 */ AUDIOCMD_OP_GLOBAL_UNMUTE,
/* 0xF3 */ AUDIOCMD_OP_GLOBAL_SYNC_LOAD_INSTRUMENT,
/* 0xF4 */ AUDIOCMD_OP_GLOBAL_ASYNC_LOAD_SAMPLE_BANK,
/* 0xF5 */ AUDIOCMD_OP_GLOBAL_ASYNC_LOAD_FONT,
/* 0xF6 */ AUDIOCMD_OP_GLOBAL_DISCARD_SEQ_FONTS,
/* 0xF8 */ AUDIOCMD_OP_GLOBAL_STOP_AUDIOCMDS = 0xF8,
/* 0xF9 */ AUDIOCMD_OP_GLOBAL_RESET_AUDIO_HEAP,
/* 0xFA */ AUDIOCMD_OP_GLOBAL_NOOP_1, // used but no code exists for it
/* 0xFB */ AUDIOCMD_OP_GLOBAL_SET_CUSTOM_UPDATE_FUNCTION,
/* 0xFC */ AUDIOCMD_OP_GLOBAL_ASYNC_LOAD_SEQ,
/* 0xFD */ AUDIOCMD_OP_GLOBAL_NOOP_2, // used but no code exists for it
/* 0xFE */ AUDIOCMD_OP_GLOBAL_DISABLE_ALL_SEQPLAYERS
} AudioThreadCmdOp;
// Pass to a AUDIOCMD_CHANNEL_ command in place of a channelIndex to try and apply to all channels.
// Then uses `threadCmdChannelMask` to determine which channels to apply the command to.
#define AUDIOCMD_ALL_CHANNELS 0xFF
// ==== Audio Thread Channel Commands ====
/**
* Set the volumeScale on a given channel
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param channelIndex the index of the channel to modify
* @param volumeScale (f32) the volume scale for the sequence. No change in volume is 1.0f
*/
#define AUDIOCMD_CHANNEL_SET_VOL_SCALE(seqPlayerIndex, channelIndex, volumeScale) \
AudioThread_QueueCmdF32(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_VOL_SCALE, seqPlayerIndex, channelIndex, 0), \
volumeScale)
/**
* Set the volume on a given channel
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param channelIndex the index of the channel to modify
* @param volume (f32) the target volume for the sequence. Default volume is 1.0f
*/
#define AUDIOCMD_CHANNEL_SET_VOL(seqPlayerIndex, channelIndex, volume) \
AudioThread_QueueCmdF32(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_VOL, seqPlayerIndex, channelIndex, 0), volume)
/**
* Set the pan
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param channelIndex the index of the channel to modify
* @param pan (s8) the pan applied to the channel
*/
#define AUDIOCMD_CHANNEL_SET_PAN(seqPlayerIndex, channelIndex, pan) \
AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_PAN, seqPlayerIndex, channelIndex, 0), pan)
/**
* Set frequency scale
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param channelIndex the index of the channel to modify
* @param freqScale (f32) the scaling factor to shift the pitch.
*/
#define AUDIOCMD_CHANNEL_SET_FREQ_SCALE(seqPlayerIndex, channelIndex, freqScale) \
AudioThread_QueueCmdF32(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_FREQ_SCALE, seqPlayerIndex, channelIndex, 0), \
freqScale)
/**
* Set reverb volume
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param channelIndex the index of the channel to modify
* @param reverbVolume (s8) volume to set the reverb to (dry/wet mix)
*/
#define AUDIOCMD_CHANNEL_SET_REVERB_VOLUME(seqPlayerIndex, channelIndex, reverbVolume) \
AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_REVERB_VOLUME, seqPlayerIndex, channelIndex, 0), \
reverbVolume)
/**
* Write a value that can be read as input directly by the sequence itself. This will be set to the channel
* ioPort, which will only affect a single channel
*
* @param seqPlayerIndex the index of the seqPlayer to write the input to
* @param channelIndex the index of the channel to write the input to
* @param ioPort the index of the array to store the input-output value
* @param ioData (s8) the value that's written to the input-output array
*/
#define AUDIOCMD_CHANNEL_SET_IO(seqPlayerIndex, channelIndex, ioPort, ioData) \
AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_IO, (seqPlayerIndex), (channelIndex), (ioPort)), \
(ioData))
/**
* Set the proportion of pan that comes from the channel
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param channelIndex the index of the channel to modify
* @param panChannelWeight (s8) proportion of pan that comes from the channel.
* Set to 0 for layer-only, and 128 for channel-only.
* As the type used is `s8` and internally cast to u8 later,
* pass `-128` to produce 128, or just use 127 instead
*/
#define AUDIOCMD_CHANNEL_SET_PAN_WEIGHT(seqPlayerIndex, channelIndex, panChannelWeight) \
AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_PAN_WEIGHT, seqPlayerIndex, channelIndex, 0), \
panChannelWeight)
/**
* Mute a specified channel. How a muted channel behaves will depend on channel mute flags
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param channelIndex the index of the channel to modify
* @param muted (s8) set true to mute
*/
#define AUDIOCMD_CHANNEL_SET_MUTE(seqPlayerIndex, channelIndex, muted) \
AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_MUTE, seqPlayerIndex, channelIndex, 0), muted)
/**
* Set the muteBehavior for a specified channel
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param channelIndex the index of the channel to modify
* @param muteBehavior (s8) Affected how a muted channel behaves. See `MUTE_BEHAVIOR_` macros
*/
#define AUDIOCMD_CHANNEL_SET_MUTE_BEHAVIOR(seqPlayerIndex, channelIndex, muteBehavior) \
AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_MUTE_BEHAVIOR, seqPlayerIndex, channelIndex, 0), \
muteBehavior)
/**
* Set the vibrato depth (also called magnitude/amplitude/extent)
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param channelIndex the index of the channel to modify
* @param vibratoDepthTarget (s8) the vibrato depth scaled down by 1/8th
*/
#define AUDIOCMD_CHANNEL_SET_VIBRATO_DEPTH(seqPlayerIndex, channelIndex, vibratoDepthTarget) \
AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_VIBRATO_DEPTH, seqPlayerIndex, channelIndex, 0), \
vibratoDepthTarget)
/**
* Set the vibrato rate (freq/pitch)
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param channelIndex the index of the channel to modify
* @param vibratoRateTarget (s8) the vibrato rate scaled down by 1/32nd
*/
#define AUDIOCMD_CHANNEL_SET_VIBRATO_RATE(seqPlayerIndex, channelIndex, vibratoRateTarget) \
AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_VIBRATO_RATE, seqPlayerIndex, channelIndex, 0), \
vibratoRateTarget)
/**
* Set the comb filter size
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param channelIndex the index of the channel to modify
* @param combFilterSize (s8) delay number of sample bytes to offset and add back to itself
*/
#define AUDIOCMD_CHANNEL_SET_COMB_FILTER_SIZE(seqPlayerIndex, channelIndex, combFilterSize) \
AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_COMB_FILTER_SIZE, seqPlayerIndex, channelIndex, 0), \
combFilterSize)
/**
* Set the comb filter gain
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param channelIndex the index of the channel to modify
* @param combFilterGain (u16) strength of the signal added back to itself
*/
#define AUDIOCMD_CHANNEL_SET_COMB_FILTER_GAIN(seqPlayerIndex, channelIndex, combFilterGain) \
AudioThread_QueueCmdU16(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_COMB_FILTER_GAIN, seqPlayerIndex, channelIndex, 0), \
combFilterGain)
/**
* Set the stereo bits
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param channelIndex the index of the channel to modify
* @param stereoData (s8) bit-packed stereo information. See `StereoData`
*/
#define AUDIOCMD_CHANNEL_SET_STEREO(seqPlayerIndex, channelIndex, stereoData) \
AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_CHANNEL_SET_STEREO, seqPlayerIndex, channelIndex, 0), stereoData)
// ==== Audio Thread SeqPlayer Commands ====
/**
* Set the fade volume scale
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param fadeVolumeScale (f32) multiplicative scaling factor to apply to volume
*/
#define AUDIOCMD_SEQPLAYER_FADE_VOLUME_SCALE(seqPlayerIndex, fadeVolumeScale) \
AudioThread_QueueCmdF32(AUDIO_MK_CMD(AUDIOCMD_OP_SEQPLAYER_FADE_VOLUME_SCALE, seqPlayerIndex, 0, 0), \
fadeVolumeScale)
/**
* Write a value that can be read as input directly by the sequence itself. This will be set to the global
* ioPort, which can affect the entire sequence
*
* @param seqPlayerIndex the index of the seqPlayer to write the input to
* @param ioPort the index of the array to store the input-output value
* @param ioData (s8) the value that's written to the input-output array
*/
#define AUDIOCMD_SEQPLAYER_SET_IO(seqPlayerIndex, ioPort, ioData) \
AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_SEQPLAYER_SET_IO, seqPlayerIndex, 0, ioPort), ioData)
/**
* Set the tempo (bpm) of a sequence on a given seqPlayer
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param tempo (s32) the tempo for the sequence, in bpm
*/
#define AUDIOCMD_SEQPLAYER_SET_TEMPO(seqPlayerIndex, tempo) \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_SEQPLAYER_SET_TEMPO, seqPlayerIndex, 0, 0), tempo)
/**
* Set the transposition
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param transposition (s8) the number of semitones to increase or decrease by for all notes on the seqPlayer
*/
#define AUDIOCMD_SEQPLAYER_SET_TRANSPOSITION(seqPlayerIndex, transposition) \
AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_SEQPLAYER_SET_TRANSPOSITION, seqPlayerIndex, 0, 0), transposition)
/**
* Set tempoChange in bpm
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param tempoChange (s32) difference in tempo to change, in bpm
*/
#define AUDIOCMD_SEQPLAYER_CHANGE_TEMPO(seqPlayerIndex, tempoChange) \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_SEQPLAYER_CHANGE_TEMPO, seqPlayerIndex, 0, 0), tempoChange)
/**
* Set tempoChange in seqTicks per minute
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param tempoChange (s32) difference in tempo to change, in seqTicks per minute
*/
#define AUDIOCMD_SEQPLAYER_CHANGE_TEMPO_SEQTICKS(seqPlayerIndex, tempoChange) \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_SEQPLAYER_CHANGE_TEMPO_SEQTICKS, seqPlayerIndex, 0, 0), tempoChange)
/**
* Fade the volume to the target volume requested in the command
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param fadeVolume target volume to fade to
* @param fadeTimer (s32) number of ticks to fade to `fadeVolume`
*/
#define AUDIOCMD_SEQPLAYER_FADE_TO_SET_VOLUME(seqPlayerIndex, fadeVolume, fadeTimer) \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_SEQPLAYER_FADE_TO_SET_VOLUME, seqPlayerIndex, fadeVolume, 0), \
fadeTimer)
/**
* Fade the volume to the current volume scaled by a scale factor
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param fadeVolumeScale scaling factor to apply to volume to get the targetVolume
* @param fadeTimer (s32) number of ticks to fade to `targetVolume`
*/
#define AUDIOCMD_SEQPLAYER_FADE_TO_SCALED_VOLUME(seqPlayerIndex, fadeVolumeScale, fadeTimer) \
AudioThread_QueueCmdS32( \
AUDIO_MK_CMD(AUDIOCMD_OP_SEQPLAYER_FADE_TO_SCALED_VOLUME, seqPlayerIndex, fadeVolumeScale, 0), fadeTimer)
/**
* Reset to the default volume of the seqPlayer
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param fadeTimer (s32) number of ticks to fade the sequence back to its default volume
*/
#define AUDIOCMD_SEQPLAYER_RESET_VOLUME(seqPlayerIndex, fadeTimer) \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_SEQPLAYER_RESET_VOLUME, seqPlayerIndex, 0, 0), fadeTimer)
/**
* Set the bend
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param bend (f32) ratio relative to 1.0f to scale channel frequencies by
*/
#define AUDIOCMD_SEQPLAYER_SET_BEND(seqPlayerIndex, bend) \
AudioThread_QueueCmdF32(AUDIO_MK_CMD(AUDIOCMD_OP_SEQPLAYER_SET_BEND, seqPlayerIndex, 0, 0), bend)
// ==== Audio Thread Global Commands ====
/**
* Synchronously load a sequence in parts
*
* @param seqId the id of the sequence to load, see `SeqId`
* @param flags set `& 1` to load the sequence, set `& 2` to load the soundfonts
*/
#define AUDIOCMD_GLOBAL_SYNC_LOAD_SEQ_PARTS(seqId, flags) \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_SYNC_LOAD_SEQ_PARTS, 0, seqId, flags), 0)
/**
* Synchronously initialize a sequence player
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param seqId the id of the sequence to play, see `SeqId`
* @param fadeInTimer (s32) number of ticks to fade in the sequence to the requested volume
*/
#define AUDIOCMD_GLOBAL_INIT_SEQPLAYER(seqPlayerIndex, seqId, fadeInTimer) \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_INIT_SEQPLAYER, seqPlayerIndex, seqId, 0), fadeInTimer)
/**
* Disable a sequence player
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param fadeOutTimer (s32) number of ticks to fade out the sequence
*/
#define AUDIOCMD_GLOBAL_DISABLE_SEQPLAYER(seqPlayerIndex, fadeOutTimer) \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_DISABLE_SEQPLAYER, seqPlayerIndex, 0, 0), fadeOutTimer)
/**
* Synchronously initialize a sequence player and skip ticks,
* allowing the sequence to start somewhere other than the beginning of the sequences
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param seqId the id of the sequence to play, see `SeqId`
* @param skipTicks (s32) number of ticks to skip before starting the sequence
*/
#define AUDIOCMD_GLOBAL_INIT_SEQPLAYER_SKIP_TICKS(seqPlayerIndex, seqId, skipTicks) \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_INIT_SEQPLAYER_SKIP_TICKS, seqPlayerIndex, seqId, 0), \
skipTicks)
/**
* When processing an audio thread channel command on all channels, set which channels to process
*
* @param seqPlayerIndex the index of the seqPlayer to modify
* @param threadCmdChannelMask (u16) bitfield for 16 channels. Turn bit on to allow audio thread commands of type
* "Channel" to process that channel with `AUDIOCMD_ALL_CHANNELS` set.
*/
#define AUDIOCMD_GLOBAL_SET_CHANNEL_MASK(seqPlayerIndex, threadCmdChannelMask) \
AudioThread_QueueCmdU16(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_SET_CHANNEL_MASK, seqPlayerIndex, 0, 0), \
threadCmdChannelMask)
/**
* Set a drum ptr within a soundfont
*
* @param fontId the id of the soundfont to set the drum in
* @param drumId the id of the drum to set
* @param drumPtr (s32) the ptr to the `Drum` struct
*/
#define AUDIOCMD_GLOBAL_SET_DRUM_FONT(fontId, drumId, drumPtr) \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_SET_DRUM_FONT, fontId, drumId, 0), drumPtr)
/**
* Set a soundeffect ptr within a soundfont
*
* @param fontId the id of the soundfont to set the sound effect in
* @param soundEffectId the id of the sound effect to set
* @param soundEffectPtr (s32) the ptr to the `SoundEffect` struct
*/
#define AUDIOCMD_GLOBAL_SET_SFX_FONT(fontId, soundEffectId, soundEffectPtr) \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_SET_SFX_FONT, fontId, soundEffectId, 0), soundEffectPtr)
/**
* Set an instrument ptr within a soundfont
*
* @param fontId the id of the soundfont to set the instrument in
* @param instId the id of the instrument to set
* @param instPtr (s32) the ptr to the `Instrument` struct
*/
#define AUDIOCMD_GLOBAL_SET_INSTRUMENT_FONT(fontId, instId, instPtr) \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_SET_INSTRUMENT_FONT, fontId, instId, 0), instPtr)
/**
* Pop the persistent cache of the specified table
*
* @param tableType (s32) see the `SampleBankTableType` enum
*/
#define AUDIOCMD_GLOBAL_POP_PERSISTENT_CACHE(tableType) \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_POP_PERSISTENT_CACHE, 0, 0, 0), tableType)
/**
* Change the sound mode of audio
*
* @param soundMode (s32) see the `SoundMode` enum
*/
#define AUDIOCMD_GLOBAL_SET_SOUND_MODE(soundMode) \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_SET_SOUND_MODE, 0, 0, 0), soundMode)
/**
* Mute all sequence players
*/
#define AUDIOCMD_GLOBAL_MUTE() \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_MUTE, 0, 0, 0), 0)
/**
* Unmute all sequence players
*
* @param restartNotes (s32) if set to 1, then notes with the `MUTE_BEHAVIOR_STOP_SAMPLES` flag set
* are marked as finished for all seqPlayers
*/
#define AUDIOCMD_GLOBAL_UNMUTE(restartNotes) \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_UNMUTE, 0, 0, 0), restartNotes)
/**
* Synchronously load an instrument
*
* @param fontId the id of the soundfont to load
* @param instId If below 0x7F, the id of the instrument to use. If equal to 0x7F, load the drum using the drumId
* @param drumId the id of the drum to use
*/
#define AUDIOCMD_GLOBAL_SYNC_LOAD_INSTRUMENT(fontId, instId, drumId) \
AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_SYNC_LOAD_INSTRUMENT, fontId, instId, drumId), 0)
/**
* Asynchronously load a sample bank
*
* @param sampleBankId the id of the samplebank to load
* @param retData return data from `externalLoadQueue`
*/
#define AUDIOCMD_GLOBAL_ASYNC_LOAD_SAMPLE_BANK(sampleBankId, retData) \
AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_ASYNC_LOAD_SAMPLE_BANK, sampleBankId, 0, retData), 0)
/**
* Asynchronously load a font
*
* @param fontId the id of the soundfont to load
* @param retData return data from `externalLoadQueue`
*/
#define AUDIOCMD_GLOBAL_ASYNC_LOAD_FONT(fontId, retData) \
AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_ASYNC_LOAD_FONT, fontId, 0, retData), 0)
/**
* Discard sequence fonts
*
* @param seqId the id of the sequence to discard, see `SeqId`
*/
#define AUDIOCMD_GLOBAL_DISCARD_SEQ_FONTS(seqId) \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_DISCARD_SEQ_FONTS, 0, seqId, 0), 0)
/**
* Stop processing all audio thread commands
*/
#define AUDIOCMD_GLOBAL_STOP_AUDIOCMDS() \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_STOP_AUDIOCMDS, 0, 0, 0), 0)
/**
* Reset Audio Heap
*
* @param specId (s32) index for the audio specifications to set high-level audio parameters
*/
#define AUDIOCMD_GLOBAL_RESET_AUDIO_HEAP(specId) \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_RESET_AUDIO_HEAP, 0, 0, 0), specId)
/**
* No Operation. No code exists for this OP
*
* @param arg0 No info
* @param arg1 No info
* @param arg2 No info
* @param data (s32) No info
*/
#define AUDIOCMD_GLOBAL_NOOP_1(arg0, arg1, arg2, data) \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_NOOP_1, arg0, arg1, arg2), data)
/**
* Set a custom function that runs every audio thread update, see `AudioCustomUpdateFunction`
*
* @param functionPtr (s32) address of the function to run once every audio frame
*/
#define AUDIOCMD_GLOBAL_SET_CUSTOM_UPDATE_FUNCTION(functionPtr) \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_SET_CUSTOM_UPDATE_FUNCTION, 0, 0, 0), functionPtr)
/**
* Asynchronously load a sequence
*
* @param seqId the id of the sequence to load, see `SeqId`
* @param retData return data from `externalLoadQueue`
*/
#define AUDIOCMD_GLOBAL_ASYNC_LOAD_SEQ(seqId, retData) \
AudioThread_QueueCmdS8(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_ASYNC_LOAD_SEQ, seqId, 0, retData), 0)
/**
* No Operation. No code exists for this OP
*
* @param arg0 No info
* @param arg1 No info
* @param arg2 No info
* @param data (s32) No info
*/
#define AUDIOCMD_GLOBAL_NOOP_2(arg0, arg1, arg2, data) \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_NOOP_2, arg0, arg1, arg2), data)
/**
* Disable all sequence players
*
* @param flags (s32) Set `& 1` to discard all sequences.
*
* @note Setting `& 3` will also only discard sampled notes, but the sequences are disabled anyway.
* Not setting `& 1` should make this command useless TODO: Test
*/
#define AUDIOCMD_GLOBAL_DISABLE_ALL_SEQPLAYERS(flags) \
AudioThread_QueueCmdS32(AUDIO_MK_CMD(AUDIOCMD_OP_GLOBAL_DISABLE_ALL_SEQPLAYERS, 0, 0, 0), flags)
#endif

View file

@ -29,35 +29,32 @@ void ViConfig_UpdateVi(u32 black);
void ViConfig_UpdateBlack(void); void ViConfig_UpdateBlack(void);
void* Yaz0_FirstDMA(void); void* Yaz0_FirstDMA(void);
void* Yaz0_NextDMA(u8* curSrcPos); void* Yaz0_NextDMA(u8* curSrcPos);
void Yaz0_DecompressImpl(Yaz0Header* hdr, u8* dst); void Yaz0_DecompressImpl(u8* src, u8* dst);
void Yaz0_Decompress(uintptr_t romStart, u8* dst, size_t size); void Yaz0_Decompress(uintptr_t romStart, u8* dst, size_t size);
void Locale_Init(void); void Locale_Init(void);
void Locale_ResetRegion(void); void Locale_ResetRegion(void);
u32 func_80001F48(void); #if OOT_DEBUG
u32 func_80001F8C(void);
u32 Locale_IsRegionNative(void);
void isPrintfInit(void); void isPrintfInit(void);
#endif
void rmonPrintf(const char* fmt, ...); void rmonPrintf(const char* fmt, ...);
#if OOT_DEBUG
void* is_proutSyncPrintf(void* arg, const char* str, size_t count); void* is_proutSyncPrintf(void* arg, const char* str, size_t count);
NORETURN void func_80002384(const char* exp, const char* file, u32 line); NORETURN void func_80002384(const char* exp, const char* file, u32 line);
#endif
OSPiHandle* osDriveRomInit(void); OSPiHandle* osDriveRomInit(void);
void Mio0_Decompress(Yaz0Header* hdr, u8* dst); void Mio0_Decompress(u8* src, u8* dst);
void StackCheck_Init(StackEntry* entry, void* stackBottom, void* stackTop, u32 initValue, s32 minSpace, void StackCheck_Init(StackEntry* entry, void* stackBottom, void* stackTop, u32 initValue, s32 minSpace,
const char* name); const char* name);
void StackCheck_Cleanup(StackEntry* entry); void StackCheck_Cleanup(StackEntry* entry);
u32 StackCheck_GetState(StackEntry* entry); u32 StackCheck_GetState(StackEntry* entry);
u32 StackCheck_CheckAll(void); u32 StackCheck_CheckAll(void);
u32 StackCheck_Check(StackEntry* entry); u32 StackCheck_Check(StackEntry* entry);
f32 LogUtils_CheckFloatRange(const char* exp, s32 line, const char* valueName, f32 value, const char* minName, f32 min, #if OOT_DEBUG
const char* maxName, f32 max);
s32 LogUtils_CheckIntRange(const char* exp, s32 line, const char* valueName, s32 value, const char* minName, s32 min,
const char* maxName, s32 max);
void LogUtils_LogHexDump(void* ptr, s32 size0); void LogUtils_LogHexDump(void* ptr, s32 size0);
void LogUtils_LogPointer(s32 value, u32 max, void* ptr, const char* name, const char* file, s32 line);
void LogUtils_CheckBoundary(const char* name, s32 value, s32 unk, const char* file, s32 line);
void LogUtils_CheckNullPointer(const char* exp, void* ptr, const char* file, s32 line); void LogUtils_CheckNullPointer(const char* exp, void* ptr, const char* file, s32 line);
void LogUtils_CheckValidPointer(const char* exp, void* ptr, const char* file, s32 line); void LogUtils_CheckValidPointer(const char* exp, void* ptr, const char* file, s32 line);
void LogUtils_LogThreadId(const char* name, s32 line); void LogUtils_LogThreadId(const char* name, s32 line);
#endif
void LogUtils_HungupThread(const char* name, s32 line); void LogUtils_HungupThread(const char* name, s32 line);
void LogUtils_ResetHungup(void); void LogUtils_ResetHungup(void);
void __osPiCreateAccessQueue(void); void __osPiCreateAccessQueue(void);
@ -615,8 +612,10 @@ u16 WaterBox_GetBgCamSetting(CollisionContext* colCtx, WaterBox* waterBox);
u32 WaterBox_GetLightIndex(CollisionContext* colCtx, WaterBox* waterBox); u32 WaterBox_GetLightIndex(CollisionContext* colCtx, WaterBox* waterBox);
s32 func_80042708(CollisionPoly* polyA, CollisionPoly* polyB, Vec3f* point, Vec3f* closestPoint); s32 func_80042708(CollisionPoly* polyA, CollisionPoly* polyB, Vec3f* point, Vec3f* closestPoint);
s32 func_800427B4(CollisionPoly* polyA, CollisionPoly* polyB, Vec3f* pointA, Vec3f* pointB, Vec3f* closestPoint); s32 func_800427B4(CollisionPoly* polyA, CollisionPoly* polyB, Vec3f* pointA, Vec3f* pointB, Vec3f* closestPoint);
#if OOT_DEBUG
void BgCheck_DrawDynaCollision(PlayState*, CollisionContext*); void BgCheck_DrawDynaCollision(PlayState*, CollisionContext*);
void BgCheck_DrawStaticCollision(PlayState*, CollisionContext*); void BgCheck_DrawStaticCollision(PlayState*, CollisionContext*);
#endif
void func_80043334(CollisionContext* colCtx, Actor* actor, s32 bgId); void func_80043334(CollisionContext* colCtx, Actor* actor, s32 bgId);
s32 DynaPolyActor_TransformCarriedActor(CollisionContext* colCtx, s32 bgId, Actor* carriedActor); s32 DynaPolyActor_TransformCarriedActor(CollisionContext* colCtx, s32 bgId, Actor* carriedActor);
void DynaPolyActor_Init(DynaPolyActor* dynaActor, s32 transformFlags); void DynaPolyActor_Init(DynaPolyActor* dynaActor, s32 transformFlags);
@ -661,8 +660,10 @@ s32 func_8005B198(void);
s16 Camera_SetFinishedFlag(Camera* camera); s16 Camera_SetFinishedFlag(Camera* camera);
DamageTable* DamageTable_Get(s32 index); DamageTable* DamageTable_Get(s32 index);
void DamageTable_Clear(DamageTable* table); void DamageTable_Clear(DamageTable* table);
#if OOT_DEBUG
void Collider_DrawRedPoly(GraphicsContext* gfxCtx, Vec3f* vA, Vec3f* vB, Vec3f* vC); void Collider_DrawRedPoly(GraphicsContext* gfxCtx, Vec3f* vA, Vec3f* vB, Vec3f* vC);
void Collider_DrawPoly(GraphicsContext* gfxCtx, Vec3f* vA, Vec3f* vB, Vec3f* vC, u8 r, u8 g, u8 b); void Collider_DrawPoly(GraphicsContext* gfxCtx, Vec3f* vA, Vec3f* vB, Vec3f* vC, u8 r, u8 g, u8 b);
#endif
s32 Collider_InitJntSph(PlayState* play, ColliderJntSph* jntSph); s32 Collider_InitJntSph(PlayState* play, ColliderJntSph* jntSph);
s32 Collider_FreeJntSph(PlayState* play, ColliderJntSph* jntSph); s32 Collider_FreeJntSph(PlayState* play, ColliderJntSph* jntSph);
s32 Collider_DestroyJntSph(PlayState* play, ColliderJntSph* jntSph); s32 Collider_DestroyJntSph(PlayState* play, ColliderJntSph* jntSph);
@ -710,8 +711,10 @@ void CollisionCheck_DestroyContext(PlayState* play, CollisionCheckContext* colCh
void CollisionCheck_ClearContext(PlayState* play, CollisionCheckContext* colChkCtx); void CollisionCheck_ClearContext(PlayState* play, CollisionCheckContext* colChkCtx);
void CollisionCheck_EnableSAC(PlayState* play, CollisionCheckContext* colChkCtx); void CollisionCheck_EnableSAC(PlayState* play, CollisionCheckContext* colChkCtx);
void CollisionCheck_DisableSAC(PlayState* play, CollisionCheckContext* colChkCtx); void CollisionCheck_DisableSAC(PlayState* play, CollisionCheckContext* colChkCtx);
#if OOT_DEBUG
void Collider_Draw(PlayState* play, Collider* col); void Collider_Draw(PlayState* play, Collider* col);
void CollisionCheck_DrawCollision(PlayState* play, CollisionCheckContext* colChkCtx); void CollisionCheck_DrawCollision(PlayState* play, CollisionCheckContext* colChkCtx);
#endif
s32 CollisionCheck_SetAT(PlayState* play, CollisionCheckContext* colChkCtx, Collider* collider); s32 CollisionCheck_SetAT(PlayState* play, CollisionCheckContext* colChkCtx, Collider* collider);
s32 CollisionCheck_SetAT_SAC(PlayState* play, CollisionCheckContext* colChkCtx, Collider* collider, s32 index); s32 CollisionCheck_SetAT_SAC(PlayState* play, CollisionCheckContext* colChkCtx, Collider* collider, s32 index);
s32 CollisionCheck_SetAC(PlayState* play, CollisionCheckContext* colChkCtx, Collider* collider); s32 CollisionCheck_SetAC(PlayState* play, CollisionCheckContext* colChkCtx, Collider* collider);
@ -753,7 +756,9 @@ s32 func_800635D0(s32);
void Regs_Init(void); void Regs_Init(void);
void DebugCamera_ScreenText(u8 x, u8 y, const char* text); void DebugCamera_ScreenText(u8 x, u8 y, const char* text);
void DebugCamera_ScreenTextColored(u8 x, u8 y, u8 colorIndex, const char* text); void DebugCamera_ScreenTextColored(u8 x, u8 y, u8 colorIndex, const char* text);
#if OOT_DEBUG
void Regs_UpdateEditor(Input* input); void Regs_UpdateEditor(Input* input);
#endif
void Debug_DrawText(GraphicsContext* gfxCtx); void Debug_DrawText(GraphicsContext* gfxCtx);
void DebugDisplay_Init(void); void DebugDisplay_Init(void);
DebugDispObject* DebugDisplay_AddObject(f32 posX, f32 posY, f32 posZ, s16 rotX, s16 rotY, s16 rotZ, f32 scaleX, DebugDispObject* DebugDisplay_AddObject(f32 posX, f32 posY, f32 posZ, s16 rotX, s16 rotY, s16 rotZ, f32 scaleX,
@ -896,22 +901,24 @@ Lights* Lights_NewAndDraw(GraphicsContext* gfxCtx, u8 ambientR, u8 ambientG, u8
Lights* Lights_New(GraphicsContext* gfxCtx, u8 ambientR, u8 ambientG, u8 ambientB); Lights* Lights_New(GraphicsContext* gfxCtx, u8 ambientR, u8 ambientG, u8 ambientB);
void Lights_GlowCheck(PlayState* play); void Lights_GlowCheck(PlayState* play);
void Lights_DrawGlow(PlayState* play); void Lights_DrawGlow(PlayState* play);
void ZeldaArena_CheckPointer(void* ptr, u32 size, const char* name, const char* action);
void* ZeldaArena_Malloc(u32 size); void* ZeldaArena_Malloc(u32 size);
void* ZeldaArena_MallocDebug(u32 size, const char* file, s32 line);
void* ZeldaArena_MallocR(u32 size); void* ZeldaArena_MallocR(u32 size);
void* ZeldaArena_MallocRDebug(u32 size, const char* file, s32 line);
void* ZeldaArena_Realloc(void* ptr, u32 newSize); void* ZeldaArena_Realloc(void* ptr, u32 newSize);
void* ZeldaArena_ReallocDebug(void* ptr, u32 newSize, const char* file, s32 line);
void ZeldaArena_Free(void* ptr); void ZeldaArena_Free(void* ptr);
void ZeldaArena_FreeDebug(void* ptr, const char* file, s32 line);
void* ZeldaArena_Calloc(u32 num, u32 size); void* ZeldaArena_Calloc(u32 num, u32 size);
void ZeldaArena_Display(void);
void ZeldaArena_GetSizes(u32* outMaxFree, u32* outFree, u32* outAlloc); void ZeldaArena_GetSizes(u32* outMaxFree, u32* outFree, u32* outAlloc);
void ZeldaArena_Check(void); void ZeldaArena_Check(void);
void ZeldaArena_Init(void* start, u32 size); void ZeldaArena_Init(void* start, u32 size);
void ZeldaArena_Cleanup(void); void ZeldaArena_Cleanup(void);
u8 ZeldaArena_IsInitialized(void); u8 ZeldaArena_IsInitialized(void);
#if OOT_DEBUG
void ZeldaArena_CheckPointer(void* ptr, u32 size, const char* name, const char* action);
void* ZeldaArena_MallocDebug(u32 size, const char* file, s32 line);
void* ZeldaArena_MallocRDebug(u32 size, const char* file, s32 line);
void* ZeldaArena_ReallocDebug(void* ptr, u32 newSize, const char* file, s32 line);
void ZeldaArena_FreeDebug(void* ptr, const char* file, s32 line);
void ZeldaArena_Display(void);
#endif
void MapMark_Init(PlayState* play); void MapMark_Init(PlayState* play);
void MapMark_ClearPointers(PlayState* play); void MapMark_ClearPointers(PlayState* play);
void MapMark_Draw(PlayState* play); void MapMark_Draw(PlayState* play);
@ -1172,12 +1179,14 @@ void View_InitDistortion(View* view);
void View_ClearDistortion(View* view); void View_ClearDistortion(View* view);
void View_SetDistortion(View* view, Vec3f orientation, Vec3f scale, f32 speed); void View_SetDistortion(View* view, Vec3f orientation, Vec3f scale, f32 speed);
s32 View_StepDistortion(View* view, Mtx* projectionMtx); s32 View_StepDistortion(View* view, Mtx* projectionMtx);
void View_Apply(View* view, s32 mask); s32 View_Apply(View* view, s32 mask);
s32 View_ApplyOrthoToOverlay(View* view); s32 View_ApplyOrthoToOverlay(View* view);
s32 View_ApplyPerspectiveToOverlay(View* view); s32 View_ApplyPerspectiveToOverlay(View* view);
s32 View_UpdateViewingMatrix(View* view); s32 View_UpdateViewingMatrix(View* view);
s32 View_ApplyTo(View* view, s32 mask, Gfx** gfxP); s32 View_ApplyTo(View* view, s32 mask, Gfx** gfxP);
#if OOT_DEBUG
s32 View_ErrorCheckEyePosition(f32 eyeX, f32 eyeY, f32 eyeZ); s32 View_ErrorCheckEyePosition(f32 eyeX, f32 eyeY, f32 eyeZ);
#endif
void ViMode_LogPrint(OSViMode* osViMode); void ViMode_LogPrint(OSViMode* osViMode);
void ViMode_Configure(ViMode* viMode, s32 type, s32 tvType, s32 loRes, s32 antialiasOff, s32 modeN, s32 fb16Bit, void ViMode_Configure(ViMode* viMode, s32 type, s32 tvType, s32 loRes, s32 antialiasOff, s32 modeN, s32 fb16Bit,
s32 width, s32 height, s32 leftAdjust, s32 rightAdjust, s32 upperAdjust, s32 lowerAdjust); s32 width, s32 height, s32 leftAdjust, s32 rightAdjust, s32 upperAdjust, s32 lowerAdjust);
@ -1295,9 +1304,7 @@ void func_800C213C(PreRender* this, Gfx** gfxP);
void PreRender_RestoreFramebuffer(PreRender* this, Gfx** gfxP); void PreRender_RestoreFramebuffer(PreRender* this, Gfx** gfxP);
void PreRender_CopyImageRegion(PreRender* this, Gfx** gfxP); void PreRender_CopyImageRegion(PreRender* this, Gfx** gfxP);
void PreRender_ApplyFilters(PreRender* this); void PreRender_ApplyFilters(PreRender* this);
void GameState_FaultPrint(void);
void GameState_SetFBFilter(Gfx** gfxP); void GameState_SetFBFilter(Gfx** gfxP);
void GameState_DrawInputDisplay(u16 input, Gfx** gfxP);
void GameState_Draw(GameState* gameState, GraphicsContext* gfxCtx); void GameState_Draw(GameState* gameState, GraphicsContext* gfxCtx);
void GameState_SetFrameBuffer(GraphicsContext* gfxCtx); void GameState_SetFrameBuffer(GraphicsContext* gfxCtx);
void GameState_ReqPadData(GameState* gameState); void GameState_ReqPadData(GameState* gameState);
@ -1308,16 +1315,14 @@ void GameState_Init(GameState* gameState, GameStateFunc init, GraphicsContext* g
void GameState_Destroy(GameState* gameState); void GameState_Destroy(GameState* gameState);
GameStateFunc GameState_GetInit(GameState* gameState); GameStateFunc GameState_GetInit(GameState* gameState);
u32 GameState_IsRunning(GameState* gameState); u32 GameState_IsRunning(GameState* gameState);
#if OOT_DEBUG
void* GameState_Alloc(GameState* gameState, size_t size, char* file, s32 line); void* GameState_Alloc(GameState* gameState, size_t size, char* file, s32 line);
void func_800C55D0(GameAlloc* this);
void* GameAlloc_MallocDebug(GameAlloc* this, u32 size, const char* file, s32 line); void* GameAlloc_MallocDebug(GameAlloc* this, u32 size, const char* file, s32 line);
#endif
void* GameAlloc_Malloc(GameAlloc* this, u32 size); void* GameAlloc_Malloc(GameAlloc* this, u32 size);
void GameAlloc_Free(GameAlloc* this, void* data); void GameAlloc_Free(GameAlloc* this, void* data);
void GameAlloc_Cleanup(GameAlloc* this); void GameAlloc_Cleanup(GameAlloc* this);
void GameAlloc_Init(GameAlloc* this); void GameAlloc_Init(GameAlloc* this);
void Graph_FaultClient(void);
void Graph_DisassembleUCode(Gfx* workBuf);
void Graph_UCodeFaultClient(Gfx* workBuf);
void Graph_InitTHGA(GraphicsContext* gfxCtx); void Graph_InitTHGA(GraphicsContext* gfxCtx);
GameStateOverlay* Graph_GetNextGameState(GameState* gameState); GameStateOverlay* Graph_GetNextGameState(GameState* gameState);
void Graph_Init(GraphicsContext* gfxCtx); void Graph_Init(GraphicsContext* gfxCtx);
@ -1327,16 +1332,17 @@ void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState);
void Graph_ThreadEntry(void*); void Graph_ThreadEntry(void*);
void* Graph_Alloc(GraphicsContext* gfxCtx, size_t size); void* Graph_Alloc(GraphicsContext* gfxCtx, size_t size);
void* Graph_Alloc2(GraphicsContext* gfxCtx, size_t size); void* Graph_Alloc2(GraphicsContext* gfxCtx, size_t size);
#if OOT_DEBUG
void Graph_OpenDisps(Gfx** dispRefs, GraphicsContext* gfxCtx, const char* file, s32 line); void Graph_OpenDisps(Gfx** dispRefs, GraphicsContext* gfxCtx, const char* file, s32 line);
void Graph_CloseDisps(Gfx** dispRefs, GraphicsContext* gfxCtx, const char* file, s32 line); void Graph_CloseDisps(Gfx** dispRefs, GraphicsContext* gfxCtx, const char* file, s32 line);
Gfx* Graph_GfxPlusOne(Gfx* gfx); #endif
Gfx* Graph_BranchDlist(Gfx* gfx, Gfx* dst); Gfx* Gfx_Open(Gfx* gfx);
void* Graph_DlistAlloc(Gfx** gfxP, u32 size); Gfx* Gfx_Close(Gfx* gfx, Gfx* dst);
void* Gfx_Alloc(Gfx** gfxP, u32 size);
ListAlloc* ListAlloc_Init(ListAlloc* this); ListAlloc* ListAlloc_Init(ListAlloc* this);
void* ListAlloc_Alloc(ListAlloc* this, u32 size); void* ListAlloc_Alloc(ListAlloc* this, u32 size);
void ListAlloc_Free(ListAlloc* this, void* data); void ListAlloc_Free(ListAlloc* this, void* data);
void ListAlloc_FreeAll(ListAlloc* this); void ListAlloc_FreeAll(ListAlloc* this);
void Main_LogSystemHeap(void);
void Main(void* arg); void Main(void* arg);
void SysCfb_Init(s32 n64dd); void SysCfb_Init(s32 n64dd);
void* SysCfb_GetFbPtr(s32 idx); void* SysCfb_GetFbPtr(s32 idx);
@ -1430,7 +1436,7 @@ void Matrix_RotateZYX(s16 x, s16 y, s16 z, u8 mode);
void Matrix_TranslateRotateZYX(Vec3f* translation, Vec3s* rotation); void Matrix_TranslateRotateZYX(Vec3f* translation, Vec3s* rotation);
void Matrix_SetTranslateRotateYXZ(f32 translateX, f32 translateY, f32 translateZ, Vec3s* rot); void Matrix_SetTranslateRotateYXZ(f32 translateX, f32 translateY, f32 translateZ, Vec3s* rot);
Mtx* Matrix_MtxFToMtx(MtxF* src, Mtx* dest); Mtx* Matrix_MtxFToMtx(MtxF* src, Mtx* dest);
#ifdef OOT_DEBUG #if OOT_DEBUG
Mtx* Matrix_ToMtx(Mtx* dest, char* file, s32 line); Mtx* Matrix_ToMtx(Mtx* dest, char* file, s32 line);
Mtx* Matrix_NewMtx(GraphicsContext* gfxCtx, char* file, s32 line); Mtx* Matrix_NewMtx(GraphicsContext* gfxCtx, char* file, s32 line);
#else #else
@ -1446,7 +1452,9 @@ void Matrix_ReplaceRotation(MtxF* mf);
void Matrix_MtxFToYXZRotS(MtxF* mf, Vec3s* rotDest, s32 flag); void Matrix_MtxFToYXZRotS(MtxF* mf, Vec3s* rotDest, s32 flag);
void Matrix_MtxFToZYXRotS(MtxF* mf, Vec3s* rotDest, s32 flag); void Matrix_MtxFToZYXRotS(MtxF* mf, Vec3s* rotDest, s32 flag);
void Matrix_RotateAxis(f32 angle, Vec3f* axis, u8 mode); void Matrix_RotateAxis(f32 angle, Vec3f* axis, u8 mode);
#if OOT_DEBUG
MtxF* Matrix_CheckFloats(MtxF* mf, char* file, s32 line); MtxF* Matrix_CheckFloats(MtxF* mf, char* file, s32 line);
#endif
void Matrix_SetTranslateScaleMtx2(Mtx* mtx, f32 scaleX, f32 scaleY, f32 scaleZ, f32 translateX, f32 translateY, void Matrix_SetTranslateScaleMtx2(Mtx* mtx, f32 scaleX, f32 scaleY, f32 scaleZ, f32 translateX, f32 translateY,
f32 translateZ); f32 translateZ);
u64* SysUcode_GetUCodeBoot(void); u64* SysUcode_GetUCodeBoot(void);
@ -1456,22 +1464,24 @@ u64* SysUcode_GetUCodeData(void);
NORETURN void func_800D31A0(void); NORETURN void func_800D31A0(void);
void func_800D31F0(void); void func_800D31F0(void);
void func_800D3210(void); void func_800D3210(void);
void DebugArena_CheckPointer(void* ptr, u32 size, const char* name, const char* action);
void* DebugArena_Malloc(u32 size); void* DebugArena_Malloc(u32 size);
void* DebugArena_MallocDebug(u32 size, const char* file, s32 line);
void* DebugArena_MallocR(u32 size); void* DebugArena_MallocR(u32 size);
void* DebugArena_MallocRDebug(u32 size, const char* file, s32 line);
void* DebugArena_Realloc(void* ptr, u32 newSize); void* DebugArena_Realloc(void* ptr, u32 newSize);
void* DebugArena_ReallocDebug(void* ptr, u32 newSize, const char* file, s32 line);
void DebugArena_Free(void* ptr); void DebugArena_Free(void* ptr);
void DebugArena_FreeDebug(void* ptr, const char* file, s32 line);
void* DebugArena_Calloc(u32 num, u32 size); void* DebugArena_Calloc(u32 num, u32 size);
void DebugArena_Display(void);
void DebugArena_GetSizes(u32* outMaxFree, u32* outFree, u32* outAlloc); void DebugArena_GetSizes(u32* outMaxFree, u32* outFree, u32* outAlloc);
void DebugArena_Check(void); void DebugArena_Check(void);
void DebugArena_Init(void* start, u32 size); void DebugArena_Init(void* start, u32 size);
void DebugArena_Cleanup(void); void DebugArena_Cleanup(void);
u8 DebugArena_IsInitialized(void); u8 DebugArena_IsInitialized(void);
#if OOT_DEBUG
void DebugArena_CheckPointer(void* ptr, u32 size, const char* name, const char* action);
void* DebugArena_MallocDebug(u32 size, const char* file, s32 line);
void* DebugArena_MallocRDebug(u32 size, const char* file, s32 line);
void* DebugArena_ReallocDebug(void* ptr, u32 newSize, const char* file, s32 line);
void DebugArena_FreeDebug(void* ptr, const char* file, s32 line);
void DebugArena_Display(void);
#endif
void UCodeDisas_Init(UCodeDisas*); void UCodeDisas_Init(UCodeDisas*);
void UCodeDisas_Destroy(UCodeDisas*); void UCodeDisas_Destroy(UCodeDisas*);
void UCodeDisas_Disassemble(UCodeDisas*, Gfx*); void UCodeDisas_Disassemble(UCodeDisas*, Gfx*);
@ -1527,20 +1537,22 @@ void AudioLoad_LoadPermanentSamples(void);
void AudioLoad_ScriptLoad(s32 tableType, s32 id, s8* status); void AudioLoad_ScriptLoad(s32 tableType, s32 id, s8* status);
void AudioLoad_ProcessScriptLoads(void); void AudioLoad_ProcessScriptLoads(void);
void AudioLoad_InitScriptLoads(void); void AudioLoad_InitScriptLoads(void);
AudioTask* func_800E4FE0(void);
void Audio_QueueCmdF32(u32 opArgs, f32 data); AudioTask* AudioThread_Update(void);
void Audio_QueueCmdS32(u32 opArgs, s32 data); void AudioThread_QueueCmdF32(u32 opArgs, f32 data);
void Audio_QueueCmdS8(u32 opArgs, s8 data); void AudioThread_QueueCmdS32(u32 opArgs, s32 data);
void Audio_QueueCmdU16(u32 opArgs, u16 data); void AudioThread_QueueCmdS8(u32 opArgs, s8 data);
s32 Audio_ScheduleProcessCmds(void); void AudioThread_QueueCmdU16(u32 opArgs, u16 data);
s32 AudioThread_ScheduleProcessCmds(void);
u32 func_800E5E20(u32* out); u32 func_800E5E20(u32* out);
u8* func_800E5E84(s32 arg0, u32* arg1); u8* AudioThread_GetFontsForSequence(s32 seqId, u32* outNumFonts);
s32 func_800E5EDC(void); s32 func_800E5EDC(void);
s32 func_800E5F88(s32 resetPreloadID); s32 AudioThread_ResetAudioHeap(s32 specId);
void Audio_PreNMIInternal(void); void AudioThread_PreNMIInternal(void);
s32 func_800E6680(void); s32 func_800E6680(void);
u32 Audio_NextRandom(void); u32 AudioThread_NextRandom(void);
void Audio_InitMesgQueues(void); void AudioThread_InitMesgQueues(void);
void Audio_InvalDCache(void* buf, s32 size); void Audio_InvalDCache(void* buf, s32 size);
void Audio_WritebackDCache(void* buf, s32 size); void Audio_WritebackDCache(void* buf, s32 size);
s32 osAiSetNextBuffer(void*, u32); s32 osAiSetNextBuffer(void*, u32);
@ -1607,8 +1619,8 @@ s32 AudioOcarina_MemoryGameNextNote(void);
void AudioOcarina_PlayLongScarecrowSong(void); void AudioOcarina_PlayLongScarecrowSong(void);
void AudioDebug_Draw(GfxPrint* printer); void AudioDebug_Draw(GfxPrint* printer);
void AudioDebug_ScrPrt(const char* str, u16 num); void AudioDebug_ScrPrt(const char* str, u16 num);
void func_800F3054(void); void Audio_Update(void);
void Audio_SetSfxProperties(u8 bankId, u8 entryIdx, u8 channelIdx); void Audio_SetSfxProperties(u8 bankId, u8 entryIdx, u8 channelIndex);
void Audio_PlayCutsceneEffectsSequence(u8 csEffectType); void Audio_PlayCutsceneEffectsSequence(u8 csEffectType);
void func_800F4010(Vec3f* pos, u16 sfxId, f32); void func_800F4010(Vec3f* pos, u16 sfxId, f32);
void Audio_PlaySfxRandom(Vec3f* pos, u16 baseSfxId, u8 randLim); void Audio_PlaySfxRandom(Vec3f* pos, u16 baseSfxId, u8 randLim);
@ -1671,8 +1683,8 @@ void Audio_InitSound(void);
void func_800F7170(void); void func_800F7170(void);
void func_800F71BC(s32 arg0); void func_800F71BC(s32 arg0);
void Audio_SetSfxBanksMute(u16 muteMask); void Audio_SetSfxBanksMute(u16 muteMask);
void Audio_QueueSeqCmdMute(u8 channelIdx); void Audio_QueueSeqCmdMute(u8 channelIndex);
void Audio_ClearBGMMute(u8 channelIdx); void Audio_ClearBGMMute(u8 channelIndex);
void Audio_PlaySfxGeneral(u16 sfxId, Vec3f* pos, u8 token, f32* freqScale, f32* vol, s8* reverbAdd); void Audio_PlaySfxGeneral(u16 sfxId, Vec3f* pos, u8 token, f32* freqScale, f32* vol, s8* reverbAdd);
void Audio_ProcessSfxRequest(void); void Audio_ProcessSfxRequest(void);
void Audio_ChooseActiveSfx(u8 bankId); void Audio_ChooseActiveSfx(u8 bankId);
@ -1713,8 +1725,8 @@ void RcpUtils_Reset(void);
void* Overlay_AllocateAndLoad(uintptr_t vromStart, uintptr_t vromEnd, void* vramStart, void* vramEnd); void* Overlay_AllocateAndLoad(uintptr_t vromStart, uintptr_t vromEnd, void* vramStart, void* vramEnd);
void MtxConv_F2L(Mtx* m1, MtxF* m2); void MtxConv_F2L(Mtx* m1, MtxF* m2);
void MtxConv_L2F(MtxF* m1, Mtx* m2); void MtxConv_L2F(MtxF* m1, Mtx* m2);
void Overlay_Relocate(void* allocatedRamAddress, OverlayRelocationSection* ovlRelocs, void* vramStart); void Overlay_Relocate(void* allocatedRamAddr, OverlayRelocationSection* ovlRelocs, void* vramStart);
s32 Overlay_Load(uintptr_t vromStart, uintptr_t vromEnd, void* vramStart, void* vramEnd, void* allocatedRamAddr); size_t Overlay_Load(uintptr_t vromStart, uintptr_t vromEnd, void* vramStart, void* vramEnd, void* allocatedRamAddr);
// ? func_800FC800(?); // ? func_800FC800(?);
// ? func_800FC83C(?); // ? func_800FC83C(?);
// ? func_800FCAB4(?); // ? func_800FCAB4(?);
@ -1751,22 +1763,23 @@ f32 ceilf(f32 x);
f32 truncf(f32 x); f32 truncf(f32 x);
f32 roundf(f32 x); f32 roundf(f32 x);
f32 nearbyintf(f32 x); f32 nearbyintf(f32 x);
void SystemArena_CheckPointer(void* ptr, u32 size, const char* name, const char* action);
void* SystemArena_Malloc(u32 size); void* SystemArena_Malloc(u32 size);
void* SystemArena_MallocDebug(u32 size, const char* file, s32 line);
void* SystemArena_MallocR(u32 size); void* SystemArena_MallocR(u32 size);
void* SystemArena_MallocRDebug(u32 size, const char* file, s32 line);
void* SystemArena_Realloc(void* ptr, u32 newSize); void* SystemArena_Realloc(void* ptr, u32 newSize);
void* SystemArena_ReallocDebug(void* ptr, u32 newSize, const char* file, s32 line);
void SystemArena_Free(void* ptr); void SystemArena_Free(void* ptr);
void SystemArena_FreeDebug(void* ptr, const char* file, s32 line);
void* SystemArena_Calloc(u32 num, u32 size); void* SystemArena_Calloc(u32 num, u32 size);
void SystemArena_Display(void);
void SystemArena_GetSizes(u32* outMaxFree, u32* outFree, u32* outAlloc); void SystemArena_GetSizes(u32* outMaxFree, u32* outFree, u32* outAlloc);
void SystemArena_Check(void); void SystemArena_Check(void);
void SystemArena_Init(void* start, u32 size); void SystemArena_Init(void* start, u32 size);
void SystemArena_Cleanup(void); void SystemArena_Cleanup(void);
u8 SystemArena_IsInitialized(void); u8 SystemArena_IsInitialized(void);
#if OOT_DEBUG
void* SystemArena_MallocDebug(u32 size, const char* file, s32 line);
void* SystemArena_MallocRDebug(u32 size, const char* file, s32 line);
void* SystemArena_ReallocDebug(void* ptr, u32 newSize, const char* file, s32 line);
void SystemArena_FreeDebug(void* ptr, const char* file, s32 line);
void SystemArena_Display(void);
#endif
u32 Rand_Next(void); u32 Rand_Next(void);
void Rand_Seed(u32 seed); void Rand_Seed(u32 seed);
f32 Rand_ZeroOne(void); f32 Rand_ZeroOne(void);
@ -1775,45 +1788,23 @@ void Rand_Seed_Variable(u32* rndNum, u32 seed);
u32 Rand_Next_Variable(u32* rndNum); u32 Rand_Next_Variable(u32* rndNum);
f32 Rand_ZeroOne_Variable(u32* rndNum); f32 Rand_ZeroOne_Variable(u32* rndNum);
f32 Rand_Centered_Variable(u32* rndNum); f32 Rand_Centered_Variable(u32* rndNum);
u32 ArenaImpl_GetFillAllocBlock(Arena* arena);
u32 ArenaImpl_GetFillFreeBlock(Arena* arena);
u32 ArenaImpl_GetCheckFreeBlock(Arena* arena);
void ArenaImpl_SetFillAllocBlock(Arena* arena);
void ArenaImpl_SetFillFreeBlock(Arena* arena);
void ArenaImpl_SetCheckFreeBlock(Arena* arena);
void ArenaImpl_UnsetFillAllocBlock(Arena* arena);
void ArenaImpl_UnsetFillFreeBlock(Arena* arena);
void ArenaImpl_UnsetCheckFreeBlock(Arena* arena);
void ArenaImpl_SetDebugInfo(ArenaNode* node, const char* file, s32 line, Arena* arena);
void ArenaImpl_LockInit(Arena* arena);
void ArenaImpl_Lock(Arena* arena);
void ArenaImpl_Unlock(Arena* arena);
ArenaNode* ArenaImpl_GetNextBlock(ArenaNode* node);
ArenaNode* ArenaImpl_GetPrevBlock(ArenaNode* node);
ArenaNode* ArenaImpl_GetLastBlock(Arena* arena);
void __osMallocInit(Arena* arena, void* start, u32 size); void __osMallocInit(Arena* arena, void* start, u32 size);
void __osMallocAddBlock(Arena* arena, void* start, s32 size); void __osMallocAddBlock(Arena* arena, void* start, s32 size);
void ArenaImpl_RemoveAllBlocks(Arena* arena);
void __osMallocCleanup(Arena* arena); void __osMallocCleanup(Arena* arena);
u8 __osMallocIsInitialized(Arena* arena); u8 __osMallocIsInitialized(Arena* arena);
void __osMalloc_FreeBlockTest(Arena* arena, ArenaNode* node);
void* __osMalloc_NoLockDebug(Arena* arena, u32 size, const char* file, s32 line);
void* __osMallocDebug(Arena* arena, u32 size, const char* file, s32 line);
void* __osMallocRDebug(Arena* arena, u32 size, const char* file, s32 line);
void* __osMalloc_NoLock(Arena* arena, u32 size);
void* __osMalloc(Arena* arena, u32 size); void* __osMalloc(Arena* arena, u32 size);
void* __osMallocR(Arena* arena, u32 size); void* __osMallocR(Arena* arena, u32 size);
void __osFree_NoLock(Arena* arena, void* ptr);
void __osFree(Arena* arena, void* ptr); void __osFree(Arena* arena, void* ptr);
void __osFree_NoLockDebug(Arena* arena, void* ptr, const char* file, s32 line);
void __osFreeDebug(Arena* arena, void* ptr, const char* file, s32 line);
void* __osRealloc(Arena* arena, void* ptr, u32 newSize); void* __osRealloc(Arena* arena, void* ptr, u32 newSize);
void* __osReallocDebug(Arena* arena, void* ptr, u32 newSize, const char* file, s32 line);
void ArenaImpl_GetSizes(Arena* arena, u32* outMaxFree, u32* outFree, u32* outAlloc); void ArenaImpl_GetSizes(Arena* arena, u32* outMaxFree, u32* outFree, u32* outAlloc);
void __osDisplayArena(Arena* arena);
void ArenaImpl_FaultClient(Arena* arena);
u32 __osCheckArena(Arena* arena); u32 __osCheckArena(Arena* arena);
u8 func_800FF334(Arena* arena); #if OOT_DEBUG
void* __osMallocDebug(Arena* arena, u32 size, const char* file, s32 line);
void* __osMallocRDebug(Arena* arena, u32 size, const char* file, s32 line);
void __osFreeDebug(Arena* arena, void* ptr, const char* file, s32 line);
void* __osReallocDebug(Arena* arena, void* ptr, u32 newSize, const char* file, s32 line);
void __osDisplayArena(Arena* arena);
#endif
s32 PrintUtils_VPrintf(PrintCallback* pfn, const char* fmt, va_list args); s32 PrintUtils_VPrintf(PrintCallback* pfn, const char* fmt, va_list args);
s32 PrintUtils_Printf(PrintCallback* pfn, const char* fmt, ...); s32 PrintUtils_Printf(PrintCallback* pfn, const char* fmt, ...);
void Sleep_Cycles(OSTime cycles); void Sleep_Cycles(OSTime cycles);

View file

@ -2,3 +2,48 @@
.global \label .global \label
\label: \label:
.endm .endm
.macro dlabel label
.global \label
\label:
.endm
.macro jlabel label
\label:
.endm
# Float register aliases (o32 ABI, odd ones are rarely used)
.set $fv0, $f0
.set $fv0f, $f1
.set $fv1, $f2
.set $fv1f, $f3
.set $ft0, $f4
.set $ft0f, $f5
.set $ft1, $f6
.set $ft1f, $f7
.set $ft2, $f8
.set $ft2f, $f9
.set $ft3, $f10
.set $ft3f, $f11
.set $fa0, $f12
.set $fa0f, $f13
.set $fa1, $f14
.set $fa1f, $f15
.set $ft4, $f16
.set $ft4f, $f17
.set $ft5, $f18
.set $ft5f, $f19
.set $fs0, $f20
.set $fs0f, $f21
.set $fs1, $f22
.set $fs1f, $f23
.set $fs2, $f24
.set $fs2f, $f25
.set $fs3, $f26
.set $fs3f, $f27
.set $fs4, $f28
.set $fs4f, $f29
.set $fs5, $f30
.set $fs5f, $f31

View file

@ -21,6 +21,14 @@
#define CLAMP_MAX(x, max) ((x) > (max) ? (max) : (x)) #define CLAMP_MAX(x, max) ((x) > (max) ? (max) : (x))
#define CLAMP_MIN(x, min) ((x) < (min) ? (min) : (x)) #define CLAMP_MIN(x, min) ((x) < (min) ? (min) : (x))
#define SWAP(type, a, b) \
{ \
type _temp = (a); \
(a) = (b); \
(b) = _temp; \
} \
(void)0
#define RGBA8(r, g, b, a) ((((r) & 0xFF) << 24) | (((g) & 0xFF) << 16) | (((b) & 0xFF) << 8) | (((a) & 0xFF) << 0)) #define RGBA8(r, g, b, a) ((((r) & 0xFF) << 24) | (((g) & 0xFF) << 16) | (((b) & 0xFF) << 8) | (((a) & 0xFF) << 0))
#define GET_PLAYER(play) ((Player*)(play)->actorCtx.actorLists[ACTORCAT_PLAYER].head) #define GET_PLAYER(play) ((Player*)(play)->actorCtx.actorLists[ACTORCAT_PLAYER].head)
@ -100,29 +108,30 @@
#define CHECK_FLAG_ALL(flags, mask) (((flags) & (mask)) == (mask)) #define CHECK_FLAG_ALL(flags, mask) (((flags) & (mask)) == (mask))
#ifdef OOT_DEBUG
#define PRINTF osSyncPrintf
#else
#ifdef __sgi /* IDO compiler */
// IDO doesn't support variadic macros, but it merely throws a warning for the // IDO doesn't support variadic macros, but it merely throws a warning for the
// number of arguments not matching the definition (warning 609) instead of // number of arguments not matching the definition (warning 609) instead of
// throwing an error. We suppress this warning and rely on GCC to catch macro // throwing an error. We suppress this warning and rely on GCC to catch macro
// argument errors instead. // argument errors instead.
// Note some tools define __sgi but preprocess with a modern cpp implementation,
// ensure that these do not use the IDO workaround to avoid errors.
#define IDO_PRINTF_WORKAROUND (__sgi && !__GNUC__ && !PERMUTER && !M2CTX)
#if OOT_DEBUG
#define PRINTF osSyncPrintf
#elif IDO_PRINTF_WORKAROUND
#define PRINTF(args) (void)0 #define PRINTF(args) (void)0
#else #else
#define PRINTF(format, ...) (void)0 #define PRINTF(format, ...) (void)0
#endif #endif
#endif
#ifdef OOT_DEBUG
#if OOT_DEBUG
#define LOG(exp, value, format, file, line) \ #define LOG(exp, value, format, file, line) \
do { \ do { \
LogUtils_LogThreadId(file, line); \ LogUtils_LogThreadId(file, line); \
osSyncPrintf(exp " = " format "\n", value); \ osSyncPrintf(exp " = " format "\n", value); \
} while (0) } while (0)
#else #else
#define LOG(exp, value, format, file, line) (void)0 #define LOG(exp, value, format, file, line) (void)(value)
#endif #endif
#define LOG_STRING(string, file, line) LOG(#string, string, "%s", file, line) #define LOG_STRING(string, file, line) LOG(#string, string, "%s", file, line)
@ -135,8 +144,10 @@
#define SET_NEXT_GAMESTATE(curState, newInit, newStruct) \ #define SET_NEXT_GAMESTATE(curState, newInit, newStruct) \
do { \ do { \
(curState)->init = newInit; \ GameState* state = curState; \
(curState)->size = sizeof(newStruct); \ \
(state)->init = newInit; \
(state)->size = sizeof(newStruct); \
} while (0) } while (0)
#define SET_FULLSCREEN_VIEWPORT(view) \ #define SET_FULLSCREEN_VIEWPORT(view) \
@ -159,7 +170,7 @@ extern struct GraphicsContext* __gfxCtx;
#define POLY_XLU_DISP __gfxCtx->polyXlu.p #define POLY_XLU_DISP __gfxCtx->polyXlu.p
#define OVERLAY_DISP __gfxCtx->overlay.p #define OVERLAY_DISP __gfxCtx->overlay.p
#ifdef OOT_DEBUG #if OOT_DEBUG
// __gfxCtx shouldn't be used directly. // __gfxCtx shouldn't be used directly.
// Use the DISP macros defined above when writing to display buffers. // Use the DISP macros defined above when writing to display buffers.
@ -183,6 +194,9 @@ extern struct GraphicsContext* __gfxCtx;
#define DMA_REQUEST_SYNC(ram, vrom, size, file, line) DmaMgr_RequestSyncDebug(ram, vrom, size, file, line) #define DMA_REQUEST_SYNC(ram, vrom, size, file, line) DmaMgr_RequestSyncDebug(ram, vrom, size, file, line)
#define DMA_REQUEST_ASYNC(req, ram, vrom, size, unk5, queue, msg, file, line) DmaMgr_RequestAsyncDebug(req, ram, vrom, size, unk5, queue, msg, file, line) #define DMA_REQUEST_ASYNC(req, ram, vrom, size, unk5, queue, msg, file, line) DmaMgr_RequestAsyncDebug(req, ram, vrom, size, unk5, queue, msg, file, line)
#define GAME_STATE_ALLOC(gameState, size, file, line) GameState_Alloc(gameState, size, file, line) #define GAME_STATE_ALLOC(gameState, size, file, line) GameState_Alloc(gameState, size, file, line)
#define DEBUG_ARENA_MALLOC(size, file, line) DebugArena_MallocDebug(size, file, line)
#define DEBUG_ARENA_MALLOC_R(size, file, line) DebugArena_MallocRDebug(size, file, line)
#define DEBUG_ARENA_FREE(size, file, line) DebugArena_FreeDebug(size, file, line)
#define SYSTEM_ARENA_MALLOC(size, file, line) SystemArena_MallocDebug(size, file, line) #define SYSTEM_ARENA_MALLOC(size, file, line) SystemArena_MallocDebug(size, file, line)
#define SYSTEM_ARENA_MALLOC_R(size, file, line) SystemArena_MallocRDebug(size, file, line) #define SYSTEM_ARENA_MALLOC_R(size, file, line) SystemArena_MallocRDebug(size, file, line)
#define SYSTEM_ARENA_FREE(size, file, line) SystemArena_FreeDebug(size, file, line) #define SYSTEM_ARENA_FREE(size, file, line) SystemArena_FreeDebug(size, file, line)
@ -191,6 +205,8 @@ extern struct GraphicsContext* __gfxCtx;
#define ZELDA_ARENA_FREE(size, file, line) ZeldaArena_FreeDebug(size, file, line) #define ZELDA_ARENA_FREE(size, file, line) ZeldaArena_FreeDebug(size, file, line)
#define LOG_UTILS_CHECK_NULL_POINTER(exp, ptr, file, line) LogUtils_CheckNullPointer(exp, ptr, file, line) #define LOG_UTILS_CHECK_NULL_POINTER(exp, ptr, file, line) LogUtils_CheckNullPointer(exp, ptr, file, line)
#define LOG_UTILS_CHECK_VALID_POINTER(exp, ptr, file, line) LogUtils_CheckValidPointer(exp, ptr, file, line) #define LOG_UTILS_CHECK_VALID_POINTER(exp, ptr, file, line) LogUtils_CheckValidPointer(exp, ptr, file, line)
#define HUNGUP_AND_CRASH(file, line) Fault_AddHungupAndCrash(file, line)
#define GAME_ALLOC_MALLOC(alloc, size, file, line) GameAlloc_MallocDebug(alloc, size, file, line)
#else #else
@ -211,6 +227,9 @@ extern struct GraphicsContext* __gfxCtx;
#define DMA_REQUEST_SYNC(ram, vrom, size, file, line) DmaMgr_RequestSync(ram, vrom, size) #define DMA_REQUEST_SYNC(ram, vrom, size, file, line) DmaMgr_RequestSync(ram, vrom, size)
#define DMA_REQUEST_ASYNC(req, ram, vrom, size, unk5, queue, msg, file, line) DmaMgr_RequestAsync(req, ram, vrom, size, unk5, queue, msg) #define DMA_REQUEST_ASYNC(req, ram, vrom, size, unk5, queue, msg, file, line) DmaMgr_RequestAsync(req, ram, vrom, size, unk5, queue, msg)
#define GAME_STATE_ALLOC(gameState, size, file, line) THA_AllocTailAlign16(&(gameState)->tha, size) #define GAME_STATE_ALLOC(gameState, size, file, line) THA_AllocTailAlign16(&(gameState)->tha, size)
#define DEBUG_ARENA_MALLOC(size, file, line) DebugArena_Malloc(size)
#define DEBUG_ARENA_MALLOC_R(size, file, line) DebugArena_MallocR(size)
#define DEBUG_ARENA_FREE(size, file, line) DebugArena_Free(size)
#define SYSTEM_ARENA_MALLOC(size, file, line) SystemArena_Malloc(size) #define SYSTEM_ARENA_MALLOC(size, file, line) SystemArena_Malloc(size)
#define SYSTEM_ARENA_MALLOC_R(size, file, line) SystemArena_MallocR(size) #define SYSTEM_ARENA_MALLOC_R(size, file, line) SystemArena_MallocR(size)
#define SYSTEM_ARENA_FREE(size, file, line) SystemArena_Free(size) #define SYSTEM_ARENA_FREE(size, file, line) SystemArena_Free(size)
@ -219,6 +238,8 @@ extern struct GraphicsContext* __gfxCtx;
#define ZELDA_ARENA_FREE(size, file, line) ZeldaArena_Free(size) #define ZELDA_ARENA_FREE(size, file, line) ZeldaArena_Free(size)
#define LOG_UTILS_CHECK_NULL_POINTER(exp, ptr, file, line) (void)0 #define LOG_UTILS_CHECK_NULL_POINTER(exp, ptr, file, line) (void)0
#define LOG_UTILS_CHECK_VALID_POINTER(exp, ptr, file, line) (void)0 #define LOG_UTILS_CHECK_VALID_POINTER(exp, ptr, file, line) (void)0
#define HUNGUP_AND_CRASH(file, line) LogUtils_HungupThread(file, line)
#define GAME_ALLOC_MALLOC(alloc, size, file, line) GameAlloc_Malloc(alloc, size)
#endif /* OOT_DEBUG */ #endif /* OOT_DEBUG */

View file

@ -219,6 +219,7 @@
#define R_GAME_OVER_RUMBLE_STRENGTH VREG(90) #define R_GAME_OVER_RUMBLE_STRENGTH VREG(90)
#define R_GAME_OVER_RUMBLE_DURATION VREG(91) #define R_GAME_OVER_RUMBLE_DURATION VREG(91)
#define R_GAME_OVER_RUMBLE_DECREASE_RATE VREG(92) #define R_GAME_OVER_RUMBLE_DECREASE_RATE VREG(92)
#define R_ENABLE_ACTOR_DEBUG_PRINTF HREG(20)
#define R_DISABLE_INPUT_DISPLAY HREG(47) #define R_DISABLE_INPUT_DISPLAY HREG(47)
#define R_ENABLE_PLAY_LOGS HREG(63) #define R_ENABLE_PLAY_LOGS HREG(63)
#define R_EN_GOROIWA_SPEED mREG(12) #define R_EN_GOROIWA_SPEED mREG(12)

View file

@ -10,10 +10,10 @@ typedef enum {
/* 0x1 */ SEQCMD_OP_STOP_SEQUENCE, /* 0x1 */ SEQCMD_OP_STOP_SEQUENCE,
/* 0x2 */ SEQCMD_OP_QUEUE_SEQUENCE, /* 0x2 */ SEQCMD_OP_QUEUE_SEQUENCE,
/* 0x3 */ SEQCMD_OP_UNQUEUE_SEQUENCE, /* 0x3 */ SEQCMD_OP_UNQUEUE_SEQUENCE,
/* 0x4 */ SEQCMD_OP_SET_PLAYER_VOLUME, /* 0x4 */ SEQCMD_OP_SET_SEQPLAYER_VOLUME,
/* 0x5 */ SEQCMD_OP_SET_PLAYER_FREQ, /* 0x5 */ SEQCMD_OP_SET_SEQPLAYER_FREQ,
/* 0x6 */ SEQCMD_OP_SET_CHANNEL_VOLUME, /* 0x6 */ SEQCMD_OP_SET_CHANNEL_VOLUME,
/* 0x7 */ SEQCMD_OP_SET_PLAYER_IO, /* 0x7 */ SEQCMD_OP_SET_SEQPLAYER_IO,
/* 0x8 */ SEQCMD_OP_SET_CHANNEL_IO, /* 0x8 */ SEQCMD_OP_SET_CHANNEL_IO,
/* 0x9 */ SEQCMD_OP_SET_CHANNEL_IO_DISABLE_MASK, /* 0x9 */ SEQCMD_OP_SET_CHANNEL_IO_DISABLE_MASK,
/* 0xA */ SEQCMD_OP_SET_CHANNEL_DISABLE_MASK, /* 0xA */ SEQCMD_OP_SET_CHANNEL_DISABLE_MASK,
@ -37,17 +37,17 @@ typedef enum {
// Subset of `SEQCMD_OP_SETUP_CMD` // Subset of `SEQCMD_OP_SETUP_CMD`
typedef enum { typedef enum {
/* 0x0 */ SEQCMD_SUB_OP_SETUP_RESTORE_VOLUME, /* 0x0 */ SEQCMD_SUB_OP_SETUP_RESTORE_SEQPLAYER_VOLUME,
/* 0x1 */ SEQCMD_SUB_OP_SETUP_SEQ_UNQUEUE, /* 0x1 */ SEQCMD_SUB_OP_SETUP_SEQ_UNQUEUE,
/* 0x2 */ SEQCMD_SUB_OP_SETUP_RESTART_SEQ, /* 0x2 */ SEQCMD_SUB_OP_SETUP_RESTART_SEQ,
/* 0x3 */ SEQCMD_SUB_OP_SETUP_TEMPO_SCALE, /* 0x3 */ SEQCMD_SUB_OP_SETUP_TEMPO_SCALE,
/* 0x4 */ SEQCMD_SUB_OP_SETUP_TEMPO_RESET, /* 0x4 */ SEQCMD_SUB_OP_SETUP_TEMPO_RESET,
/* 0x5 */ SEQCMD_SUB_OP_SETUP_PLAY_SEQ, /* 0x5 */ SEQCMD_SUB_OP_SETUP_PLAY_SEQ,
/* 0x6 */ SEQCMD_SUB_OP_SETUP_SET_FADE_TIMER, /* 0x6 */ SEQCMD_SUB_OP_SETUP_SET_FADE_TIMER,
/* 0x7 */ SEQCMD_SUB_OP_SETUP_RESTORE_VOLUME_IF_QUEUED, /* 0x7 */ SEQCMD_SUB_OP_SETUP_RESTORE_SEQPLAYER_VOLUME_IF_QUEUED,
/* 0x8 */ SEQCMD_SUB_OP_SETUP_RESTORE_VOLUME_WITH_SCALE_INDEX, /* 0x8 */ SEQCMD_SUB_OP_SETUP_RESTORE_SEQPLAYER_VOLUME_WITH_SCALE_INDEX,
/* 0x9 */ SEQCMD_SUB_OP_SETUP_SET_CHANNEL_DISABLE_MASK, /* 0x9 */ SEQCMD_SUB_OP_SETUP_SET_CHANNEL_DISABLE_MASK,
/* 0xA */ SEQCMD_SUB_OP_SETUP_SET_PLAYER_FREQ, /* 0xA */ SEQCMD_SUB_OP_SETUP_SET_SEQPLAYER_FREQ,
/* 0xE */ SEQCMD_SUB_OP_SETUP_POP_PERSISTENT_CACHE = 0xE, /* 0xE */ SEQCMD_SUB_OP_SETUP_POP_PERSISTENT_CACHE = 0xE,
/* 0xF */ SEQCMD_SUB_OP_SETUP_RESET_SETUP_CMDS /* 0xF */ SEQCMD_SUB_OP_SETUP_RESET_SETUP_CMDS
} SeqCmdSetupCmdOp; } SeqCmdSetupCmdOp;
@ -64,13 +64,15 @@ typedef enum {
* Play a sequence on a given seqPlayer * Play a sequence on a given seqPlayer
* *
* @param seqPlayerIndex the index of the seqPlayer to play the sequence * @param seqPlayerIndex the index of the seqPlayer to play the sequence
* @param fadeInDuration duration the sequence will fade in over * @param fadeInDuration effect will depend on seqArg. See below
* @param seqArg no effect: < 0x7F, skip ticks: = 0x7F, will not play: >= 0x80 (see note) * @param seqArg no effect: < 0x7F, skip ahead: = 0x7F, will not play: >= 0x80 (see note)
* @param seqId the id of the sequence to play, see `SeqId` * @param seqId the id of the sequence to play, see `SeqId`
* *
* @note seqArg will also be stored in gActiveSeqs.seqId, any check against that seqId must also include seqArg. * @note seqArg will also be stored in gActiveSeqs.seqId, any check against that seqId must also include seqArg.
* seqArg = 0x7F will interpret the duration as the number of ticks to skip. * seqArg < 0x7F: fade in the sequence over `fadeInDuration` in units of (1/30th) seconds
* seqArg >= 0x80 was intented to load a soundFont asynchronously but the code is unfinished (based on MM). * seqArg = 0x7F: start the sequence immediately, but begins `fadeInDuration` number of second into the sequence.
* seqArg >= 0x80: no sequence will play. Intended to load a soundFont asynchronously but was only half implemented
* (inferred from MM).
*/ */
#define SEQCMD_PLAY_SEQUENCE(seqPlayerIndex, fadeInDuration, seqArg, seqId) \ #define SEQCMD_PLAY_SEQUENCE(seqPlayerIndex, fadeInDuration, seqArg, seqId) \
Audio_QueueSeqCmd((SEQCMD_OP_PLAY_SEQUENCE << 28) | ((u8)(seqPlayerIndex) << 24) | ((u8)(fadeInDuration) << 16) | \ Audio_QueueSeqCmd((SEQCMD_OP_PLAY_SEQUENCE << 28) | ((u8)(seqPlayerIndex) << 24) | ((u8)(fadeInDuration) << 16) | \
@ -79,7 +81,7 @@ typedef enum {
/** /**
* Stop a sequence on a given seqPlayer * Stop a sequence on a given seqPlayer
* *
* @param seqPlayerIndex the index of the seqPlayer to play the sequence * @param seqPlayerIndex the index of the seqPlayer to stop the sequence
* @param fadeOutDuration duration the sequence will fade out over * @param fadeOutDuration duration the sequence will fade out over
* *
* @note the 0xFF in the command is not read from at all, but is common in all Stop SeqPlayer Commands * @note the 0xFF in the command is not read from at all, but is common in all Stop SeqPlayer Commands
@ -125,8 +127,8 @@ typedef enum {
* @param duration duration to transition to the volume * @param duration duration to transition to the volume
* @param volume the target volume for the sequence. Ranged from 0-0xFF, with 0x7F mapping to 1.0f * @param volume the target volume for the sequence. Ranged from 0-0xFF, with 0x7F mapping to 1.0f
*/ */
#define SEQCMD_SET_PLAYER_VOLUME(seqPlayerIndex, duration, volume) \ #define SEQCMD_SET_SEQPLAYER_VOLUME(seqPlayerIndex, duration, volume) \
Audio_QueueSeqCmd((SEQCMD_OP_SET_PLAYER_VOLUME << 28) | ((u8)(seqPlayerIndex) << 24) | ((duration) << 16) | \ Audio_QueueSeqCmd((SEQCMD_OP_SET_SEQPLAYER_VOLUME << 28) | ((u8)(seqPlayerIndex) << 24) | ((duration) << 16) | \
(volume)) (volume))
/** /**
@ -139,8 +141,8 @@ typedef enum {
* @note 2000 will double the frequency (raise an octave), 500 will halve the frequency (lower an octave). * @note 2000 will double the frequency (raise an octave), 500 will halve the frequency (lower an octave).
* Cannot be used with `SEQCMD_SET_CHANNEL_FREQ` as they will overwrite one another. * Cannot be used with `SEQCMD_SET_CHANNEL_FREQ` as they will overwrite one another.
*/ */
#define SEQCMD_SET_PLAYER_FREQ(seqPlayerIndex, duration, freqScale) \ #define SEQCMD_SET_SEQPLAYER_FREQ(seqPlayerIndex, duration, freqScale) \
Audio_QueueSeqCmd((SEQCMD_OP_SET_PLAYER_FREQ << 28) | ((u8)(seqPlayerIndex) << 24) | ((duration) << 16) | \ Audio_QueueSeqCmd((SEQCMD_OP_SET_SEQPLAYER_FREQ << 28) | ((u8)(seqPlayerIndex) << 24) | ((duration) << 16) | \
(freqScale)) (freqScale))
/** /**
@ -152,7 +154,7 @@ typedef enum {
* @param freqScale the scaling factor to shift the pitch. Ranged from 0-0xFFF, with 1000 mapping to 1.0f * @param freqScale the scaling factor to shift the pitch. Ranged from 0-0xFFF, with 1000 mapping to 1.0f
* *
* @note a frequency of 2000 will double the frequency (raise an octave), 500 will halve the frequency (lower an octave). * @note a frequency of 2000 will double the frequency (raise an octave), 500 will halve the frequency (lower an octave).
* Cannot be used with `SEQCMD_SET_PLAYER_FREQ` as they will overwrite one another. * Cannot be used with `SEQCMD_SET_SEQPLAYER_FREQ` as they will overwrite one another.
*/ */
#define SEQCMD_SET_CHANNEL_FREQ(seqPlayerIndex, channelIndex, duration, freqScale) \ #define SEQCMD_SET_CHANNEL_FREQ(seqPlayerIndex, channelIndex, duration, freqScale) \
Audio_QueueSeqCmd((SEQCMD_OP_SET_CHANNEL_FREQ << 28) | ((u8)(seqPlayerIndex) << 24) | ((duration) << 16) | \ Audio_QueueSeqCmd((SEQCMD_OP_SET_CHANNEL_FREQ << 28) | ((u8)(seqPlayerIndex) << 24) | ((duration) << 16) | \
@ -175,15 +177,15 @@ typedef enum {
* ioPort, which can affect the entire sequence. * ioPort, which can affect the entire sequence.
* *
* @param seqPlayerIndex the index of the seqPlayer to write the input to * @param seqPlayerIndex the index of the seqPlayer to write the input to
* @param ioPort the index of the array to store the input-output value, * @param ioPort the index of the array to store the input-output value
* @param ioData the value s8 that's written to the input-output array * @param ioData the value s8 that's written to the input-output array
* *
* @note Each seqPlayer has 8 global ioPorts indexed 0-7. * @note Each seqPlayer has 8 global ioPorts indexed 0-7.
* ioPort 0 and 1 are read-only-once, and will reset after being read by the sequence. * ioPort 0 and 1 are read-only-once, and will reset after being read by the sequence.
* ioPort 2-7 can be read multiple times. * ioPort 2-7 can be read multiple times.
*/ */
#define SEQCMD_SET_PLAYER_IO(seqPlayerIndex, ioPort, ioData) \ #define SEQCMD_SET_SEQPLAYER_IO(seqPlayerIndex, ioPort, ioData) \
Audio_QueueSeqCmd((SEQCMD_OP_SET_PLAYER_IO << 28) | ((u8)(seqPlayerIndex) << 24) | ((u8)(ioPort) << 16) | \ Audio_QueueSeqCmd((SEQCMD_OP_SET_SEQPLAYER_IO << 28) | ((u8)(seqPlayerIndex) << 24) | ((u8)(ioPort) << 16) | \
(u8)(ioData)) (u8)(ioData))
/** /**
@ -209,7 +211,7 @@ typedef enum {
* @param seqPlayerIndex the index of the seqPlayer to modify * @param seqPlayerIndex the index of the seqPlayer to modify
* @param channelMask a 16 bit mask where each bit maps to a channel. Bitflag on to disable * @param channelMask a 16 bit mask where each bit maps to a channel. Bitflag on to disable
* *
* @note using Audio_QueueCmdS8 0x06 will bypass this channelMask * @note using AUDIOCMD_CHANNEL_SET_IO will bypass this channelMask
*/ */
#define SEQCMD_SET_CHANNEL_IO_DISABLE_MASK(seqPlayerIndex, channelMask) \ #define SEQCMD_SET_CHANNEL_IO_DISABLE_MASK(seqPlayerIndex, channelMask) \
Audio_QueueSeqCmd((SEQCMD_OP_SET_CHANNEL_IO_DISABLE_MASK << 28) | ((u8)(seqPlayerIndex) << 24) | (u16)(channelMask)) Audio_QueueSeqCmd((SEQCMD_OP_SET_CHANNEL_IO_DISABLE_MASK << 28) | ((u8)(seqPlayerIndex) << 24) | (u16)(channelMask))
@ -304,8 +306,8 @@ typedef enum {
* @param targetSeqPlayerIndex the index of the seqPlayer to modify * @param targetSeqPlayerIndex the index of the seqPlayer to modify
* @param duration duration to transition to the volume * @param duration duration to transition to the volume
*/ */
#define SEQCMD_SETUP_RESTORE_PLAYER_VOLUME(setupSeqPlayerIndex, targetSeqPlayerIndex, duration) \ #define SEQCMD_SETUP_RESTORE_SEQPLAYER_VOLUME(setupSeqPlayerIndex, targetSeqPlayerIndex, duration) \
Audio_QueueSeqCmd((SEQCMD_OP_SETUP_CMD << 28) | (SEQCMD_SUB_OP_SETUP_RESTORE_VOLUME << 20) | \ Audio_QueueSeqCmd((SEQCMD_OP_SETUP_CMD << 28) | (SEQCMD_SUB_OP_SETUP_RESTORE_SEQPLAYER_VOLUME << 20) | \
((u8)(setupSeqPlayerIndex) << 24) | ((u8)(targetSeqPlayerIndex) << 16) | (u8)(duration)) ((u8)(setupSeqPlayerIndex) << 24) | ((u8)(targetSeqPlayerIndex) << 16) | (u8)(duration))
/** /**
@ -394,9 +396,9 @@ typedef enum {
* @param duration duration to transition to the volume * @param duration duration to transition to the volume
* @param numSeqRequests the number of sequence requests queued that must match the actual number of sequence requests * @param numSeqRequests the number of sequence requests queued that must match the actual number of sequence requests
*/ */
#define SEQCMD_SETUP_RESTORE_PLAYER_VOLUME_IF_QUEUED(setupSeqPlayerIndex, targetSeqPlayerIndex, duration, \ #define SEQCMD_SETUP_RESTORE_SEQPLAYER_VOLUME_IF_QUEUED(setupSeqPlayerIndex, targetSeqPlayerIndex, duration, \
numSeqRequests) \ numSeqRequests) \
Audio_QueueSeqCmd((SEQCMD_OP_SETUP_CMD << 28) | (SEQCMD_SUB_OP_SETUP_RESTORE_VOLUME_IF_QUEUED << 20) | \ Audio_QueueSeqCmd((SEQCMD_OP_SETUP_CMD << 28) | (SEQCMD_SUB_OP_SETUP_RESTORE_SEQPLAYER_VOLUME_IF_QUEUED << 20) | \
((u8)(setupSeqPlayerIndex) << 24) | ((u8)(targetSeqPlayerIndex) << 16) | ((u8)(duration) << 8) | \ ((u8)(setupSeqPlayerIndex) << 24) | ((u8)(targetSeqPlayerIndex) << 16) | ((u8)(duration) << 8) | \
(u8)(numSeqRequests)) (u8)(numSeqRequests))
@ -409,8 +411,10 @@ typedef enum {
* @param scaleIndex the scale index of a seqPlayer * @param scaleIndex the scale index of a seqPlayer
* @param duration duration to transition to the volume * @param duration duration to transition to the volume
*/ */
#define SEQCMD_SETUP_RESTORE_PLAYER_VOLUME_WITH_SCALE_INDEX(setupSeqPlayerIndex, targetSeqPlayerIndex, scaleIndex, duration) \ #define SEQCMD_SETUP_RESTORE_SEQPLAYER_VOLUME_WITH_SCALE_INDEX(setupSeqPlayerIndex, targetSeqPlayerIndex, scaleIndex, \
Audio_QueueSeqCmd((SEQCMD_OP_SETUP_CMD << 28) | (SEQCMD_SUB_OP_SETUP_RESTORE_VOLUME_WITH_SCALE_INDEX << 20) | \ duration) \
Audio_QueueSeqCmd((SEQCMD_OP_SETUP_CMD << 28) | \
(SEQCMD_SUB_OP_SETUP_RESTORE_SEQPLAYER_VOLUME_WITH_SCALE_INDEX << 20) | \
((u8)(setupSeqPlayerIndex) << 24) | ((u8)(targetSeqPlayerIndex) << 16) | \ ((u8)(setupSeqPlayerIndex) << 24) | ((u8)(targetSeqPlayerIndex) << 16) | \
((u8)(scaleIndex) << 8) | (u8)(duration)) ((u8)(scaleIndex) << 8) | (u8)(duration))
@ -438,8 +442,8 @@ typedef enum {
* @note The base value for frequency, 100, is 10 times smaller than other frequency commands. * @note The base value for frequency, 100, is 10 times smaller than other frequency commands.
* 200 will double the frequency (raise an octave), 50 will halve the frequency (lower an octave). * 200 will double the frequency (raise an octave), 50 will halve the frequency (lower an octave).
*/ */
#define SEQCMD_SETUP_SET_PLAYER_FREQ(setupSeqPlayerIndex, targetSeqPlayerIndex, duration, freqScale) \ #define SEQCMD_SETUP_SET_SEQPLAYER_FREQ(setupSeqPlayerIndex, targetSeqPlayerIndex, duration, freqScale) \
Audio_QueueSeqCmd((SEQCMD_OP_SETUP_CMD << 28) | (SEQCMD_SUB_OP_SETUP_SET_PLAYER_FREQ << 20) | \ Audio_QueueSeqCmd((SEQCMD_OP_SETUP_CMD << 28) | (SEQCMD_SUB_OP_SETUP_SET_SEQPLAYER_FREQ << 20) | \
((u8)(setupSeqPlayerIndex) << 24) | ((u8)(targetSeqPlayerIndex) << 16) | ((u8)(duration) << 8) | \ ((u8)(setupSeqPlayerIndex) << 24) | ((u8)(targetSeqPlayerIndex) << 16) | ((u8)(duration) << 8) | \
(u8)(freqScale)) (u8)(freqScale))

View file

@ -37,7 +37,7 @@ typedef struct {
/* 0x2B */ u8 freshness; /* 0x2B */ u8 freshness;
/* 0x2C */ u8 prev; /* 0x2C */ u8 prev;
/* 0x2D */ u8 next; /* 0x2D */ u8 next;
/* 0x2E */ u8 channelIdx; /* 0x2E */ u8 channelIndex;
/* 0x2F */ u8 unk_2F; /* 0x2F */ u8 unk_2F;
} SfxBankEntry; // size = 0x30 } SfxBankEntry; // size = 0x30
@ -119,4 +119,10 @@ typedef struct {
u16 params; u16 params;
} SfxParams; } SfxParams;
#if OOT_DEBUG
#define SFX_DIST_SCALING 1.0f
#else
#define SFX_DIST_SCALING 10.0f
#endif
#endif #endif

View file

@ -1,8 +1,8 @@
/** /**
* Select dmadata table for version * Select dmadata table for version
*/ */
#ifdef NON_MATCHING #if !OOT_DEBUG || NON_MATCHING
// For non-matching builds, dmadata is generated from the specfile segments // For retail versions and non-matching builds, dmadata is generated from the specfile segments
#include "dmadata_table_spec.h" #include "dmadata_table_spec.h"
#else #else
#include "dmadata_table_mqdbg.h" #include "dmadata_table_mqdbg.h"

View file

@ -110,7 +110,7 @@
/* 0x62 */ DEFINE_SCENE(spot18_scene, g_pn_41, SCENE_GORON_CITY, SDC_GORON_CITY, 0, 0) /* 0x62 */ DEFINE_SCENE(spot18_scene, g_pn_41, SCENE_GORON_CITY, SDC_GORON_CITY, 0, 0)
/* 0x63 */ DEFINE_SCENE(spot20_scene, g_pn_42, SCENE_LON_LON_RANCH, SDC_LON_LON_RANCH, 0, 0) /* 0x63 */ DEFINE_SCENE(spot20_scene, g_pn_42, SCENE_LON_LON_RANCH, SDC_LON_LON_RANCH, 0, 0)
/* 0x64 */ DEFINE_SCENE(ganon_tou_scene, g_pn_43, SCENE_OUTSIDE_GANONS_CASTLE, SDC_OUTSIDE_GANONS_CASTLE, 0, 0) /* 0x64 */ DEFINE_SCENE(ganon_tou_scene, g_pn_43, SCENE_OUTSIDE_GANONS_CASTLE, SDC_OUTSIDE_GANONS_CASTLE, 0, 0)
// Debug-only scenes #if OOT_DEBUG
/* 0x65 */ DEFINE_SCENE(test01_scene, none, SCENE_TEST01, SDC_CALM_WATER, 0, 0) /* 0x65 */ DEFINE_SCENE(test01_scene, none, SCENE_TEST01, SDC_CALM_WATER, 0, 0)
/* 0x66 */ DEFINE_SCENE(besitu_scene, none, SCENE_BESITU, SDC_BESITU, 0, 0) /* 0x66 */ DEFINE_SCENE(besitu_scene, none, SCENE_BESITU, SDC_BESITU, 0, 0)
/* 0x67 */ DEFINE_SCENE(depth_test_scene, none, SCENE_DEPTH_TEST, SDC_DEFAULT, 0, 0) /* 0x67 */ DEFINE_SCENE(depth_test_scene, none, SCENE_DEPTH_TEST, SDC_DEFAULT, 0, 0)
@ -120,3 +120,4 @@
/* 0x6B */ DEFINE_SCENE(hairal_niwa2_scene, g_pn_12, SCENE_HAIRAL_NIWA2, SDC_CASTLE_COURTYARD_GUARDS, 0, 0) /* 0x6B */ DEFINE_SCENE(hairal_niwa2_scene, g_pn_12, SCENE_HAIRAL_NIWA2, SDC_CASTLE_COURTYARD_GUARDS, 0, 0)
/* 0x6C */ DEFINE_SCENE(sasatest_scene, none, SCENE_SASATEST, SDC_DEFAULT, 0, 0) /* 0x6C */ DEFINE_SCENE(sasatest_scene, none, SCENE_SASATEST, SDC_DEFAULT, 0, 0)
/* 0x6D */ DEFINE_SCENE(testroom_scene, none, SCENE_TESTROOM, SDC_DEFAULT, 0, 0) /* 0x6D */ DEFINE_SCENE(testroom_scene, none, SCENE_TESTROOM, SDC_DEFAULT, 0, 0)
#endif

View file

@ -5123,7 +5123,7 @@ _DW({ \
#define gDPNoOpTag(pkt, tag) gDPParam(pkt, G_NOOP, tag) #define gDPNoOpTag(pkt, tag) gDPParam(pkt, G_NOOP, tag)
#define gsDPNoOpTag(tag) gsDPParam( G_NOOP, tag) #define gsDPNoOpTag(tag) gsDPParam( G_NOOP, tag)
#ifdef OOT_DEBUG #if OOT_DEBUG
#define gDPNoOpHere(pkt, file, line) gDma1p(pkt, G_NOOP, file, line, 1) #define gDPNoOpHere(pkt, file, line) gDma1p(pkt, G_NOOP, file, line, 1)
#define gDPNoOpString(pkt, data, n) gDma1p(pkt, G_NOOP, data, n, 2) #define gDPNoOpString(pkt, data, n) gDma1p(pkt, G_NOOP, data, n, 2)

View file

@ -5,8 +5,8 @@
void osSyncPrintf(const char* fmt, ...); void osSyncPrintf(const char* fmt, ...);
void bzero(void* __s, size_t __n); void bzero(void* __s, int __n);
int bcmp(const void* __sl, const void* __s2, size_t __n); int bcmp(const void* __sl, const void* __s2, int __n);
void bcopy(const void* __src, void* __dest, size_t __n); void bcopy(const void* __src, void* __dest, int __n);
#endif #endif

View file

@ -9,7 +9,7 @@
#define osMotorStart(x) __osMotorAccess((x), MOTOR_START) #define osMotorStart(x) __osMotorAccess((x), MOTOR_START)
#define osMotorStop(x) __osMotorAccess((x), MOTOR_STOP) #define osMotorStop(x) __osMotorAccess((x), MOTOR_STOP)
s32 __osMotorAccess(OSPfs* pfs, u32 vibrate); s32 __osMotorAccess(OSPfs* pfs, s32 vibrate);
s32 osMotorInit(OSMesgQueue* ctrlrqueue, OSPfs* pfs, s32 channel); s32 osMotorInit(OSMesgQueue* ctrlrqueue, OSPfs* pfs, s32 channel);
#endif #endif

View file

@ -85,7 +85,7 @@ extern u32 gGsFlagsMasks[4];
extern u32 gGsFlagsShifts[4]; extern u32 gGsFlagsShifts[4];
extern void* gItemIcons[0x82]; extern void* gItemIcons[0x82];
extern u8 gItemSlots[56]; extern u8 gItemSlots[56];
extern void (*gSceneCmdHandlers[SCENE_CMD_ID_MAX])(PlayState*, SceneCmd*); extern SceneCmdHandlerFunc gSceneCmdHandlers[SCENE_CMD_ID_MAX];
extern s16 gLinkObjectIds[2]; extern s16 gLinkObjectIds[2];
extern u32 gObjectTableSize; extern u32 gObjectTableSize;
extern RomFile gObjectTable[OBJECT_ID_MAX]; extern RomFile gObjectTable[OBJECT_ID_MAX];
@ -103,7 +103,9 @@ extern s32 gScreenWidth;
extern s32 gScreenHeight; extern s32 gScreenHeight;
extern Mtx gMtxClear; extern Mtx gMtxClear;
extern MtxF gMtxFClear; extern MtxF gMtxFClear;
#if OOT_DEBUG
extern u32 gIsCtrlr2Valid; extern u32 gIsCtrlr2Valid;
#endif
extern s16* gWaveSamples[9]; extern s16* gWaveSamples[9];
extern f32 gBendPitchOneOctaveFrequencies[256]; extern f32 gBendPitchOneOctaveFrequencies[256];
extern f32 gBendPitchTwoSemitonesFrequencies[256]; extern f32 gBendPitchTwoSemitonesFrequencies[256];
@ -157,8 +159,7 @@ extern s32 gSystemArenaLogSeverity;
extern u8 __osPfsInodeCacheBank; extern u8 __osPfsInodeCacheBank;
extern s32 __osPfsLastChannel; extern s32 __osPfsLastChannel;
extern const s16 D_8014A6C0[]; extern const TempoData gTempoData;
#define gTatumsPerBeat (D_8014A6C0[1])
extern const AudioHeapInitSizes gAudioHeapInitSizes; extern const AudioHeapInitSizes gAudioHeapInitSizes;
extern s16 gOcarinaSongItemMap[]; extern s16 gOcarinaSongItemMap[];
extern u8 gSoundFontTable[]; extern u8 gSoundFontTable[];
@ -215,7 +216,7 @@ extern u16 gAudioSfxSwapTarget[10];
extern u8 gAudioSfxSwapMode[10]; extern u8 gAudioSfxSwapMode[10];
extern ActiveSequence gActiveSeqs[4]; extern ActiveSequence gActiveSeqs[4];
extern AudioContext gAudioCtx; extern AudioContext gAudioCtx;
extern void(*D_801755D0)(void); extern AudioCustomUpdateFunction gAudioCustomUpdateFunction;
extern u32 __osMalloc_FreeBlockTest_Enable; extern u32 __osMalloc_FreeBlockTest_Enable;
extern Arena gSystemArena; extern Arena gSystemArena;

View file

@ -38,6 +38,7 @@
#include "z64view.h" #include "z64view.h"
#include "z64vis.h" #include "z64vis.h"
#include "alignment.h" #include "alignment.h"
#include "audiothread_cmd.h"
#include "seqcmd.h" #include "seqcmd.h"
#include "sequence.h" #include "sequence.h"
#include "sfx.h" #include "sfx.h"
@ -695,8 +696,7 @@ typedef struct {
/* 0x04 */ u32 decSize; /* 0x04 */ u32 decSize;
/* 0x08 */ u32 compInfoOffset; // only used in mio0 /* 0x08 */ u32 compInfoOffset; // only used in mio0
/* 0x0C */ u32 uncompDataOffset; // only used in mio0 /* 0x0C */ u32 uncompDataOffset; // only used in mio0
/* 0x10 */ u8 data[1]; } Yaz0Header; // size = 0x10
} Yaz0Header; // size = 0x10 ("data" is not part of the header)
struct ArenaNode; struct ArenaNode;
@ -704,7 +704,7 @@ typedef struct Arena {
/* 0x00 */ struct ArenaNode* head; /* 0x00 */ struct ArenaNode* head;
/* 0x04 */ void* start; /* 0x04 */ void* start;
/* 0x08 */ OSMesgQueue lockQueue; /* 0x08 */ OSMesgQueue lockQueue;
/* 0x20 */ u8 unk_20; /* 0x20 */ u8 allocFailures; // only used in non-debug builds
/* 0x21 */ u8 isInit; /* 0x21 */ u8 isInit;
/* 0x22 */ u8 flag; /* 0x22 */ u8 flag;
} Arena; // size = 0x24 } Arena; // size = 0x24
@ -715,12 +715,14 @@ typedef struct ArenaNode {
/* 0x04 */ u32 size; /* 0x04 */ u32 size;
/* 0x08 */ struct ArenaNode* next; /* 0x08 */ struct ArenaNode* next;
/* 0x0C */ struct ArenaNode* prev; /* 0x0C */ struct ArenaNode* prev;
#if OOT_DEBUG // TODO: This debug info is also present in N64 retail builds
/* 0x10 */ const char* filename; /* 0x10 */ const char* filename;
/* 0x14 */ s32 line; /* 0x14 */ s32 line;
/* 0x18 */ OSId threadId; /* 0x18 */ OSId threadId;
/* 0x1C */ Arena* arena; /* 0x1C */ Arena* arena;
/* 0x20 */ OSTime time; /* 0x20 */ OSTime time;
/* 0x28 */ u8 unk_28[0x30-0x28]; // probably padding /* 0x28 */ u8 unk_28[0x30-0x28]; // probably padding
#endif
} ArenaNode; // size = 0x30 } ArenaNode; // size = 0x30
/* Relocation entry field getters */ /* Relocation entry field getters */

View file

@ -42,7 +42,11 @@ typedef struct {
/** /**
* @see ACTOROVL_ALLOC_ABSOLUTE * @see ACTOROVL_ALLOC_ABSOLUTE
*/ */
#if OOT_DEBUG
#define ACTOROVL_ABSOLUTE_SPACE_SIZE 0x27A0 #define ACTOROVL_ABSOLUTE_SPACE_SIZE 0x27A0
#else
#define ACTOROVL_ABSOLUTE_SPACE_SIZE 0x24E0
#endif
/** /**
* The actor overlay should be allocated memory for when loading, * The actor overlay should be allocated memory for when loading,
@ -305,7 +309,7 @@ typedef struct Actor {
/* 0x130 */ ActorFunc update; // Update Routine. Called by `Actor_UpdateAll` /* 0x130 */ ActorFunc update; // Update Routine. Called by `Actor_UpdateAll`
/* 0x134 */ ActorFunc draw; // Draw Routine. Called by `Actor_Draw` /* 0x134 */ ActorFunc draw; // Draw Routine. Called by `Actor_Draw`
/* 0x138 */ ActorOverlay* overlayEntry; // Pointer to the overlay table entry for this actor /* 0x138 */ ActorOverlay* overlayEntry; // Pointer to the overlay table entry for this actor
#ifdef OOT_DEBUG #if OOT_DEBUG
/* 0x13C */ char dbgPad[0x10]; /* 0x13C */ char dbgPad[0x10];
#endif #endif
} Actor; // size = 0x14C } Actor; // size = 0x14C

View file

@ -1,11 +1,25 @@
#ifndef Z64_AUDIO_H #ifndef Z64_AUDIO_H
#define Z64_AUDIO_H #define Z64_AUDIO_H
#define MK_CMD(b0,b1,b2,b3) ((((b0) & 0xFF) << 0x18) | (((b1) & 0xFF) << 0x10) | (((b2) & 0xFF) << 0x8) | (((b3) & 0xFF) << 0)) typedef void (*AudioCustomUpdateFunction)(void);
#define REFRESH_RATE_PAL 50
#define REFRESH_RATE_MPAL 60
#define REFRESH_RATE_NTSC 60
// Small deviation parameters used in estimating the max tempo
// It is unclear why these vary by region, and aren't all just 1
#define REFRESH_RATE_DEVIATION_PAL 1.001521f
#define REFRESH_RATE_DEVIATION_MPAL 0.99276f
#define REFRESH_RATE_DEVIATION_NTSC 1.00278f
#define AUDIO_MK_CMD(b0,b1,b2,b3) ((((b0) & 0xFF) << 0x18) | (((b1) & 0xFF) << 0x10) | (((b2) & 0xFF) << 0x8) | (((b3) & 0xFF) << 0))
#define NO_LAYER ((SequenceLayer*)(-1)) #define NO_LAYER ((SequenceLayer*)(-1))
#define TATUMS_PER_BEAT 48 // Also known as "Pulses Per Quarter Note" or "Tatums Per Beat"
#define SEQTICKS_PER_BEAT 48
#define IS_SEQUENCE_CHANNEL_VALID(ptr) ((u32)(ptr) != (u32)&gAudioCtx.sequenceChannelNone) #define IS_SEQUENCE_CHANNEL_VALID(ptr) ((u32)(ptr) != (u32)&gAudioCtx.sequenceChannelNone)
#define SEQ_NUM_CHANNELS 16 #define SEQ_NUM_CHANNELS 16
@ -297,12 +311,12 @@ typedef struct {
/* 0x005 */ u8 defaultFont; /* 0x005 */ u8 defaultFont;
/* 0x006 */ u8 unk_06[1]; /* 0x006 */ u8 unk_06[1];
/* 0x007 */ s8 playerIdx; /* 0x007 */ s8 playerIdx;
/* 0x008 */ u16 tempo; // tatums per minute /* 0x008 */ u16 tempo; // seqTicks per minute
/* 0x00A */ u16 tempoAcc; /* 0x00A */ u16 tempoAcc; // tempo accumulation, used in a discretized algorithm to apply tempo.
/* 0x00C */ u16 unk_0C; /* 0x00C */ u16 tempoChange; // Used to adjust the tempo without altering the base tempo.
/* 0x00E */ s16 transposition; /* 0x00E */ s16 transposition;
/* 0x010 */ u16 delay; /* 0x010 */ u16 delay;
/* 0x012 */ u16 fadeTimer; /* 0x012 */ u16 fadeTimer; // in ticks
/* 0x014 */ u16 fadeTimerUnkEu; /* 0x014 */ u16 fadeTimerUnkEu;
/* 0x018 */ u8* seqData; /* 0x018 */ u8* seqData;
/* 0x01C */ f32 fadeVolume; /* 0x01C */ f32 fadeVolume;
@ -320,7 +334,7 @@ typedef struct {
/* 0x0DC */ s32 skipTicks; /* 0x0DC */ s32 skipTicks;
/* 0x0E0 */ u32 scriptCounter; /* 0x0E0 */ u32 scriptCounter;
/* 0x0E4 */ char unk_E4[0x74]; // unused struct members for sequence/sound font dma management, according to sm64 decomp /* 0x0E4 */ char unk_E4[0x74]; // unused struct members for sequence/sound font dma management, according to sm64 decomp
/* 0x158 */ s8 soundScriptIO[8]; /* 0x158 */ s8 seqScriptIO[8];
} SequencePlayer; // size = 0x160 } SequencePlayer; // size = 0x160
typedef struct { typedef struct {
@ -332,7 +346,7 @@ typedef struct {
typedef struct { typedef struct {
/* 0x00 */ union { /* 0x00 */ union {
struct A { struct A {
/* 0x00 */ u8 unk_0b80 : 1; /* 0x00 */ u8 unused : 1;
/* 0x00 */ u8 hang : 1; /* 0x00 */ u8 hang : 1;
/* 0x00 */ u8 decay : 1; /* 0x00 */ u8 decay : 1;
/* 0x00 */ u8 release : 1; /* 0x00 */ u8 release : 1;
@ -370,8 +384,8 @@ typedef struct {
/* 0x01 */ u8 gain; // Increases volume by a multiplicative scaling factor. Represented as a UQ4.4 number /* 0x01 */ u8 gain; // Increases volume by a multiplicative scaling factor. Represented as a UQ4.4 number
/* 0x02 */ u8 pan; /* 0x02 */ u8 pan;
/* 0x03 */ Stereo stereo; /* 0x03 */ Stereo stereo;
/* 0x04 */ u8 unk_4; /* 0x04 */ u8 combFilterSize;
/* 0x06 */ u16 unk_6; /* 0x06 */ u16 combFilterGain;
/* 0x08 */ f32 freqScale; /* 0x08 */ f32 freqScale;
/* 0x0C */ f32 velocity; /* 0x0C */ f32 velocity;
/* 0x10 */ s16* filter; /* 0x10 */ s16* filter;
@ -383,7 +397,7 @@ typedef struct SequenceChannel {
/* 0x00 */ u8 enabled : 1; /* 0x00 */ u8 enabled : 1;
/* 0x00 */ u8 finished : 1; /* 0x00 */ u8 finished : 1;
/* 0x00 */ u8 stopScript : 1; /* 0x00 */ u8 stopScript : 1;
/* 0x00 */ u8 stopSomething2 : 1; // sets SequenceLayer.stopSomething /* 0x00 */ u8 muted : 1; // sets SequenceLayer.muted
/* 0x00 */ u8 hasInstrument : 1; /* 0x00 */ u8 hasInstrument : 1;
/* 0x00 */ u8 stereoHeadsetEffects : 1; /* 0x00 */ u8 stereoHeadsetEffects : 1;
/* 0x00 */ u8 largeNotes : 1; // notes specify duration and velocity /* 0x00 */ u8 largeNotes : 1; // notes specify duration and velocity
@ -398,7 +412,7 @@ typedef struct SequenceChannel {
} changes; } changes;
/* 0x02 */ u8 noteAllocPolicy; /* 0x02 */ u8 noteAllocPolicy;
/* 0x03 */ u8 muteBehavior; /* 0x03 */ u8 muteBehavior;
/* 0x04 */ u8 reverb; // or dry/wet mix /* 0x04 */ u8 targetReverbVol;
/* 0x05 */ u8 notePriority; // 0-3 /* 0x05 */ u8 notePriority; // 0-3
/* 0x06 */ u8 someOtherPriority; /* 0x06 */ u8 someOtherPriority;
/* 0x07 */ u8 fontId; /* 0x07 */ u8 fontId;
@ -409,16 +423,16 @@ typedef struct SequenceChannel {
/* 0x0C */ u8 gain; // Increases volume by a multiplicative scaling factor. Represented as a UQ4.4 number /* 0x0C */ u8 gain; // Increases volume by a multiplicative scaling factor. Represented as a UQ4.4 number
/* 0x0D */ u8 velocityRandomVariance; /* 0x0D */ u8 velocityRandomVariance;
/* 0x0E */ u8 gateTimeRandomVariance; /* 0x0E */ u8 gateTimeRandomVariance;
/* 0x0F */ u8 unk_0F; /* 0x0F */ u8 combFilterSize;
/* 0x10 */ u16 vibratoRateStart; /* 0x10 */ u16 vibratoRateStart;
/* 0x12 */ u16 vibratoExtentStart; /* 0x12 */ u16 vibratoDepthStart;
/* 0x14 */ u16 vibratoRateTarget; /* 0x14 */ u16 vibratoRateTarget;
/* 0x16 */ u16 vibratoExtentTarget; /* 0x16 */ u16 vibratoDepthTarget;
/* 0x18 */ u16 vibratoRateChangeDelay; /* 0x18 */ u16 vibratoRateChangeDelay;
/* 0x1A */ u16 vibratoExtentChangeDelay; /* 0x1A */ u16 vibratoDepthChangeDelay;
/* 0x1C */ u16 vibratoDelay; /* 0x1C */ u16 vibratoDelay;
/* 0x1E */ u16 delay; /* 0x1E */ u16 delay;
/* 0x20 */ u16 unk_20; /* 0x20 */ u16 combFilterGain;
/* 0x22 */ u16 unk_22; /* 0x22 */ u16 unk_22;
/* 0x24 */ s16 instOrWave; // either 0 (none), instrument index + 1, or /* 0x24 */ s16 instOrWave; // either 0 (none), instrument index + 1, or
// 0x80..0x83 for sawtooth/triangle/sine/square waves. // 0x80..0x83 for sawtooth/triangle/sine/square waves.
@ -437,7 +451,7 @@ typedef struct SequenceChannel {
/* 0x60 */ SeqScriptState scriptState; /* 0x60 */ SeqScriptState scriptState;
/* 0x7C */ AdsrSettings adsr; /* 0x7C */ AdsrSettings adsr;
/* 0x84 */ NotePool notePool; /* 0x84 */ NotePool notePool;
/* 0xC4 */ s8 soundScriptIO[8]; // bridge between sound script and audio lib, "io ports" /* 0xC4 */ s8 seqScriptIO[8]; // bridge between .seq script and audio lib, "io ports"
/* 0xCC */ s16* filter; /* 0xCC */ s16* filter;
/* 0xD0 */ Stereo stereo; /* 0xD0 */ Stereo stereo;
} SequenceChannel; // size = 0xD4 } SequenceChannel; // size = 0xD4
@ -446,7 +460,7 @@ typedef struct SequenceChannel {
typedef struct SequenceLayer { typedef struct SequenceLayer {
/* 0x00 */ u8 enabled : 1; /* 0x00 */ u8 enabled : 1;
/* 0x00 */ u8 finished : 1; /* 0x00 */ u8 finished : 1;
/* 0x00 */ u8 stopSomething : 1; /* 0x00 */ u8 muted : 1;
/* 0x00 */ u8 continuousNotes : 1; // keep the same note for consecutive notes with the same sound /* 0x00 */ u8 continuousNotes : 1; // keep the same note for consecutive notes with the same sound
/* 0x00 */ u8 bit3 : 1; // "loaded"? /* 0x00 */ u8 bit3 : 1; // "loaded"?
/* 0x00 */ u8 ignoreDrumPan : 1; /* 0x00 */ u8 ignoreDrumPan : 1;
@ -490,7 +504,7 @@ typedef struct {
/* 0x040 */ s16 mixEnvelopeState[32]; /* 0x040 */ s16 mixEnvelopeState[32];
/* 0x080 */ s16 unusedState[16]; /* 0x080 */ s16 unusedState[16];
/* 0x0A0 */ s16 haasEffectDelayState[32]; /* 0x0A0 */ s16 haasEffectDelayState[32];
/* 0x0E0 */ s16 unkState[128]; /* 0x0E0 */ s16 combFilterState[128];
} NoteSynthesisBuffers; // size = 0x1E0 } NoteSynthesisBuffers; // size = 0x1E0
typedef struct { typedef struct {
@ -505,23 +519,20 @@ typedef struct {
/* 0x0C */ NoteSynthesisBuffers* synthesisBuffers; /* 0x0C */ NoteSynthesisBuffers* synthesisBuffers;
/* 0x10 */ s16 curVolLeft; /* 0x10 */ s16 curVolLeft;
/* 0x12 */ s16 curVolRight; /* 0x12 */ s16 curVolRight;
/* 0x14 */ u16 unk_14; /* 0x14 */ char unk_14[0x6];
/* 0x16 */ u16 unk_16; /* 0x1A */ u8 combFilterNeedsInit;
/* 0x18 */ u16 unk_18; /* 0x1C */ char unk_1C[0x4];
/* 0x1A */ u8 unk_1A;
/* 0x1C */ u16 unk_1C;
/* 0x1E */ u16 unk_1E;
} NoteSynthesisState; // size = 0x20 } NoteSynthesisState; // size = 0x20
typedef struct { typedef struct {
/* 0x00 */ struct SequenceChannel* channel; /* 0x00 */ struct SequenceChannel* channel;
/* 0x04 */ u32 time; /* 0x04 */ u32 time;
/* 0x08 */ s16* curve; /* 0x08 */ s16* curve; // sineWave
/* 0x0C */ f32 extent; /* 0x0C */ f32 depth;
/* 0x10 */ f32 rate; /* 0x10 */ f32 rate;
/* 0x14 */ u8 active; /* 0x14 */ u8 active;
/* 0x16 */ u16 rateChangeTimer; /* 0x16 */ u16 rateChangeTimer;
/* 0x18 */ u16 extentChangeTimer; /* 0x18 */ u16 depthChangeTimer;
/* 0x1A */ u16 delay; /* 0x1A */ u16 delay;
} VibratoState; // size = 0x1C } VibratoState; // size = 0x1C
@ -567,11 +578,11 @@ typedef struct {
/* 0x04 */ u8 haasEffectRightDelaySize; /* 0x04 */ u8 haasEffectRightDelaySize;
/* 0x05 */ u8 reverbVol; /* 0x05 */ u8 reverbVol;
/* 0x06 */ u8 harmonicIndexCurAndPrev; // bits 3..2 store curHarmonicIndex, bits 1..0 store prevHarmonicIndex /* 0x06 */ u8 harmonicIndexCurAndPrev; // bits 3..2 store curHarmonicIndex, bits 1..0 store prevHarmonicIndex
/* 0x07 */ u8 unk_07; /* 0x07 */ u8 combFilterSize;
/* 0x08 */ u16 targetVolLeft; /* 0x08 */ u16 targetVolLeft;
/* 0x0A */ u16 targetVolRight; /* 0x0A */ u16 targetVolRight;
/* 0x0C */ u16 resamplingRateFixedPoint; /* 0x0C */ u16 resamplingRateFixedPoint;
/* 0x0E */ u16 unk_0E; /* 0x0E */ u16 combFilterGain;
/* 0x10 */ union { /* 0x10 */ union {
TunedSample* tunedSample; TunedSample* tunedSample;
s16* waveSampleAddr; // used for synthetic waves s16* waveSampleAddr; // used for synthetic waves
@ -642,15 +653,15 @@ typedef struct {
/* 0x06 */ s16 samplesPerFrameTarget; /* 0x06 */ s16 samplesPerFrameTarget;
/* 0x08 */ s16 maxAiBufferLength; /* 0x08 */ s16 maxAiBufferLength;
/* 0x0A */ s16 minAiBufferLength; /* 0x0A */ s16 minAiBufferLength;
/* 0x0C */ s16 updatesPerFrame; // for each frame of the audio thread (default 60 fps), number of updates to process audio /* 0x0C */ s16 ticksPerUpdate; // for each audio thread update, number of ticks to process audio
/* 0x0E */ s16 samplesPerUpdate; /* 0x0E */ s16 samplesPerTick;
/* 0x10 */ s16 samplesPerUpdateMax; /* 0x10 */ s16 samplesPerTickMax;
/* 0x12 */ s16 samplesPerUpdateMin; /* 0x12 */ s16 samplesPerTickMin;
/* 0x14 */ s16 numSequencePlayers; /* 0x14 */ s16 numSequencePlayers;
/* 0x18 */ f32 resampleRate; /* 0x18 */ f32 resampleRate;
/* 0x1C */ f32 updatesPerFrameInv; // inverse (reciprocal) of updatesPerFrame /* 0x1C */ f32 ticksPerUpdateInv; // inverse (reciprocal) of ticksPerUpdate
/* 0x20 */ f32 updatesPerFrameInvScaled; // updatesPerFrameInv scaled down by a factor of 256 /* 0x20 */ f32 ticksPerUpdateInvScaled; // ticksPerUpdateInv scaled down by a factor of 256
/* 0x24 */ f32 updatesPerFrameScaled; // updatesPerFrame scaled down by a factor of 4 /* 0x24 */ f32 ticksPerUpdateScaled; // ticksPerUpdate scaled down by a factor of 4
} AudioBufferParameters; // size = 0x28 } AudioBufferParameters; // size = 0x28
/** /**
@ -887,7 +898,7 @@ typedef struct {
/* 0x288C */ s32 sampleDmaBufSize; /* 0x288C */ s32 sampleDmaBufSize;
/* 0x2890 */ s32 maxAudioCmds; /* 0x2890 */ s32 maxAudioCmds;
/* 0x2894 */ s32 numNotes; /* 0x2894 */ s32 numNotes;
/* 0x2898 */ s16 tempoInternalToExternal; /* 0x2898 */ s16 maxTempo; // Maximum possible tempo (seqTicks per minute), using every tick as a seqTick to process a .seq file
/* 0x289A */ s8 soundMode; /* 0x289A */ s8 soundMode;
/* 0x289C */ s32 totalTaskCount; // The total number of times the top-level function on the audio thread has run since audio was initialized /* 0x289C */ s32 totalTaskCount; // The total number of times the top-level function on the audio thread has run since audio was initialized
/* 0x28A0 */ s32 curAudioFrameDmaCount; /* 0x28A0 */ s32 curAudioFrameDmaCount;
@ -898,7 +909,7 @@ typedef struct {
/* 0x28B8 */ AudioTask* curTask; /* 0x28B8 */ AudioTask* curTask;
/* 0x28BC */ char unk_28BC[0x4]; /* 0x28BC */ char unk_28BC[0x4];
/* 0x28C0 */ AudioTask rspTask[2]; /* 0x28C0 */ AudioTask rspTask[2];
/* 0x2960 */ f32 unk_2960; /* 0x2960 */ f32 maxTempoTvTypeFactors; // tvType factors that impact maxTempo, in units of milliseconds/frame
/* 0x2964 */ s32 refreshRate; /* 0x2964 */ s32 refreshRate;
/* 0x2968 */ s16* aiBuffers[3]; /* 0x2968 */ s16* aiBuffers[3];
/* 0x2974 */ s16 aiBufLengths[3]; /* 0x2974 */ s16 aiBufLengths[3];
@ -929,7 +940,7 @@ typedef struct {
/* 0x3468 */ u8 fontLoadStatus[0x30]; /* 0x3468 */ u8 fontLoadStatus[0x30];
/* 0x3498 */ u8 seqLoadStatus[0x80]; /* 0x3498 */ u8 seqLoadStatus[0x80];
/* 0x3518 */ volatile u8 resetStatus; /* 0x3518 */ volatile u8 resetStatus;
/* 0x3519 */ u8 audioResetSpecIdToLoad; /* 0x3519 */ u8 specId;
/* 0x351C */ s32 audioResetFadeOutFramesLeft; /* 0x351C */ s32 audioResetFadeOutFramesLeft;
/* 0x3520 */ f32* adsrDecayTable; // A table on the audio heap that stores decay rates used for adsr /* 0x3520 */ f32* adsrDecayTable; // A table on the audio heap that stores decay rates used for adsr
/* 0x3524 */ u8* audioHeap; /* 0x3524 */ u8* audioHeap;
@ -941,20 +952,20 @@ typedef struct {
/* 0x5B84 */ s32 noteSubEuOffset; /* 0x5B84 */ s32 noteSubEuOffset;
/* 0x5B88 */ AudioListItem layerFreeList; /* 0x5B88 */ AudioListItem layerFreeList;
/* 0x5B98 */ NotePool noteFreeLists; /* 0x5B98 */ NotePool noteFreeLists;
/* 0x5BD8 */ u8 cmdWrPos; /* 0x5BD8 */ u8 threadCmdWritePos;
/* 0x5BD9 */ u8 cmdRdPos; /* 0x5BD9 */ u8 threadCmdReadPos;
/* 0x5BDA */ u8 cmdQueueFinished; /* 0x5BDA */ u8 threadCmdQueueFinished;
/* 0x5BDC */ u16 unk_5BDC[4]; /* 0x5BDC */ u16 threadCmdChannelMask[4]; // bitfield for 16 channels. When processing an audio thread channel command on all channels, only process channels with their bit set.
/* 0x5BE4 */ OSMesgQueue* audioResetQueueP; /* 0x5BE4 */ OSMesgQueue* audioResetQueueP;
/* 0x5BE8 */ OSMesgQueue* taskStartQueueP; /* 0x5BE8 */ OSMesgQueue* taskStartQueueP;
/* 0x5BEC */ OSMesgQueue* cmdProcQueueP; /* 0x5BEC */ OSMesgQueue* threadCmdProcQueueP;
/* 0x5BF0 */ OSMesgQueue taskStartQueue; /* 0x5BF0 */ OSMesgQueue taskStartQueue;
/* 0x5C08 */ OSMesgQueue cmdProcQueue; /* 0x5C08 */ OSMesgQueue threadCmdProcQueue;
/* 0x5C20 */ OSMesgQueue audioResetQueue; /* 0x5C20 */ OSMesgQueue audioResetQueue;
/* 0x5C38 */ OSMesg taskStartMsgBuf[1]; /* 0x5C38 */ OSMesg taskStartMsgBuf[1];
/* 0x5C3C */ OSMesg audioResetMsgBuf[1]; /* 0x5C3C */ OSMesg audioResetMsgBuf[1];
/* 0x5C40 */ OSMesg cmdProcMsgBuf[4]; /* 0x5C40 */ OSMesg threadCmdProcMsgBuf[4];
/* 0x5C50 */ AudioCmd cmdBuf[0x100]; // Audio commands used to transfer audio requests from the graph thread to the audio thread /* 0x5C50 */ AudioCmd threadCmdBuf[0x100]; // Audio thread commands used to transfer audio requests from the graph thread to the audio thread
} AudioContext; // size = 0x6450 } AudioContext; // size = 0x6450
typedef struct { typedef struct {
@ -966,10 +977,15 @@ typedef struct {
/* 0x08 */ f32 velocity; /* 0x08 */ f32 velocity;
/* 0x0C */ char unk_0C[0x4]; /* 0x0C */ char unk_0C[0x4];
/* 0x10 */ s16* filter; /* 0x10 */ s16* filter;
/* 0x14 */ u8 unk_14; /* 0x14 */ u8 combFilterSize;
/* 0x16 */ u16 unk_16; /* 0x16 */ u16 combFilterGain;
} NoteSubAttributes; // size = 0x18 } NoteSubAttributes; // size = 0x18
typedef struct {
/* 0x0 */ s16 unk_00; // set to 0x1C00, unused
/* 0x2 */ s16 seqTicksPerBeat;
} TempoData; // size = 0x4
typedef struct { typedef struct {
/* 0x00 */ u32 heapSize; // total number of bytes allocated to the audio heap. Must be <= the size of `gAudioHeap` (ideally about the same size) /* 0x00 */ u32 heapSize; // total number of bytes allocated to the audio heap. Must be <= the size of `gAudioHeap` (ideally about the same size)
/* 0x04 */ u32 initPoolSize; // The entire audio heap is split into two pools. /* 0x04 */ u32 initPoolSize; // The entire audio heap is split into two pools.

View file

@ -46,9 +46,11 @@ extern size_t gDmaMgrDmaBuffSize;
s32 DmaMgr_RequestAsync(DmaRequest* req, void* ram, uintptr_t vrom, size_t size, u32 unk5, OSMesgQueue* queue, s32 DmaMgr_RequestAsync(DmaRequest* req, void* ram, uintptr_t vrom, size_t size, u32 unk5, OSMesgQueue* queue,
OSMesg msg); OSMesg msg);
s32 DmaMgr_RequestSync(void* ram, uintptr_t vrom, size_t size); s32 DmaMgr_RequestSync(void* ram, uintptr_t vrom, size_t size);
#if OOT_DEBUG
s32 DmaMgr_RequestAsyncDebug(DmaRequest* req, void* ram, uintptr_t vrom, size_t size, u32 unk5, OSMesgQueue* queue, s32 DmaMgr_RequestAsyncDebug(DmaRequest* req, void* ram, uintptr_t vrom, size_t size, u32 unk5, OSMesgQueue* queue,
OSMesg msg, const char* file, s32 line); OSMesg msg, const char* file, s32 line);
s32 DmaMgr_RequestSyncDebug(void* ram, uintptr_t vrom, size_t size, const char* file, s32 line); s32 DmaMgr_RequestSyncDebug(void* ram, uintptr_t vrom, size_t size, const char* file, s32 line);
#endif
// Special-purpose DMA Requests // Special-purpose DMA Requests

View file

@ -464,7 +464,7 @@ typedef enum {
#define EVENTCHKINF_4C 0x4C #define EVENTCHKINF_4C 0x4C
#define EVENTCHKINF_4D 0x4D #define EVENTCHKINF_4D 0x4D
#define EVENTCHKINF_4E 0x4E #define EVENTCHKINF_4E 0x4E
#define EVENTCHKINF_4F 0x4F #define EVENTCHKINF_WATCHED_SHEIK_AFTER_MASTER_SWORD_CS 0x4F // Cutscene in Temple of Time as adult after pulling the Master Sword for the first time
#define EVENTCHKINF_50 0x50 #define EVENTCHKINF_50 0x50
#define EVENTCHKINF_51 0x51 #define EVENTCHKINF_51 0x51
#define EVENTCHKINF_52 0x52 #define EVENTCHKINF_52 0x52

View file

@ -344,6 +344,8 @@ typedef union {
SCmdAltHeaders altHeaders; SCmdAltHeaders altHeaders;
} SceneCmd; // size = 0x8 } SceneCmd; // size = 0x8
typedef BAD_RETURN(s32) (*SceneCmdHandlerFunc)(struct PlayState*, SceneCmd*);
#define DEFINE_SCENE(_0, _1, enum, _3, _4, _5) enum, #define DEFINE_SCENE(_0, _1, enum, _3, _4, _5) enum,
typedef enum { typedef enum {
@ -353,9 +355,21 @@ typedef enum {
#undef DEFINE_SCENE #undef DEFINE_SCENE
// this define exists to preserve shiftability for an unused scene that is // Fake enum values for scenes that are still referenced in the entrance table
// listed in the entrance table #if !OOT_DEBUG
#define SCENE_UNUSED_6E SCENE_ID_MAX // Debug-only scenes
#define SCENE_TEST01 0x65
#define SCENE_BESITU 0x66
#define SCENE_DEPTH_TEST 0x67
#define SCENE_SYOTES 0x68
#define SCENE_SYOTES2 0x69
#define SCENE_SUTARU 0x6A
#define SCENE_HAIRAL_NIWA2 0x6B
#define SCENE_SASATEST 0x6C
#define SCENE_TESTROOM 0x6D
#endif
// Deleted scene
#define SCENE_UNUSED_6E 0x6E
// Entrance Index Enum // Entrance Index Enum
#define DEFINE_ENTRANCE(enum, _1, _2, _3, _4, _5, _6) enum, #define DEFINE_ENTRANCE(enum, _1, _2, _3, _4, _5, _6) enum,

View file

@ -49,4 +49,10 @@ typedef struct {
#define VIEW_FORCE_PROJECTION_PERSPECTIVE (VIEW_PROJECTION_PERSPECTIVE << 4) #define VIEW_FORCE_PROJECTION_PERSPECTIVE (VIEW_PROJECTION_PERSPECTIVE << 4)
#define VIEW_FORCE_PROJECTION_ORTHO (VIEW_PROJECTION_ORTHO << 4) #define VIEW_FORCE_PROJECTION_ORTHO (VIEW_PROJECTION_ORTHO << 4)
#if OOT_DEBUG
#define VIEW_ERROR_CHECK_EYE_POS(x, y, z) View_ErrorCheckEyePosition((x), (y), (z))
#else
#define VIEW_ERROR_CHECK_EYE_POS(x, y, z) (void)0
#endif
#endif #endif

View file

@ -61,7 +61,7 @@ def IsCFile(objfile):
srcfile = objfile.strip().replace("build/gc-eu-mq-dbg/", "").replace(".o", ".c") srcfile = objfile.strip().replace("build/gc-eu-mq-dbg/", "").replace(".o", ".c")
return os.path.isfile(srcfile) return os.path.isfile(srcfile)
mapFile = ReadAllLines("build/gc-eu-mq-dbg/z64.map") mapFile = ReadAllLines("build/gc-eu-mq-dbg/oot-gc-eu-mq-dbg.map")
curSegment = None curSegment = None
src = 0 src = 0
code = 0 code = 0

View file

@ -16,3 +16,4 @@ toml
# tools # tools
mapfile-parser>=1.2.1,<2.0.0 mapfile-parser>=1.2.1,<2.0.0
rabbitizer>=1.0.0,<2.0.0 rabbitizer>=1.0.0,<2.0.0
spimdisasm>=1.20.0,<2.0.0

245
retail_progress.py Executable file
View file

@ -0,0 +1,245 @@
#!/usr/bin/env python3
# SPDX-FileCopyrightText: © 2024 ZeldaRET
# SPDX-License-Identifier: CC0-1.0
import argparse
import collections
from dataclasses import dataclass
import difflib
from enum import Enum
import itertools
import math
from pathlib import Path
import re
import subprocess
import sys
from typing import Iterator, List, Optional, Tuple
@dataclass
class Inst:
func_name: str
mnemonic: str
regs: List[str]
imm: Optional[int]
reloc_type: Optional[str]
reloc_symbol: Optional[str]
FUNC_RE = re.compile(r"([0-9a-f]+) <(.*)>:")
def parse_func_name(line: str) -> str:
match = FUNC_RE.match(line)
if not match:
raise Exception(f"could not parse function name from '{line}'")
return match.group(2)
def is_branch(mnemonic: str) -> bool:
return mnemonic.startswith("b") and mnemonic != "break"
def parse_inst(func_name: str, line: str) -> Inst:
parts = line.split()
addr = int(parts[0][:-1], 16)
mnemonic = parts[2]
regs = []
imm = None
if len(parts) > 3:
for part in parts[3].split(","):
if "(" in part: # load/store
offset_str, rest = part.split("(")
regs.append(rest[:-1])
imm = int(offset_str, 10)
elif is_branch(mnemonic):
try:
# convert branch targets to relative offsets
offset = int(part, 16)
imm = offset - addr - 4
except ValueError:
regs.append(part)
else:
try:
imm = int(part, 0)
except ValueError:
regs.append(part)
return Inst(func_name, mnemonic, regs, imm, None, None)
def run_objdump(path: Path) -> List[Inst]:
if not path.exists():
raise Exception(f"file {path} does not exist")
command = [
"mips-linux-gnu-objdump",
"-drz",
"-m",
"mips:4300",
"-j",
".text",
str(path),
]
try:
lines = subprocess.run(
command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
check=True,
encoding="utf-8",
).stdout.splitlines()
except subprocess.CalledProcessError as e:
return []
result = []
func_name = None
i = 6 # skip preamble
while i < len(lines):
row = lines[i]
i += 1
if not row:
continue
if not row.startswith(" "):
func_name = parse_func_name(row)
continue
if not func_name:
raise Exception(f"no function name for line '{row}'")
inst = parse_inst(func_name, row)
if i < len(lines) and lines[i].startswith("\t"):
reloc = lines[i]
i += 1
_, inst.reloc_type, inst.reloc_symbol = reloc.split()
result.append(inst)
# trim trailing nops
while result and result[-1].mnemonic == "nop":
result.pop()
return result
def pair_instructions(
insts1: List[Inst], insts2: List[Inst]
) -> Iterator[Tuple[Optional[Inst], Optional[Inst]]]:
differ = difflib.SequenceMatcher(
a=[(inst.func_name, inst.mnemonic) for inst in insts1],
b=[(inst.func_name, inst.mnemonic) for inst in insts2],
autojunk=False,
)
for tag, i1, i2, j1, j2 in differ.get_opcodes():
for inst1, inst2 in itertools.zip_longest(insts1[i1:i2], insts2[j1:j2]):
yield (inst1, inst2)
def has_diff(inst1: Inst, inst2: Inst) -> bool:
if (
inst1.func_name != inst2.func_name
or inst1.mnemonic != inst2.mnemonic
or inst1.regs != inst2.regs
):
return True
if inst1.reloc_type == inst2.reloc_type and inst1.reloc_type in (
"R_MIPS_HI16",
"R_MIPS_LO16",
):
# ignore symbol differences
return False
return inst1 != inst2
def find_functions_with_diffs(version: str, c_path: str):
object_path = Path(c_path).with_suffix(".o")
expected_dir = Path("expected/build") / version
build_dir = Path("build") / version
insts1 = run_objdump(expected_dir / object_path)
insts2 = run_objdump(build_dir / object_path)
functions_with_diffs = collections.OrderedDict()
for inst1, inst2 in pair_instructions(insts1, insts2):
if inst1 is None and inst2 is not None:
functions_with_diffs[inst2.func_name] = True
elif inst1 is not None and inst2 is None:
functions_with_diffs[inst1.func_name] = True
elif inst1 is not None and inst2 is not None and has_diff(inst1, inst2):
functions_with_diffs[inst1.func_name] = True
functions_with_diffs[inst2.func_name] = True
if not functions_with_diffs:
print(f"{c_path} OK")
return
print(f"{c_path} functions with diffs:")
for func_name in functions_with_diffs:
print(f" {func_name}")
def print_summary(version: str, csv: bool):
expected_dir = Path("expected/build") / version
build_dir = Path("build") / version
if csv:
print("path,expected,actual,added,removed,changed,progress")
for object_file in sorted(expected_dir.glob("src/**/*.o")):
object_path = object_file.relative_to(expected_dir)
c_path = object_path.with_suffix(".c")
insts1 = run_objdump(expected_dir / object_path)
insts2 = run_objdump(build_dir / object_path)
added = 0
removed = 0
changed = 0
for inst1, inst2 in pair_instructions(insts1, insts2):
if inst1 is None and inst2 is not None:
added += 1
elif inst1 is not None and inst2 is None:
removed += 1
elif inst1 is not None and inst2 is not None and has_diff(inst1, inst2):
changed += 1
if insts1:
progress = max(1.0 - (added + removed + changed) / len(insts1), 0)
else:
progress = 1.0
if csv:
print(
f"{c_path},{len(insts1)},{len(insts2)},{added},{removed},{changed},{progress:.3f}"
)
elif progress == 1.0:
print(f" OK {c_path}")
else:
print(f" {math.floor(progress * 100):>2}% {c_path}")
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Calculate progress matching .text sections"
)
parser.add_argument(
"file",
metavar="FILE",
nargs="?",
help="find functions with diffs in the given source file (if omitted, print summary of diffs for all files)",
)
parser.add_argument(
"-v", "--version", help="version to compare", default="gc-eu-mq"
)
parser.add_argument("--csv", help="print summary CSV", action="store_true")
args = parser.parse_args()
if args.file is not None:
find_functions_with_diffs(args.version, args.file)
else:
print_summary(args.version, args.csv)

16
spec
View file

@ -400,6 +400,7 @@ beginseg
include "$(BUILD_DIR)/src/code/game.o" include "$(BUILD_DIR)/src/code/game.o"
include "$(BUILD_DIR)/src/code/gamealloc.o" include "$(BUILD_DIR)/src/code/gamealloc.o"
include "$(BUILD_DIR)/src/code/graph.o" include "$(BUILD_DIR)/src/code/graph.o"
include "$(BUILD_DIR)/src/code/gfxalloc.o"
include "$(BUILD_DIR)/src/code/listalloc.o" include "$(BUILD_DIR)/src/code/listalloc.o"
include "$(BUILD_DIR)/src/code/main.o" include "$(BUILD_DIR)/src/code/main.o"
include "$(BUILD_DIR)/src/code/padmgr.o" include "$(BUILD_DIR)/src/code/padmgr.o"
@ -537,6 +538,7 @@ endseg
beginseg beginseg
name "buffers" name "buffers"
flags NOLOAD
align 0x40 align 0x40
include "$(BUILD_DIR)/src/buffers/zbuffer.o" include "$(BUILD_DIR)/src/buffers/zbuffer.o"
include "$(BUILD_DIR)/src/buffers/gfxbuffers.o" include "$(BUILD_DIR)/src/buffers/gfxbuffers.o"
@ -9626,6 +9628,7 @@ beginseg
number 3 number 3
endseg endseg
#if OOT_DEBUG
beginseg beginseg
name "syotes_scene" name "syotes_scene"
romalign 0x1000 romalign 0x1000
@ -9667,6 +9670,7 @@ beginseg
include "$(BUILD_DIR)/assets/scenes/test_levels/depth_test/depth_test_room_0.o" include "$(BUILD_DIR)/assets/scenes/test_levels/depth_test/depth_test_room_0.o"
number 3 number 3
endseg endseg
#endif
beginseg beginseg
name "spot00_scene" name "spot00_scene"
@ -10148,6 +10152,7 @@ beginseg
number 3 number 3
endseg endseg
#if OOT_DEBUG
beginseg beginseg
name "testroom_scene" name "testroom_scene"
romalign 0x1000 romalign 0x1000
@ -10189,6 +10194,7 @@ beginseg
include "$(BUILD_DIR)/assets/scenes/test_levels/testroom/testroom_room_4.o" include "$(BUILD_DIR)/assets/scenes/test_levels/testroom/testroom_room_4.o"
number 3 number 3
endseg endseg
#endif
beginseg beginseg
name "kenjyanoma_scene" name "kenjyanoma_scene"
@ -10230,6 +10236,7 @@ beginseg
number 3 number 3
endseg endseg
#if OOT_DEBUG
beginseg beginseg
name "sutaru_scene" name "sutaru_scene"
romalign 0x1000 romalign 0x1000
@ -10243,6 +10250,7 @@ beginseg
include "$(BUILD_DIR)/assets/scenes/test_levels/sutaru/sutaru_room_0.o" include "$(BUILD_DIR)/assets/scenes/test_levels/sutaru/sutaru_room_0.o"
number 3 number 3
endseg endseg
#endif
beginseg beginseg
name "link_home_scene" name "link_home_scene"
@ -10516,6 +10524,7 @@ beginseg
number 3 number 3
endseg endseg
#if OOT_DEBUG
beginseg beginseg
name "sasatest_scene" name "sasatest_scene"
romalign 0x1000 romalign 0x1000
@ -10529,6 +10538,7 @@ beginseg
include "$(BUILD_DIR)/assets/scenes/test_levels/sasatest/sasatest_room_0.o" include "$(BUILD_DIR)/assets/scenes/test_levels/sasatest/sasatest_room_0.o"
number 3 number 3
endseg endseg
#endif
beginseg beginseg
name "market_alley_scene" name "market_alley_scene"
@ -11266,6 +11276,7 @@ beginseg
number 3 number 3
endseg endseg
#if OOT_DEBUG
beginseg beginseg
name "hairal_niwa2_scene" name "hairal_niwa2_scene"
romalign 0x1000 romalign 0x1000
@ -11279,6 +11290,7 @@ beginseg
include "$(BUILD_DIR)/assets/scenes/indoors/hairal_niwa2/hairal_niwa2_room_0.o" include "$(BUILD_DIR)/assets/scenes/indoors/hairal_niwa2/hairal_niwa2_room_0.o"
number 3 number 3
endseg endseg
#endif
beginseg beginseg
name "hakasitarelay_scene" name "hakasitarelay_scene"
@ -11752,6 +11764,7 @@ beginseg
number 3 number 3
endseg endseg
#if OOT_DEBUG
beginseg beginseg
name "besitu_scene" name "besitu_scene"
romalign 0x1000 romalign 0x1000
@ -11765,6 +11778,7 @@ beginseg
include "$(BUILD_DIR)/assets/scenes/test_levels/besitu/besitu_room_0.o" include "$(BUILD_DIR)/assets/scenes/test_levels/besitu/besitu_room_0.o"
number 3 number 3
endseg endseg
#endif
beginseg beginseg
name "face_shop_scene" name "face_shop_scene"
@ -11822,6 +11836,7 @@ beginseg
number 3 number 3
endseg endseg
#if OOT_DEBUG
beginseg beginseg
name "test01_scene" name "test01_scene"
romalign 0x1000 romalign 0x1000
@ -11835,6 +11850,7 @@ beginseg
include "$(BUILD_DIR)/assets/scenes/test_levels/test01/test01_room_0.o" include "$(BUILD_DIR)/assets/scenes/test_levels/test01/test01_room_0.o"
number 3 number 3
endseg endseg
#endif
beginseg beginseg
name "bump_texture_static" name "bump_texture_static"

1381
src/audio/debug.inc.c Normal file

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -113,8 +113,8 @@ f32 Audio_GetVibratoFreqScale(VibratoState* vib) {
static f32 D_80130510 = 0.0f; static f32 D_80130510 = 0.0f;
static s32 D_80130514 = 0; static s32 D_80130514 = 0;
f32 pitchChange; f32 pitchChange;
f32 extent; f32 depth;
f32 invExtent; f32 invDepth;
f32 result; f32 result;
f32 temp; f32 temp;
SequenceChannel* channel = vib->channel; SequenceChannel* channel = vib->channel;
@ -127,17 +127,17 @@ f32 Audio_GetVibratoFreqScale(VibratoState* vib) {
//! @bug this probably meant to compare with gAudioCtx.sequenceChannelNone. //! @bug this probably meant to compare with gAudioCtx.sequenceChannelNone.
//! -1 isn't used as a channel pointer anywhere else. //! -1 isn't used as a channel pointer anywhere else.
if (channel != ((SequenceChannel*)(-1))) { if (channel != ((SequenceChannel*)(-1))) {
if (vib->extentChangeTimer) { if (vib->depthChangeTimer) {
if (vib->extentChangeTimer == 1) { if (vib->depthChangeTimer == 1) {
vib->extent = (s32)channel->vibratoExtentTarget; vib->depth = (s32)channel->vibratoDepthTarget;
} else { } else {
vib->extent += ((s32)channel->vibratoExtentTarget - vib->extent) / (s32)vib->extentChangeTimer; vib->depth += ((s32)channel->vibratoDepthTarget - vib->depth) / (s32)vib->depthChangeTimer;
} }
vib->extentChangeTimer--; vib->depthChangeTimer--;
} else if (channel->vibratoExtentTarget != (s32)vib->extent) { } else if (channel->vibratoDepthTarget != (s32)vib->depth) {
if ((vib->extentChangeTimer = channel->vibratoExtentChangeDelay) == 0) { if ((vib->depthChangeTimer = channel->vibratoDepthChangeDelay) == 0) {
vib->extent = (s32)channel->vibratoExtentTarget; vib->depth = (s32)channel->vibratoDepthTarget;
} }
} }
@ -156,16 +156,16 @@ f32 Audio_GetVibratoFreqScale(VibratoState* vib) {
} }
} }
if (vib->extent == 0.0f) { if (vib->depth == 0.0f) {
return 1.0f; return 1.0f;
} }
pitchChange = Audio_GetVibratoPitchChange(vib) + 32768.0f; pitchChange = Audio_GetVibratoPitchChange(vib) + 32768.0f;
temp = vib->extent / 4096.0f; temp = vib->depth / 4096.0f;
extent = temp + 1.0f; depth = temp + 1.0f;
invExtent = 1.0f / extent; invDepth = 1.0f / depth;
result = 1.0f / ((extent - invExtent) * pitchChange / 65536.0f + invExtent); result = 1.0f / ((depth - invDepth) * pitchChange / 65536.0f + invDepth);
D_80130510 += result; D_80130510 += result;
D_80130514++; D_80130514++;
@ -190,16 +190,16 @@ void Audio_NoteVibratoInit(Note* note) {
vib = &note->playbackState.vibratoState; vib = &note->playbackState.vibratoState;
vib->active = 1; vib->active = true;
vib->time = 0; vib->time = 0;
vib->curve = gWaveSamples[2]; // gSineWaveSample[0..63]
vib->curve = gWaveSamples[2];
vib->channel = note->playbackState.parentLayer->channel; vib->channel = note->playbackState.parentLayer->channel;
channel = vib->channel; channel = vib->channel;
if ((vib->extentChangeTimer = channel->vibratoExtentChangeDelay) == 0) { if ((vib->depthChangeTimer = channel->vibratoDepthChangeDelay) == 0) {
vib->extent = (s32)channel->vibratoExtentTarget; vib->depth = (s32)channel->vibratoDepthTarget;
} else { } else {
vib->extent = (s32)channel->vibratoExtentStart; vib->depth = (s32)channel->vibratoDepthStart;
} }
if ((vib->rateChangeTimer = channel->vibratoRateChangeDelay) == 0) { if ((vib->rateChangeTimer = channel->vibratoRateChangeDelay) == 0) {
@ -264,7 +264,7 @@ f32 Audio_AdsrUpdate(AdsrState* adsr) {
break; break;
default: default:
adsr->delay *= gAudioCtx.audioBufferParameters.updatesPerFrameScaled; adsr->delay *= gAudioCtx.audioBufferParameters.ticksPerUpdateScaled;
if (adsr->delay == 0) { if (adsr->delay == 0) {
adsr->delay = 1; adsr->delay = 1;
} }

View file

@ -11,12 +11,10 @@ void AudioHeap_DiscardSampleBank(s32 sampleBankId);
void AudioHeap_DiscardSampleBanks(void); void AudioHeap_DiscardSampleBanks(void);
/** /**
* Effectively scales `updatesPerFrameInv` by the reciprocal of `scaleInv` * Effectively scales `ticksPerUpdateInv` by the reciprocal of `scaleInv`
* `updatesPerFrameInvScaled` is just `updatesPerFrameInv` scaled down by a factor of 256.0f
* i.e. (256.0f * `updatesPerFrameInvScaled`) is just `updatesPerFrameInv`
*/ */
f32 AudioHeap_CalculateAdsrDecay(f32 scaleInv) { f32 AudioHeap_CalculateAdsrDecay(f32 scaleInv) {
return (256.0f * gAudioCtx.audioBufferParameters.updatesPerFrameInvScaled) / scaleInv; return (256.0f * gAudioCtx.audioBufferParameters.ticksPerUpdateInvScaled) / scaleInv;
} }
/** /**
@ -96,7 +94,7 @@ void AudioHeap_ReleaseNotesForFont(s32 fontId) {
if (playbackState->fontId == fontId) { if (playbackState->fontId == fontId) {
if ((playbackState->priority != 0) && (playbackState->adsr.action.s.state == ADSR_STATE_DECAY)) { if ((playbackState->priority != 0) && (playbackState->adsr.action.s.state == ADSR_STATE_DECAY)) {
playbackState->priority = 1; playbackState->priority = 1;
playbackState->adsr.fadeOutVel = gAudioCtx.audioBufferParameters.updatesPerFrameInv; playbackState->adsr.fadeOutVel = gAudioCtx.audioBufferParameters.ticksPerUpdateInv;
playbackState->adsr.action.s.release = true; playbackState->adsr.action.s.release = true;
} }
} }
@ -793,7 +791,7 @@ s32 AudioHeap_ResetStep(void) {
if (gAudioCtx.notes[i].noteSubEu.bitField0.enabled && if (gAudioCtx.notes[i].noteSubEu.bitField0.enabled &&
gAudioCtx.notes[i].playbackState.adsr.action.s.state != ADSR_STATE_DISABLED) { gAudioCtx.notes[i].playbackState.adsr.action.s.state != ADSR_STATE_DISABLED) {
gAudioCtx.notes[i].playbackState.adsr.fadeOutVel = gAudioCtx.notes[i].playbackState.adsr.fadeOutVel =
gAudioCtx.audioBufferParameters.updatesPerFrameInv; gAudioCtx.audioBufferParameters.ticksPerUpdateInv;
gAudioCtx.notes[i].playbackState.adsr.action.s.release = true; gAudioCtx.notes[i].playbackState.adsr.action.s.release = true;
} }
} }
@ -853,7 +851,7 @@ void AudioHeap_Init(void) {
s32 i; s32 i;
s32 j; s32 j;
s32 pad2; s32 pad2;
AudioSpec* spec = &gAudioSpecs[gAudioCtx.audioResetSpecIdToLoad]; // Audio Specifications AudioSpec* spec = &gAudioSpecs[gAudioCtx.specId]; // Audio Specifications
gAudioCtx.sampleDmaCount = 0; gAudioCtx.sampleDmaCount = 0;
@ -865,17 +863,17 @@ void AudioHeap_Init(void) {
ALIGN16(gAudioCtx.audioBufferParameters.samplingFrequency / gAudioCtx.refreshRate); ALIGN16(gAudioCtx.audioBufferParameters.samplingFrequency / gAudioCtx.refreshRate);
gAudioCtx.audioBufferParameters.minAiBufferLength = gAudioCtx.audioBufferParameters.samplesPerFrameTarget - 0x10; gAudioCtx.audioBufferParameters.minAiBufferLength = gAudioCtx.audioBufferParameters.samplesPerFrameTarget - 0x10;
gAudioCtx.audioBufferParameters.maxAiBufferLength = gAudioCtx.audioBufferParameters.samplesPerFrameTarget + 0x10; gAudioCtx.audioBufferParameters.maxAiBufferLength = gAudioCtx.audioBufferParameters.samplesPerFrameTarget + 0x10;
gAudioCtx.audioBufferParameters.updatesPerFrame = gAudioCtx.audioBufferParameters.ticksPerUpdate =
((gAudioCtx.audioBufferParameters.samplesPerFrameTarget + 0x10) / 0xD0) + 1; ((gAudioCtx.audioBufferParameters.samplesPerFrameTarget + 0x10) / 0xD0) + 1;
gAudioCtx.audioBufferParameters.samplesPerUpdate = gAudioCtx.audioBufferParameters.samplesPerTick =
(gAudioCtx.audioBufferParameters.samplesPerFrameTarget / gAudioCtx.audioBufferParameters.updatesPerFrame) & ~7; (gAudioCtx.audioBufferParameters.samplesPerFrameTarget / gAudioCtx.audioBufferParameters.ticksPerUpdate) & ~7;
gAudioCtx.audioBufferParameters.samplesPerUpdateMax = gAudioCtx.audioBufferParameters.samplesPerUpdate + 8; gAudioCtx.audioBufferParameters.samplesPerTickMax = gAudioCtx.audioBufferParameters.samplesPerTick + 8;
gAudioCtx.audioBufferParameters.samplesPerUpdateMin = gAudioCtx.audioBufferParameters.samplesPerUpdate - 8; gAudioCtx.audioBufferParameters.samplesPerTickMin = gAudioCtx.audioBufferParameters.samplesPerTick - 8;
gAudioCtx.audioBufferParameters.resampleRate = 32000.0f / (s32)gAudioCtx.audioBufferParameters.samplingFrequency; gAudioCtx.audioBufferParameters.resampleRate = 32000.0f / (s32)gAudioCtx.audioBufferParameters.samplingFrequency;
gAudioCtx.audioBufferParameters.updatesPerFrameInvScaled = gAudioCtx.audioBufferParameters.ticksPerUpdateInvScaled =
(1.0f / 256.0f) / gAudioCtx.audioBufferParameters.updatesPerFrame; (1.0f / 256.0f) / gAudioCtx.audioBufferParameters.ticksPerUpdate;
gAudioCtx.audioBufferParameters.updatesPerFrameScaled = gAudioCtx.audioBufferParameters.updatesPerFrame / 4.0f; gAudioCtx.audioBufferParameters.ticksPerUpdateScaled = gAudioCtx.audioBufferParameters.ticksPerUpdate / 4.0f;
gAudioCtx.audioBufferParameters.updatesPerFrameInv = 1.0f / gAudioCtx.audioBufferParameters.updatesPerFrame; gAudioCtx.audioBufferParameters.ticksPerUpdateInv = 1.0f / gAudioCtx.audioBufferParameters.ticksPerUpdate;
// SampleDma buffer size // SampleDma buffer size
gAudioCtx.sampleDmaBufSize1 = spec->sampleDmaBufSize1; gAudioCtx.sampleDmaBufSize1 = spec->sampleDmaBufSize1;
@ -887,19 +885,22 @@ void AudioHeap_Init(void) {
gAudioCtx.audioBufferParameters.numSequencePlayers = 4; gAudioCtx.audioBufferParameters.numSequencePlayers = 4;
} }
gAudioCtx.unk_2 = spec->unk_14; gAudioCtx.unk_2 = spec->unk_14;
gAudioCtx.tempoInternalToExternal =
(u32)(gAudioCtx.audioBufferParameters.updatesPerFrame * 2880000.0f / gTatumsPerBeat / gAudioCtx.unk_2960); // (ticks / min)
// 60 * 1000 is a conversion from milliseconds to minutes
gAudioCtx.maxTempo = (u32)(gAudioCtx.audioBufferParameters.ticksPerUpdate * (f32)(60 * 1000 * SEQTICKS_PER_BEAT) /
gTempoData.seqTicksPerBeat / gAudioCtx.maxTempoTvTypeFactors);
gAudioCtx.unk_2870 = gAudioCtx.refreshRate; gAudioCtx.unk_2870 = gAudioCtx.refreshRate;
gAudioCtx.unk_2870 *= gAudioCtx.audioBufferParameters.updatesPerFrame; gAudioCtx.unk_2870 *= gAudioCtx.audioBufferParameters.ticksPerUpdate;
gAudioCtx.unk_2870 /= gAudioCtx.audioBufferParameters.aiSamplingFrequency; gAudioCtx.unk_2870 /= gAudioCtx.audioBufferParameters.aiSamplingFrequency;
gAudioCtx.unk_2870 /= gAudioCtx.tempoInternalToExternal; gAudioCtx.unk_2870 /= gAudioCtx.maxTempo;
gAudioCtx.audioBufferParameters.specUnk4 = spec->unk_04; gAudioCtx.audioBufferParameters.specUnk4 = spec->unk_04;
gAudioCtx.audioBufferParameters.samplesPerFrameTarget *= gAudioCtx.audioBufferParameters.specUnk4; gAudioCtx.audioBufferParameters.samplesPerFrameTarget *= gAudioCtx.audioBufferParameters.specUnk4;
gAudioCtx.audioBufferParameters.maxAiBufferLength *= gAudioCtx.audioBufferParameters.specUnk4; gAudioCtx.audioBufferParameters.maxAiBufferLength *= gAudioCtx.audioBufferParameters.specUnk4;
gAudioCtx.audioBufferParameters.minAiBufferLength *= gAudioCtx.audioBufferParameters.specUnk4; gAudioCtx.audioBufferParameters.minAiBufferLength *= gAudioCtx.audioBufferParameters.specUnk4;
gAudioCtx.audioBufferParameters.updatesPerFrame *= gAudioCtx.audioBufferParameters.specUnk4; gAudioCtx.audioBufferParameters.ticksPerUpdate *= gAudioCtx.audioBufferParameters.specUnk4;
if (gAudioCtx.audioBufferParameters.specUnk4 >= 2) { if (gAudioCtx.audioBufferParameters.specUnk4 >= 2) {
gAudioCtx.audioBufferParameters.maxAiBufferLength -= 0x10; gAudioCtx.audioBufferParameters.maxAiBufferLength -= 0x10;
@ -907,7 +908,7 @@ void AudioHeap_Init(void) {
// Determine the length of the buffer for storing the audio command list passed to the rsp audio microcode // Determine the length of the buffer for storing the audio command list passed to the rsp audio microcode
gAudioCtx.maxAudioCmds = gAudioCtx.maxAudioCmds =
gAudioCtx.numNotes * 0x10 * gAudioCtx.audioBufferParameters.updatesPerFrame + spec->numReverbs * 0x18 + 0x140; gAudioCtx.numNotes * 0x10 * gAudioCtx.audioBufferParameters.ticksPerUpdate + spec->numReverbs * 0x18 + 0x140;
// Calculate sizes for various caches on the audio heap // Calculate sizes for various caches on the audio heap
persistentSize = persistentSize =
@ -949,7 +950,7 @@ void AudioHeap_Init(void) {
gAudioCtx.notes = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, gAudioCtx.numNotes * sizeof(Note)); gAudioCtx.notes = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, gAudioCtx.numNotes * sizeof(Note));
Audio_NoteInitAll(); Audio_NoteInitAll();
Audio_InitNoteFreeList(); Audio_InitNoteFreeList();
gAudioCtx.noteSubsEu = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, gAudioCtx.audioBufferParameters.updatesPerFrame * gAudioCtx.noteSubsEu = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, gAudioCtx.audioBufferParameters.ticksPerUpdate *
gAudioCtx.numNotes * sizeof(NoteSubEu)); gAudioCtx.numNotes * sizeof(NoteSubEu));
// Initialize audio binary interface command list buffers // Initialize audio binary interface command list buffers
for (i = 0; i != 2; i++) { for (i = 0; i != 2; i++) {
@ -1011,7 +1012,7 @@ void AudioHeap_Init(void) {
reverb->unk_34 = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, sizeof(RESAMPLE_STATE)); reverb->unk_34 = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, sizeof(RESAMPLE_STATE));
reverb->unk_38 = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, sizeof(RESAMPLE_STATE)); reverb->unk_38 = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, sizeof(RESAMPLE_STATE));
reverb->unk_3C = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, sizeof(RESAMPLE_STATE)); reverb->unk_3C = AudioHeap_AllocZeroed(&gAudioCtx.miscPool, sizeof(RESAMPLE_STATE));
for (j = 0; j < gAudioCtx.audioBufferParameters.updatesPerFrame; j++) { for (j = 0; j < gAudioCtx.audioBufferParameters.ticksPerUpdate; j++) {
ramAddr = AudioHeap_AllocZeroedAttemptExternal(&gAudioCtx.miscPool, DMEM_2CH_SIZE); ramAddr = AudioHeap_AllocZeroedAttemptExternal(&gAudioCtx.miscPool, DMEM_2CH_SIZE);
reverb->items[0][j].toDownsampleLeft = ramAddr; reverb->items[0][j].toDownsampleLeft = ramAddr;
reverb->items[0][j].toDownsampleRight = ramAddr + DMEM_1CH_SIZE / SAMPLE_SIZE; reverb->items[0][j].toDownsampleRight = ramAddr + DMEM_1CH_SIZE / SAMPLE_SIZE;

View file

@ -1126,7 +1126,7 @@ void AudioLoad_Init(void* heap, u32 heapSize) {
void* ramAddr; void* ramAddr;
s32 i; s32 i;
D_801755D0 = NULL; gAudioCustomUpdateFunction = NULL;
gAudioCtx.resetTimer = 0; gAudioCtx.resetTimer = 0;
{ {
@ -1138,25 +1138,26 @@ void AudioLoad_Init(void* heap, u32 heapSize) {
} }
} }
// 1000 is a conversion from seconds to milliseconds
switch (osTvType) { switch (osTvType) {
case OS_TV_PAL: case OS_TV_PAL:
gAudioCtx.unk_2960 = 20.03042f; gAudioCtx.maxTempoTvTypeFactors = 1000 * REFRESH_RATE_DEVIATION_PAL / REFRESH_RATE_PAL;
gAudioCtx.refreshRate = 50; gAudioCtx.refreshRate = REFRESH_RATE_PAL;
break; break;
case OS_TV_MPAL: case OS_TV_MPAL:
gAudioCtx.unk_2960 = 16.546f; gAudioCtx.maxTempoTvTypeFactors = 1000 * REFRESH_RATE_DEVIATION_MPAL / REFRESH_RATE_MPAL;
gAudioCtx.refreshRate = 60; gAudioCtx.refreshRate = REFRESH_RATE_MPAL;
break; break;
case OS_TV_NTSC: case OS_TV_NTSC:
default: default:
gAudioCtx.unk_2960 = 16.713f; gAudioCtx.maxTempoTvTypeFactors = 1000 * REFRESH_RATE_DEVIATION_NTSC / REFRESH_RATE_NTSC;
gAudioCtx.refreshRate = 60; gAudioCtx.refreshRate = REFRESH_RATE_NTSC;
break; break;
} }
Audio_InitMesgQueues(); AudioThread_InitMesgQueues();
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
gAudioCtx.aiBufLengths[i] = 0xA0; gAudioCtx.aiBufLengths[i] = 0xA0;
@ -1209,7 +1210,7 @@ void AudioLoad_Init(void* heap, u32 heapSize) {
gAudioCtx.numSequences = gAudioCtx.sequenceTable->numEntries; gAudioCtx.numSequences = gAudioCtx.sequenceTable->numEntries;
gAudioCtx.audioResetSpecIdToLoad = 0; gAudioCtx.specId = 0;
gAudioCtx.resetStatus = 1; // Set reset to immediately initialize the audio heap gAudioCtx.resetStatus = 1; // Set reset to immediately initialize the audio heap
AudioHeap_ResetStep(); AudioHeap_ResetStep();

View file

@ -100,8 +100,8 @@ void Audio_InitNoteSub(Note* note, NoteSubEu* sub, NoteSubAttributes* attrs) {
sub->gain = attrs->gain; sub->gain = attrs->gain;
sub->filter = attrs->filter; sub->filter = attrs->filter;
sub->unk_07 = attrs->unk_14; sub->combFilterSize = attrs->combFilterSize;
sub->unk_0E = attrs->unk_16; sub->combFilterGain = attrs->combFilterGain;
sub->reverbVol = reverbVol; sub->reverbVol = reverbVol;
} }
@ -174,7 +174,7 @@ void Audio_ProcessNotes(void) {
if (note != playbackState->parentLayer->note && playbackState->unk_04 == 0) { if (note != playbackState->parentLayer->note && playbackState->unk_04 == 0) {
playbackState->adsr.action.s.release = true; playbackState->adsr.action.s.release = true;
playbackState->adsr.fadeOutVel = gAudioCtx.audioBufferParameters.updatesPerFrameInv; playbackState->adsr.fadeOutVel = gAudioCtx.audioBufferParameters.ticksPerUpdateInv;
playbackState->priority = 1; playbackState->priority = 1;
playbackState->unk_04 = 2; playbackState->unk_04 = 2;
goto out; goto out;
@ -256,8 +256,8 @@ void Audio_ProcessNotes(void) {
subAttrs.stereo = attrs->stereo; subAttrs.stereo = attrs->stereo;
subAttrs.gain = attrs->gain; subAttrs.gain = attrs->gain;
subAttrs.filter = attrs->filter; subAttrs.filter = attrs->filter;
subAttrs.unk_14 = attrs->unk_4; subAttrs.combFilterSize = attrs->combFilterSize;
subAttrs.unk_16 = attrs->unk_6; subAttrs.combFilterGain = attrs->combFilterGain;
bookOffset = noteSubEu->bitField1.bookOffset; bookOffset = noteSubEu->bitField1.bookOffset;
} else { } else {
SequenceLayer* layer = playbackState->parentLayer; SequenceLayer* layer = playbackState->parentLayer;
@ -271,11 +271,11 @@ void Audio_ProcessNotes(void) {
} else { } else {
subAttrs.stereo = layer->stereo; subAttrs.stereo = layer->stereo;
} }
subAttrs.reverbVol = channel->reverb; subAttrs.reverbVol = channel->targetReverbVol;
subAttrs.gain = channel->gain; subAttrs.gain = channel->gain;
subAttrs.filter = channel->filter; subAttrs.filter = channel->filter;
subAttrs.unk_14 = channel->unk_0F; subAttrs.combFilterSize = channel->combFilterSize;
subAttrs.unk_16 = channel->unk_20; subAttrs.combFilterGain = channel->combFilterGain;
bookOffset = channel->bookOffset & 0x7; bookOffset = channel->bookOffset & 0x7;
if (channel->seqPlayer->muted && (channel->muteBehavior & MUTE_BEHAVIOR_3)) { if (channel->seqPlayer->muted && (channel->muteBehavior & MUTE_BEHAVIOR_3)) {
@ -433,7 +433,7 @@ s32 Audio_SetFontInstrument(s32 instrumentType, s32 fontId, s32 index, void* val
void Audio_SeqLayerDecayRelease(SequenceLayer* layer, s32 target) { void Audio_SeqLayerDecayRelease(SequenceLayer* layer, s32 target) {
Note* note; Note* note;
NoteAttributes* attrs; NoteAttributes* attrs;
SequenceChannel* chan; SequenceChannel* channel;
s32 i; s32 i;
if (layer == NO_LAYER) { if (layer == NO_LAYER) {
@ -456,7 +456,7 @@ void Audio_SeqLayerDecayRelease(SequenceLayer* layer, s32 target) {
if (note->playbackState.parentLayer != layer) { if (note->playbackState.parentLayer != layer) {
if (note->playbackState.parentLayer == NO_LAYER && note->playbackState.wantedParentLayer == NO_LAYER && if (note->playbackState.parentLayer == NO_LAYER && note->playbackState.wantedParentLayer == NO_LAYER &&
note->playbackState.prevParentLayer == layer && target != ADSR_STATE_DECAY) { note->playbackState.prevParentLayer == layer && target != ADSR_STATE_DECAY) {
note->playbackState.adsr.fadeOutVel = gAudioCtx.audioBufferParameters.updatesPerFrameInv; note->playbackState.adsr.fadeOutVel = gAudioCtx.audioBufferParameters.ticksPerUpdateInv;
note->playbackState.adsr.action.s.release = true; note->playbackState.adsr.action.s.release = true;
} }
return; return;
@ -468,10 +468,10 @@ void Audio_SeqLayerDecayRelease(SequenceLayer* layer, s32 target) {
attrs->pan = layer->notePan; attrs->pan = layer->notePan;
if (layer->channel != NULL) { if (layer->channel != NULL) {
chan = layer->channel; channel = layer->channel;
attrs->reverb = chan->reverb; attrs->reverb = channel->targetReverbVol;
attrs->gain = chan->gain; attrs->gain = channel->gain;
attrs->filter = chan->filter; attrs->filter = channel->filter;
if (attrs->filter != NULL) { if (attrs->filter != NULL) {
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
@ -480,18 +480,18 @@ void Audio_SeqLayerDecayRelease(SequenceLayer* layer, s32 target) {
attrs->filter = attrs->filterBuf; attrs->filter = attrs->filterBuf;
} }
attrs->unk_6 = chan->unk_20; attrs->combFilterGain = channel->combFilterGain;
attrs->unk_4 = chan->unk_0F; attrs->combFilterSize = channel->combFilterSize;
if (chan->seqPlayer->muted && (chan->muteBehavior & MUTE_BEHAVIOR_3)) { if (channel->seqPlayer->muted && (channel->muteBehavior & MUTE_BEHAVIOR_3)) {
note->noteSubEu.bitField0.finished = true; note->noteSubEu.bitField0.finished = true;
} }
if (layer->stereo.asByte == 0) { if (layer->stereo.asByte == 0) {
attrs->stereo = chan->stereo; attrs->stereo = channel->stereo;
} else { } else {
attrs->stereo = layer->stereo; attrs->stereo = layer->stereo;
} }
note->playbackState.priority = chan->someOtherPriority; note->playbackState.priority = channel->someOtherPriority;
} else { } else {
attrs->stereo = layer->stereo; attrs->stereo = layer->stereo;
note->playbackState.priority = 1; note->playbackState.priority = 1;
@ -500,7 +500,7 @@ void Audio_SeqLayerDecayRelease(SequenceLayer* layer, s32 target) {
note->playbackState.prevParentLayer = note->playbackState.parentLayer; note->playbackState.prevParentLayer = note->playbackState.parentLayer;
note->playbackState.parentLayer = NO_LAYER; note->playbackState.parentLayer = NO_LAYER;
if (target == ADSR_STATE_RELEASE) { if (target == ADSR_STATE_RELEASE) {
note->playbackState.adsr.fadeOutVel = gAudioCtx.audioBufferParameters.updatesPerFrameInv; note->playbackState.adsr.fadeOutVel = gAudioCtx.audioBufferParameters.ticksPerUpdateInv;
note->playbackState.adsr.action.s.release = true; note->playbackState.adsr.action.s.release = true;
note->playbackState.unk_04 = 2; note->playbackState.unk_04 = 2;
} else { } else {
@ -805,7 +805,7 @@ void Audio_NoteReleaseAndTakeOwnership(Note* note, SequenceLayer* layer) {
note->playbackState.wantedParentLayer = layer; note->playbackState.wantedParentLayer = layer;
note->playbackState.priority = layer->channel->notePriority; note->playbackState.priority = layer->channel->notePriority;
note->playbackState.adsr.fadeOutVel = gAudioCtx.audioBufferParameters.updatesPerFrameInv; note->playbackState.adsr.fadeOutVel = gAudioCtx.audioBufferParameters.ticksPerUpdateInv;
note->playbackState.adsr.action.s.release = true; note->playbackState.adsr.action.s.release = true;
} }

View file

@ -259,7 +259,7 @@ void AudioSeq_InitSequenceChannel(SequenceChannel* channel) {
channel->enabled = false; channel->enabled = false;
channel->finished = false; channel->finished = false;
channel->stopScript = false; channel->stopScript = false;
channel->stopSomething2 = false; channel->muted = false;
channel->hasInstrument = false; channel->hasInstrument = false;
channel->stereoHeadsetEffects = false; channel->stereoHeadsetEffects = false;
channel->transposition = 0; channel->transposition = 0;
@ -274,7 +274,7 @@ void AudioSeq_InitSequenceChannel(SequenceChannel* channel) {
channel->gateTimeRandomVariance = 0; channel->gateTimeRandomVariance = 0;
channel->noteUnused = NULL; channel->noteUnused = NULL;
channel->reverbIndex = 0; channel->reverbIndex = 0;
channel->reverb = 0; channel->targetReverbVol = 0;
channel->gain = 0; channel->gain = 0;
channel->notePriority = 3; channel->notePriority = 3;
channel->someOtherPriority = 1; channel->someOtherPriority = 1;
@ -284,20 +284,20 @@ void AudioSeq_InitSequenceChannel(SequenceChannel* channel) {
channel->adsr.sustain = 0; channel->adsr.sustain = 0;
channel->vibratoRateTarget = 0x800; channel->vibratoRateTarget = 0x800;
channel->vibratoRateStart = 0x800; channel->vibratoRateStart = 0x800;
channel->vibratoExtentTarget = 0; channel->vibratoDepthTarget = 0;
channel->vibratoExtentStart = 0; channel->vibratoDepthStart = 0;
channel->vibratoRateChangeDelay = 0; channel->vibratoRateChangeDelay = 0;
channel->vibratoExtentChangeDelay = 0; channel->vibratoDepthChangeDelay = 0;
channel->vibratoDelay = 0; channel->vibratoDelay = 0;
channel->filter = NULL; channel->filter = NULL;
channel->unk_20 = 0; channel->combFilterGain = 0;
channel->unk_0F = 0; channel->combFilterSize = 0;
channel->volume = 1.0f; channel->volume = 1.0f;
channel->volumeScale = 1.0f; channel->volumeScale = 1.0f;
channel->freqScale = 1.0f; channel->freqScale = 1.0f;
for (i = 0; i < ARRAY_COUNT(channel->soundScriptIO); i++) { for (i = 0; i < ARRAY_COUNT(channel->seqScriptIO); i++) {
channel->soundScriptIO[i] = SEQ_IO_VAL_NONE; channel->seqScriptIO[i] = SEQ_IO_VAL_NONE;
} }
channel->unused = false; channel->unused = false;
@ -326,7 +326,7 @@ s32 AudioSeq_SeqChannelSetLayer(SequenceChannel* channel, s32 layerIndex) {
layer->adsr.decayIndex = 0; layer->adsr.decayIndex = 0;
layer->enabled = true; layer->enabled = true;
layer->finished = false; layer->finished = false;
layer->stopSomething = false; layer->muted = false;
layer->continuousNotes = false; layer->continuousNotes = false;
layer->bit3 = false; layer->bit3 = false;
layer->ignoreDrumPan = false; layer->ignoreDrumPan = false;
@ -530,9 +530,9 @@ void AudioSeq_SeqLayerProcessScript(SequenceLayer* layer) {
if (layer->delay > 1) { if (layer->delay > 1) {
layer->delay--; layer->delay--;
if (!layer->stopSomething && layer->delay <= layer->gateDelay) { if (!layer->muted && (layer->delay <= layer->gateDelay)) {
Audio_SeqLayerNoteDecay(layer); Audio_SeqLayerNoteDecay(layer);
layer->stopSomething = true; layer->muted = true;
} }
return; return;
} }
@ -555,7 +555,7 @@ void AudioSeq_SeqLayerProcessScript(SequenceLayer* layer) {
AudioSeq_SeqLayerProcessScriptStep5(layer, cmd); AudioSeq_SeqLayerProcessScriptStep5(layer, cmd);
} }
if (layer->stopSomething == true) { if (layer->muted == true) {
if ((layer->note != NULL) || layer->continuousNotes) { if ((layer->note != NULL) || layer->continuousNotes) {
Audio_SeqLayerNoteDecay(layer); Audio_SeqLayerNoteDecay(layer);
} }
@ -579,9 +579,9 @@ void AudioSeq_SeqLayerProcessScriptStep1(SequenceLayer* layer) {
s32 AudioSeq_SeqLayerProcessScriptStep5(SequenceLayer* layer, s32 sameTunedSample) { s32 AudioSeq_SeqLayerProcessScriptStep5(SequenceLayer* layer, s32 sameTunedSample) {
Note* note; Note* note;
if (!layer->stopSomething && layer->tunedSample != NULL && if (!layer->muted && (layer->tunedSample != NULL) && (layer->tunedSample->sample->codec == CODEC_S16_INMEMORY) &&
layer->tunedSample->sample->codec == CODEC_S16_INMEMORY && layer->tunedSample->sample->medium != MEDIUM_RAM) { (layer->tunedSample->sample->medium != MEDIUM_RAM)) {
layer->stopSomething = true; layer->muted = true;
return PROCESS_SCRIPT_END; return PROCESS_SCRIPT_END;
} }
@ -812,7 +812,7 @@ s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd) {
drum = Audio_GetDrum(channel->fontId, semitone); drum = Audio_GetDrum(channel->fontId, semitone);
if (drum == NULL) { if (drum == NULL) {
layer->stopSomething = true; layer->muted = true;
layer->delay2 = layer->delay; layer->delay2 = layer->delay;
return PROCESS_SCRIPT_END; return PROCESS_SCRIPT_END;
} }
@ -834,7 +834,7 @@ s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd) {
soundEffect = Audio_GetSoundEffect(channel->fontId, sfxId); soundEffect = Audio_GetSoundEffect(channel->fontId, sfxId);
if (soundEffect == NULL) { if (soundEffect == NULL) {
layer->stopSomething = true; layer->muted = true;
layer->delay2 = layer->delay + 1; layer->delay2 = layer->delay + 1;
return PROCESS_SCRIPT_END; return PROCESS_SCRIPT_END;
} }
@ -850,7 +850,7 @@ s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd) {
layer->semitone = semitone; layer->semitone = semitone;
if (semitone >= 0x80) { if (semitone >= 0x80) {
layer->stopSomething = true; layer->muted = true;
return PROCESS_SCRIPT_END; return PROCESS_SCRIPT_END;
} }
@ -903,12 +903,12 @@ s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd) {
portamento->extent = (freqScale2 / freqScale) - 1.0f; portamento->extent = (freqScale2 / freqScale) - 1.0f;
if (PORTAMENTO_IS_SPECIAL(*portamento)) { if (PORTAMENTO_IS_SPECIAL(*portamento)) {
speed = seqPlayer->tempo * 0x8000 / gAudioCtx.tempoInternalToExternal; speed = seqPlayer->tempo * 0x8000 / gAudioCtx.maxTempo;
if (layer->delay != 0) { if (layer->delay != 0) {
speed = speed * 0x100 / (layer->delay * layer->portamentoTime); speed = speed * 0x100 / (layer->delay * layer->portamentoTime);
} }
} else { } else {
speed = 0x20000 / (layer->portamentoTime * gAudioCtx.audioBufferParameters.updatesPerFrame); speed = 0x20000 / (layer->portamentoTime * gAudioCtx.audioBufferParameters.ticksPerUpdate);
} }
if (speed >= 0x7FFF) { if (speed >= 0x7FFF) {
@ -964,7 +964,7 @@ s32 AudioSeq_SeqLayerProcessScriptStep4(SequenceLayer* layer, s32 cmd) {
// (It's a bit unclear if 'portamento' has actually always been // (It's a bit unclear if 'portamento' has actually always been
// set when this is reached...) // set when this is reached...)
if (PORTAMENTO_IS_SPECIAL(*portamento)) { if (PORTAMENTO_IS_SPECIAL(*portamento)) {
speed2 = seqPlayer->tempo * 0x8000 / gAudioCtx.tempoInternalToExternal; speed2 = seqPlayer->tempo * 0x8000 / gAudioCtx.maxTempo;
speed2 = speed2 * 0x100 / (layer->delay * layer->portamentoTime); speed2 = speed2 * 0x100 / (layer->delay * layer->portamentoTime);
if (speed2 >= 0x7FFF) { if (speed2 >= 0x7FFF) {
speed2 = 0x7FFF; speed2 = 0x7FFF;
@ -989,12 +989,12 @@ s32 AudioSeq_SeqLayerProcessScriptStep3(SequenceLayer* layer, s32 cmd) {
if (cmd == 0xC0) { if (cmd == 0xC0) {
layer->delay = AudioSeq_ScriptReadCompressedU16(state); layer->delay = AudioSeq_ScriptReadCompressedU16(state);
layer->stopSomething = true; layer->muted = true;
layer->bit1 = false; layer->bit1 = false;
return PROCESS_SCRIPT_END; return PROCESS_SCRIPT_END;
} }
layer->stopSomething = false; layer->muted = false;
if (channel->largeNotes == true) { if (channel->largeNotes == true) {
switch (cmd & 0xC0) { switch (cmd & 0xC0) {
@ -1078,13 +1078,13 @@ s32 AudioSeq_SeqLayerProcessScriptStep3(SequenceLayer* layer, s32 cmd) {
} }
if ((seqPlayer->muted && (channel->muteBehavior & (MUTE_BEHAVIOR_STOP_NOTES | MUTE_BEHAVIOR_4))) || if ((seqPlayer->muted && (channel->muteBehavior & (MUTE_BEHAVIOR_STOP_NOTES | MUTE_BEHAVIOR_4))) ||
channel->stopSomething2) { channel->muted) {
layer->stopSomething = true; layer->muted = true;
return PROCESS_SCRIPT_END; return PROCESS_SCRIPT_END;
} }
if (seqPlayer->skipTicks != 0) { if (seqPlayer->skipTicks != 0) {
layer->stopSomething = true; layer->muted = true;
return PROCESS_SCRIPT_END; return PROCESS_SCRIPT_END;
} }
@ -1329,9 +1329,9 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
case 0xD8: case 0xD8:
cmd = (u8)cmdArgs[0]; cmd = (u8)cmdArgs[0];
channel->vibratoExtentTarget = cmd * 8; channel->vibratoDepthTarget = cmd * 8;
channel->vibratoExtentStart = 0; channel->vibratoDepthStart = 0;
channel->vibratoExtentChangeDelay = 0; channel->vibratoDepthChangeDelay = 0;
break; break;
case 0xD7: case 0xD7:
@ -1343,11 +1343,11 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
case 0xE2: case 0xE2:
cmd = (u8)cmdArgs[0]; cmd = (u8)cmdArgs[0];
channel->vibratoExtentStart = cmd * 8; channel->vibratoDepthStart = cmd * 8;
cmd = (u8)cmdArgs[1]; cmd = (u8)cmdArgs[1];
channel->vibratoExtentTarget = cmd * 8; channel->vibratoDepthTarget = cmd * 8;
cmd = (u8)cmdArgs[2]; cmd = (u8)cmdArgs[2];
channel->vibratoExtentChangeDelay = cmd * 16; channel->vibratoDepthChangeDelay = cmd * 16;
break; break;
case 0xE1: case 0xE1:
@ -1366,7 +1366,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
case 0xD4: case 0xD4:
cmd = (u8)cmdArgs[0]; cmd = (u8)cmdArgs[0];
channel->reverb = cmd; channel->targetReverbVol = cmd;
break; break;
case 0xC6: case 0xC6:
@ -1483,7 +1483,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
data += 4; data += 4;
channel->newPan = data[-3]; channel->newPan = data[-3];
channel->panChannelWeight = data[-2]; channel->panChannelWeight = data[-2];
channel->reverb = data[-1]; channel->targetReverbVol = data[-1];
channel->reverbIndex = data[0]; channel->reverbIndex = data[0];
//! @bug: Not marking reverb state as changed //! @bug: Not marking reverb state as changed
channel->changes.s.pan = true; channel->changes.s.pan = true;
@ -1497,16 +1497,16 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
channel->transposition = (s8)AudioSeq_ScriptReadU8(scriptState); channel->transposition = (s8)AudioSeq_ScriptReadU8(scriptState);
channel->newPan = AudioSeq_ScriptReadU8(scriptState); channel->newPan = AudioSeq_ScriptReadU8(scriptState);
channel->panChannelWeight = AudioSeq_ScriptReadU8(scriptState); channel->panChannelWeight = AudioSeq_ScriptReadU8(scriptState);
channel->reverb = AudioSeq_ScriptReadU8(scriptState); channel->targetReverbVol = AudioSeq_ScriptReadU8(scriptState);
channel->reverbIndex = AudioSeq_ScriptReadU8(scriptState); channel->reverbIndex = AudioSeq_ScriptReadU8(scriptState);
//! @bug: Not marking reverb state as changed //! @bug: Not marking reverb state as changed
channel->changes.s.pan = true; channel->changes.s.pan = true;
break; break;
case 0xEC: case 0xEC:
channel->vibratoExtentTarget = 0; channel->vibratoDepthTarget = 0;
channel->vibratoExtentStart = 0; channel->vibratoDepthStart = 0;
channel->vibratoExtentChangeDelay = 0; channel->vibratoDepthChangeDelay = 0;
channel->vibratoRateTarget = 0; channel->vibratoRateTarget = 0;
channel->vibratoRateStart = 0; channel->vibratoRateStart = 0;
channel->vibratoRateChangeDelay = 0; channel->vibratoRateChangeDelay = 0;
@ -1515,8 +1515,8 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
channel->adsr.sustain = 0; channel->adsr.sustain = 0;
channel->velocityRandomVariance = 0; channel->velocityRandomVariance = 0;
channel->gateTimeRandomVariance = 0; channel->gateTimeRandomVariance = 0;
channel->unk_0F = 0; channel->combFilterSize = 0;
channel->unk_20 = 0; channel->combFilterGain = 0;
channel->bookOffset = 0; channel->bookOffset = 0;
channel->freqScale = 1.0f; channel->freqScale = 1.0f;
break; break;
@ -1578,7 +1578,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
break; break;
case 0xBD: case 0xBD:
temp2 = Audio_NextRandom(); temp2 = AudioThread_NextRandom();
channel->unk_22 = (cmdArgs[0] == 0) ? (temp2 & 0xFFFF) : (temp2 % cmdArgs[0]); channel->unk_22 = (cmdArgs[0] == 0) ? (temp2 & 0xFFFF) : (temp2 % cmdArgs[0]);
channel->unk_22 += cmdArgs[1]; channel->unk_22 += cmdArgs[1];
temp2 = (channel->unk_22 / 0x100) + 0x80; temp2 = (channel->unk_22 / 0x100) + 0x80;
@ -1595,8 +1595,8 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
break; break;
case 0xBB: case 0xBB:
channel->unk_0F = cmdArgs[0]; channel->combFilterSize = cmdArgs[0];
channel->unk_20 = cmdArgs[1]; channel->combFilterGain = cmdArgs[1];
break; break;
case 0xBC: case 0xBC:
@ -1642,7 +1642,7 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
break; break;
case 0x70: case 0x70:
channel->soundScriptIO[lowBits] = scriptState->value; channel->seqScriptIO[lowBits] = scriptState->value;
break; break;
case 0x78: case 0x78:
@ -1664,26 +1664,26 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
case 0x10: case 0x10:
if (lowBits < 8) { if (lowBits < 8) {
channel->soundScriptIO[lowBits] = SEQ_IO_VAL_NONE; channel->seqScriptIO[lowBits] = SEQ_IO_VAL_NONE;
if (AudioLoad_SlowLoadSample(channel->fontId, scriptState->value, if (AudioLoad_SlowLoadSample(channel->fontId, scriptState->value, &channel->seqScriptIO[lowBits]) ==
&channel->soundScriptIO[lowBits]) == -1) {} -1) {}
} else { } else {
lowBits -= 8; lowBits -= 8;
channel->soundScriptIO[lowBits] = SEQ_IO_VAL_NONE; channel->seqScriptIO[lowBits] = SEQ_IO_VAL_NONE;
if (AudioLoad_SlowLoadSample(channel->fontId, channel->unk_22 + 0x100, if (AudioLoad_SlowLoadSample(channel->fontId, channel->unk_22 + 0x100,
&channel->soundScriptIO[lowBits]) == -1) {} &channel->seqScriptIO[lowBits]) == -1) {}
} }
break; break;
case 0x60: case 0x60:
scriptState->value = channel->soundScriptIO[lowBits]; scriptState->value = channel->seqScriptIO[lowBits];
if (lowBits < 2) { if (lowBits < 2) {
channel->soundScriptIO[lowBits] = SEQ_IO_VAL_NONE; channel->seqScriptIO[lowBits] = SEQ_IO_VAL_NONE;
} }
break; break;
case 0x50: case 0x50:
scriptState->value -= channel->soundScriptIO[lowBits]; scriptState->value -= channel->seqScriptIO[lowBits];
break; break;
case 0x20: case 0x20:
@ -1693,12 +1693,12 @@ void AudioSeq_SequenceChannelProcessScript(SequenceChannel* channel) {
case 0x30: case 0x30:
cmd = AudioSeq_ScriptReadU8(scriptState); cmd = AudioSeq_ScriptReadU8(scriptState);
seqPlayer->channels[lowBits]->soundScriptIO[cmd] = scriptState->value; seqPlayer->channels[lowBits]->seqScriptIO[cmd] = scriptState->value;
break; break;
case 0x40: case 0x40:
cmd = AudioSeq_ScriptReadU8(scriptState); cmd = AudioSeq_ScriptReadU8(scriptState);
scriptState->value = seqPlayer->channels[lowBits]->soundScriptIO[cmd]; scriptState->value = seqPlayer->channels[lowBits]->seqScriptIO[cmd];
break; break;
} }
} }
@ -1743,14 +1743,18 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) {
} }
seqPlayer->scriptCounter++; seqPlayer->scriptCounter++;
seqPlayer->tempoAcc += seqPlayer->tempo;
seqPlayer->tempoAcc += (s16)seqPlayer->unk_0C;
if (seqPlayer->tempoAcc < gAudioCtx.tempoInternalToExternal) { // Apply the tempo by controlling the number of updates run on the .seq script.
// Processing the .seq script every possible update will result in a tempo = maxTempo
// Processing the .seq script a fraction of the updates will result in a `tempo = fraction * maxTempo`
// where `fraction = (tempo + tempoChange) / maxTempo`
// This algorithm uses `tempoAcc` to discretize `(tempo + tempoChange) / maxTempo`
seqPlayer->tempoAcc += seqPlayer->tempo;
seqPlayer->tempoAcc += (s16)seqPlayer->tempoChange;
if (seqPlayer->tempoAcc < gAudioCtx.maxTempo) {
return; return;
} }
seqPlayer->tempoAcc -= (u16)gAudioCtx.maxTempo;
seqPlayer->tempoAcc -= (u16)gAudioCtx.tempoInternalToExternal;
if (seqPlayer->stopScript == true) { if (seqPlayer->stopScript == true) {
return; return;
@ -1810,9 +1814,9 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) {
break; break;
case 0xDD: case 0xDD:
seqPlayer->tempo = AudioSeq_ScriptReadU8(seqScript) * TATUMS_PER_BEAT; seqPlayer->tempo = AudioSeq_ScriptReadU8(seqScript) * SEQTICKS_PER_BEAT;
if (seqPlayer->tempo > gAudioCtx.tempoInternalToExternal) { if (seqPlayer->tempo > gAudioCtx.maxTempo) {
seqPlayer->tempo = (u16)gAudioCtx.tempoInternalToExternal; seqPlayer->tempo = (u16)gAudioCtx.maxTempo;
} }
if ((s16)seqPlayer->tempo <= 0) { if ((s16)seqPlayer->tempo <= 0) {
@ -1821,7 +1825,7 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) {
break; break;
case 0xDC: case 0xDC:
seqPlayer->unk_0C = (s8)AudioSeq_ScriptReadU8(seqScript) * TATUMS_PER_BEAT; seqPlayer->tempoChange = (s8)AudioSeq_ScriptReadU8(seqScript) * SEQTICKS_PER_BEAT;
break; break;
case 0xDA: case 0xDA:
@ -1982,17 +1986,17 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) {
break; break;
case 0x50: case 0x50:
seqScript->value -= seqPlayer->soundScriptIO[cmdLowBits]; seqScript->value -= seqPlayer->seqScriptIO[cmdLowBits];
break; break;
case 0x70: case 0x70:
seqPlayer->soundScriptIO[cmdLowBits] = seqScript->value; seqPlayer->seqScriptIO[cmdLowBits] = seqScript->value;
break; break;
case 0x80: case 0x80:
seqScript->value = seqPlayer->soundScriptIO[cmdLowBits]; seqScript->value = seqPlayer->seqScriptIO[cmdLowBits];
if (cmdLowBits < 2) { if (cmdLowBits < 2) {
seqPlayer->soundScriptIO[cmdLowBits] = SEQ_IO_VAL_NONE; seqPlayer->seqScriptIO[cmdLowBits] = SEQ_IO_VAL_NONE;
} }
break; break;
@ -2014,14 +2018,14 @@ void AudioSeq_SequencePlayerProcessSequence(SequencePlayer* seqPlayer) {
cmd = AudioSeq_ScriptReadU8(seqScript); cmd = AudioSeq_ScriptReadU8(seqScript);
temp = AudioSeq_ScriptReadS16(seqScript); temp = AudioSeq_ScriptReadS16(seqScript);
data2 = &seqPlayer->seqData[temp]; data2 = &seqPlayer->seqData[temp];
AudioLoad_SlowLoadSeq(cmd, data2, &seqPlayer->soundScriptIO[cmdLowBits]); AudioLoad_SlowLoadSeq(cmd, data2, &seqPlayer->seqScriptIO[cmdLowBits]);
break; break;
case 0x60: case 0x60:
cmd = AudioSeq_ScriptReadU8(seqScript); cmd = AudioSeq_ScriptReadU8(seqScript);
value = cmd; value = cmd;
temp = AudioSeq_ScriptReadU8(seqScript); temp = AudioSeq_ScriptReadU8(seqScript);
AudioLoad_ScriptLoad(value, temp, &seqPlayer->soundScriptIO[cmdLowBits]); AudioLoad_ScriptLoad(value, temp, &seqPlayer->seqScriptIO[cmdLowBits]);
break; break;
} }
} }
@ -2038,7 +2042,7 @@ void AudioSeq_ProcessSequences(s32 arg0) {
SequencePlayer* seqPlayer; SequencePlayer* seqPlayer;
u32 i; u32 i;
gAudioCtx.noteSubEuOffset = (gAudioCtx.audioBufferParameters.updatesPerFrame - arg0 - 1) * gAudioCtx.numNotes; gAudioCtx.noteSubEuOffset = (gAudioCtx.audioBufferParameters.ticksPerUpdate - arg0 - 1) * gAudioCtx.numNotes;
for (i = 0; i < (u32)gAudioCtx.audioBufferParameters.numSequencePlayers; i++) { for (i = 0; i < (u32)gAudioCtx.audioBufferParameters.numSequencePlayers; i++) {
seqPlayer = &gAudioCtx.seqPlayers[i]; seqPlayer = &gAudioCtx.seqPlayers[i];
@ -2069,8 +2073,8 @@ void AudioSeq_ResetSequencePlayer(SequencePlayer* seqPlayer) {
seqPlayer->fadeTimer = 0; seqPlayer->fadeTimer = 0;
seqPlayer->fadeTimerUnkEu = 0; seqPlayer->fadeTimerUnkEu = 0;
seqPlayer->tempoAcc = 0; seqPlayer->tempoAcc = 0;
seqPlayer->tempo = 120 * TATUMS_PER_BEAT; // 120 BPM seqPlayer->tempo = 120 * SEQTICKS_PER_BEAT; // 120 BPM
seqPlayer->unk_0C = 0; seqPlayer->tempoChange = 0;
seqPlayer->transposition = 0; seqPlayer->transposition = 0;
seqPlayer->noteAllocPolicy = 0; seqPlayer->noteAllocPolicy = 0;
seqPlayer->shortNoteVelocityTable = gDefaultShortNoteVelocityTable; seqPlayer->shortNoteVelocityTable = gDefaultShortNoteVelocityTable;
@ -2122,8 +2126,8 @@ void AudioSeq_InitSequencePlayer(SequencePlayer* seqPlayer) {
seqPlayer->seqDmaInProgress = false; seqPlayer->seqDmaInProgress = false;
seqPlayer->applyBend = false; seqPlayer->applyBend = false;
for (j = 0; j < ARRAY_COUNT(seqPlayer->soundScriptIO); j++) { for (j = 0; j < ARRAY_COUNT(seqPlayer->seqScriptIO); j++) {
seqPlayer->soundScriptIO[j] = SEQ_IO_VAL_NONE; seqPlayer->seqScriptIO[j] = SEQ_IO_VAL_NONE;
} }
seqPlayer->muteBehavior = MUTE_BEHAVIOR_SOFTEN | MUTE_BEHAVIOR_STOP_NOTES; seqPlayer->muteBehavior = MUTE_BEHAVIOR_SOFTEN | MUTE_BEHAVIOR_STOP_NOTES;

View file

@ -5,7 +5,7 @@
#define DMEM_TEMP 0x3C0 #define DMEM_TEMP 0x3C0
#define DMEM_UNCOMPRESSED_NOTE 0x580 #define DMEM_UNCOMPRESSED_NOTE 0x580
#define DMEM_HAAS_TEMP 0x5C0 #define DMEM_HAAS_TEMP 0x5C0
#define DMEM_SCRATCH2 0x760 // = DMEM_TEMP + DMEM_2CH_SIZE + a bit more #define DMEM_COMB_TEMP 0x760 // = DMEM_TEMP + DMEM_2CH_SIZE + a bit more
#define DMEM_COMPRESSED_ADPCM_DATA 0x940 // = DMEM_LEFT_CH #define DMEM_COMPRESSED_ADPCM_DATA 0x940 // = DMEM_LEFT_CH
#define DMEM_LEFT_CH 0x940 #define DMEM_LEFT_CH 0x940
#define DMEM_RIGHT_CH 0xAE0 #define DMEM_RIGHT_CH 0xAE0
@ -38,14 +38,14 @@ u32 sEnvMixerOp = _SHIFTL(A_ENVMIXER, 24, 8);
// Store the left dry channel in a temp space to be delayed to produce the haas effect // Store the left dry channel in a temp space to be delayed to produce the haas effect
u32 sEnvMixerLeftHaasDmemDests = u32 sEnvMixerLeftHaasDmemDests =
MK_CMD(DMEM_HAAS_TEMP >> 4, DMEM_RIGHT_CH >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4); AUDIO_MK_CMD(DMEM_HAAS_TEMP >> 4, DMEM_RIGHT_CH >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4);
// Store the right dry channel in a temp space to be delayed to produce the haas effect // Store the right dry channel in a temp space to be delayed to produce the haas effect
u32 sEnvMixerRightHaasDmemDests = u32 sEnvMixerRightHaasDmemDests =
MK_CMD(DMEM_LEFT_CH >> 4, DMEM_HAAS_TEMP >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4); AUDIO_MK_CMD(DMEM_LEFT_CH >> 4, DMEM_HAAS_TEMP >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4);
u32 sEnvMixerDefaultDmemDests = u32 sEnvMixerDefaultDmemDests =
MK_CMD(DMEM_LEFT_CH >> 4, DMEM_RIGHT_CH >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4); AUDIO_MK_CMD(DMEM_LEFT_CH >> 4, DMEM_RIGHT_CH >> 4, DMEM_WET_LEFT_CH >> 4, DMEM_WET_RIGHT_CH >> 4);
u16 D_801304B0[] = { u16 D_801304B0[] = {
0x7FFF, 0xD001, 0x3FFF, 0xF001, 0x5FFF, 0x9001, 0x7FFF, 0x8001, 0x7FFF, 0xD001, 0x3FFF, 0xF001, 0x5FFF, 0x9001, 0x7FFF, 0x8001,
@ -158,32 +158,32 @@ Acmd* AudioSynth_Update(Acmd* cmdStart, s32* cmdCnt, s16* aiStart, s32 aiBufLen)
SynthesisReverb* reverb; SynthesisReverb* reverb;
cmdP = cmdStart; cmdP = cmdStart;
for (i = gAudioCtx.audioBufferParameters.updatesPerFrame; i > 0; i--) { for (i = gAudioCtx.audioBufferParameters.ticksPerUpdate; i > 0; i--) {
AudioSeq_ProcessSequences(i - 1); AudioSeq_ProcessSequences(i - 1);
func_800DB03C(gAudioCtx.audioBufferParameters.updatesPerFrame - i); func_800DB03C(gAudioCtx.audioBufferParameters.ticksPerUpdate - i);
} }
aiBufP = aiStart; aiBufP = aiStart;
gAudioCtx.curLoadedBook = NULL; gAudioCtx.curLoadedBook = NULL;
for (i = gAudioCtx.audioBufferParameters.updatesPerFrame; i > 0; i--) { for (i = gAudioCtx.audioBufferParameters.ticksPerUpdate; i > 0; i--) {
if (i == 1) { if (i == 1) {
chunkLen = aiBufLen; chunkLen = aiBufLen;
} else if ((aiBufLen / i) >= gAudioCtx.audioBufferParameters.samplesPerUpdateMax) { } else if ((aiBufLen / i) >= gAudioCtx.audioBufferParameters.samplesPerTickMax) {
chunkLen = gAudioCtx.audioBufferParameters.samplesPerUpdateMax; chunkLen = gAudioCtx.audioBufferParameters.samplesPerTickMax;
} else if (gAudioCtx.audioBufferParameters.samplesPerUpdateMin >= (aiBufLen / i)) { } else if (gAudioCtx.audioBufferParameters.samplesPerTickMin >= (aiBufLen / i)) {
chunkLen = gAudioCtx.audioBufferParameters.samplesPerUpdateMin; chunkLen = gAudioCtx.audioBufferParameters.samplesPerTickMin;
} else { } else {
chunkLen = gAudioCtx.audioBufferParameters.samplesPerUpdate; chunkLen = gAudioCtx.audioBufferParameters.samplesPerTick;
} }
for (j = 0; j < gAudioCtx.numSynthesisReverbs; j++) { for (j = 0; j < gAudioCtx.numSynthesisReverbs; j++) {
if (gAudioCtx.synthesisReverbs[j].useReverb) { if (gAudioCtx.synthesisReverbs[j].useReverb) {
AudioSynth_InitNextRingBuf(chunkLen, gAudioCtx.audioBufferParameters.updatesPerFrame - i, j); AudioSynth_InitNextRingBuf(chunkLen, gAudioCtx.audioBufferParameters.ticksPerUpdate - i, j);
} }
} }
cmdP = AudioSynth_DoOneAudioUpdate(aiBufP, chunkLen, cmdP, gAudioCtx.audioBufferParameters.updatesPerFrame - i); cmdP = AudioSynth_DoOneAudioUpdate(aiBufP, chunkLen, cmdP, gAudioCtx.audioBufferParameters.ticksPerUpdate - i);
aiBufLen -= chunkLen; aiBufLen -= chunkLen;
aiBufP += 2 * chunkLen; aiBufP += 2 * chunkLen;
} }
@ -203,7 +203,7 @@ void func_800DB2C0(s32 updateIndex, s32 noteIndex) {
NoteSubEu* noteSubEu; NoteSubEu* noteSubEu;
s32 i; s32 i;
for (i = updateIndex + 1; i < gAudioCtx.audioBufferParameters.updatesPerFrame; i++) { for (i = updateIndex + 1; i < gAudioCtx.audioBufferParameters.ticksPerUpdate; i++) {
noteSubEu = &gAudioCtx.noteSubsEu[(gAudioCtx.numNotes * i) + noteIndex]; noteSubEu = &gAudioCtx.noteSubsEu[(gAudioCtx.numNotes * i) + noteIndex];
if (!noteSubEu->bitField0.needsInit) { if (!noteSubEu->bitField0.needsInit) {
noteSubEu->bitField0.enabled = false; noteSubEu->bitField0.enabled = false;
@ -717,7 +717,7 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS
s32 frameIndex; s32 frameIndex;
s32 skipBytes; s32 skipBytes;
s32 temp_v1_6; s32 temp_v1_6;
void* buf; s16* combFilterState;
s32 nSamplesToDecode; s32 nSamplesToDecode;
u32 sampleAddr; u32 sampleAddr;
u32 samplesLenFixedPoint; u32 samplesLenFixedPoint;
@ -740,12 +740,12 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS
s32 resampledTempLen; s32 resampledTempLen;
u16 sampleDmemBeforeResampling; u16 sampleDmemBeforeResampling;
s32 sampleDataOffset; s32 sampleDataOffset;
s32 thing; s32 combFilterDmem;
s32 s5; s32 s5;
Note* note; Note* note;
u32 numSamplesToLoad; u32 numSamplesToLoad;
u16 unk7; u16 combFilterSize;
u16 unkE; u16 combFilterGain;
s16* filter; s16* filter;
s32 bookOffset; s32 bookOffset;
s32 finished; s32 finished;
@ -769,7 +769,7 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS
synthState->prevHaasEffectRightDelaySize = 0; synthState->prevHaasEffectRightDelaySize = 0;
synthState->reverbVol = noteSubEu->reverbVol; synthState->reverbVol = noteSubEu->reverbVol;
synthState->numParts = 0; synthState->numParts = 0;
synthState->unk_1A = 1; synthState->combFilterNeedsInit = true;
note->noteSubEu.bitField0.finished = false; note->noteSubEu.bitField0.finished = false;
finished = false; finished = false;
} }
@ -1089,23 +1089,26 @@ Acmd* AudioSynth_ProcessNote(s32 noteIndex, NoteSubEu* noteSubEu, NoteSynthesisS
AudioSynth_LoadFilterBuffer(cmd++, flags, DMEM_TEMP, synthState->synthesisBuffers->mixEnvelopeState); AudioSynth_LoadFilterBuffer(cmd++, flags, DMEM_TEMP, synthState->synthesisBuffers->mixEnvelopeState);
} }
unk7 = noteSubEu->unk_07; // Apply the comb filter to the mono-signal by taking the signal with a small temporal offset,
unkE = noteSubEu->unk_0E; // and adding it back to itself
buf = synthState->synthesisBuffers->unkState; combFilterSize = noteSubEu->combFilterSize;
if (unk7 != 0 && noteSubEu->unk_0E != 0) { combFilterGain = noteSubEu->combFilterGain;
AudioSynth_DMemMove(cmd++, DMEM_TEMP, DMEM_SCRATCH2, aiBufLen * SAMPLE_SIZE); combFilterState = synthState->synthesisBuffers->combFilterState;
thing = DMEM_SCRATCH2 - unk7; if ((combFilterSize != 0) && (noteSubEu->combFilterGain != 0)) {
if (synthState->unk_1A != 0) { AudioSynth_DMemMove(cmd++, DMEM_TEMP, DMEM_COMB_TEMP, aiBufLen * SAMPLE_SIZE);
AudioSynth_ClearBuffer(cmd++, thing, unk7); combFilterDmem = DMEM_COMB_TEMP - combFilterSize;
synthState->unk_1A = 0; if (synthState->combFilterNeedsInit) {
AudioSynth_ClearBuffer(cmd++, combFilterDmem, combFilterSize);
synthState->combFilterNeedsInit = false;
} else { } else {
AudioSynth_LoadBuffer(cmd++, thing, unk7, buf); AudioSynth_LoadBuffer(cmd++, combFilterDmem, combFilterSize, combFilterState);
} }
AudioSynth_SaveBuffer(cmd++, DMEM_TEMP + (aiBufLen * SAMPLE_SIZE) - unk7, unk7, buf); AudioSynth_SaveBuffer(cmd++, DMEM_TEMP + (aiBufLen * SAMPLE_SIZE) - combFilterSize, combFilterSize,
AudioSynth_Mix(cmd++, (aiBufLen * (s32)SAMPLE_SIZE) >> 4, unkE, DMEM_SCRATCH2, thing); combFilterState);
AudioSynth_DMemMove(cmd++, thing, DMEM_TEMP, aiBufLen * SAMPLE_SIZE); AudioSynth_Mix(cmd++, (aiBufLen * (s32)SAMPLE_SIZE) >> 4, combFilterGain, DMEM_COMB_TEMP, combFilterDmem);
AudioSynth_DMemMove(cmd++, combFilterDmem, DMEM_TEMP, aiBufLen * SAMPLE_SIZE);
} else { } else {
synthState->unk_1A = 1; synthState->combFilterNeedsInit = true;
} }
if ((noteSubEu->haasEffectLeftDelaySize != 0) || (synthState->prevHaasEffectLeftDelaySize != 0)) { if ((noteSubEu->haasEffectLeftDelaySize != 0) || (synthState->prevHaasEffectLeftDelaySize != 0)) {

View file

@ -3,42 +3,23 @@
#define SAMPLES_TO_OVERPRODUCE 0x10 #define SAMPLES_TO_OVERPRODUCE 0x10
#define EXTRA_BUFFERED_AI_SAMPLES_TARGET 0x80 #define EXTRA_BUFFERED_AI_SAMPLES_TARGET 0x80
typedef enum { AudioTask* AudioThread_UpdateImpl(void);
CHAN_UPD_UNK_0, // 0 void AudioThread_SetFadeInTimer(s32 seqPlayerIndex, s32 fadeTimer);
CHAN_UPD_VOL_SCALE, // 1 void AudioThread_SetFadeOutTimer(s32 seqPlayerIndex, s32 fadeTimer);
CHAN_UPD_VOL, // 2 void AudioThread_ProcessCmds(u32);
CHAN_UPD_PAN_SIGNED, // 3 void AudioThread_ProcessSeqPlayerCmd(SequencePlayer* seqPlayer, AudioCmd* cmd);
CHAN_UPD_FREQ_SCALE, // 4 void AudioThread_ProcessChannelCmd(SequenceChannel* channel, AudioCmd* cmd);
CHAN_UPD_REVERB, // 5 s32 func_800E66C0(s32 flags);
CHAN_UPD_SCRIPT_IO, // 6
CHAN_UPD_PAN_UNSIGNED, // 7
CHAN_UPD_STOP_SOMETHING2, // 8
CHAN_UPD_MUTE_BEHAVE, // 9
CHAN_UPD_VIBE_X8, // 10
CHAN_UPD_VIBE_X32, // 11
CHAN_UPD_UNK_0F, // 12
CHAN_UPD_UNK_20, // 13
CHAN_UPD_STEREO // 14
} ChannelUpdateType;
void func_800E6300(SequenceChannel* channel, AudioCmd* cmd);
void func_800E59AC(s32 playerIdx, s32 fadeTimer);
void Audio_InitMesgQueues(void);
AudioTask* func_800E5000(void);
void Audio_ProcessCmds(u32);
void func_800E6128(SequencePlayer* seqPlayer, AudioCmd* cmd);
void func_800E5958(s32 playerIdx, s32 fadeTimer);
s32 func_800E66C0(s32 arg0);
// AudioMgr_Retrace // AudioMgr_Retrace
AudioTask* func_800E4FE0(void) { AudioTask* AudioThread_Update(void) {
return func_800E5000(); return AudioThread_UpdateImpl();
} }
/** /**
* This is Audio_Update for the audio thread * This is Audio_Update for the audio thread
*/ */
AudioTask* func_800E5000(void) { AudioTask* AudioThread_UpdateImpl(void) {
static s32 sMaxAbiCmdCnt = 0x80; static s32 sMaxAbiCmdCnt = 0x80;
static AudioTask* sWaitingAudioTask = NULL; static AudioTask* sWaitingAudioTask = NULL;
u32 samplesRemainingInAi; u32 samplesRemainingInAi;
@ -55,8 +36,8 @@ AudioTask* func_800E5000(void) {
gAudioCtx.totalTaskCount++; gAudioCtx.totalTaskCount++;
if (gAudioCtx.totalTaskCount % (gAudioCtx.audioBufferParameters.specUnk4) != 0) { if (gAudioCtx.totalTaskCount % (gAudioCtx.audioBufferParameters.specUnk4) != 0) {
if (D_801755D0 != NULL) { if (gAudioCustomUpdateFunction != NULL) {
D_801755D0(); gAudioCustomUpdateFunction();
} }
if ((gAudioCtx.totalTaskCount % gAudioCtx.audioBufferParameters.specUnk4) + 1 == if ((gAudioCtx.totalTaskCount % gAudioCtx.audioBufferParameters.specUnk4) + 1 ==
@ -82,8 +63,8 @@ AudioTask* func_800E5000(void) {
} }
} }
if (D_801755D0 != NULL) { if (gAudioCustomUpdateFunction != NULL) {
D_801755D0(); gAudioCustomUpdateFunction();
} }
sp5C = gAudioCtx.curAudioFrameDmaCount; sp5C = gAudioCtx.curAudioFrameDmaCount;
@ -114,7 +95,7 @@ AudioTask* func_800E5000(void) {
if (gAudioCtx.resetStatus != 0) { if (gAudioCtx.resetStatus != 0) {
if (AudioHeap_ResetStep() == 0) { if (AudioHeap_ResetStep() == 0) {
if (gAudioCtx.resetStatus == 0) { if (gAudioCtx.resetStatus == 0) {
osSendMesg(gAudioCtx.audioResetQueueP, (OSMesg)(u32)gAudioCtx.audioResetSpecIdToLoad, OS_MESG_NOBLOCK); osSendMesg(gAudioCtx.audioResetQueueP, (OSMesg)(u32)gAudioCtx.specId, OS_MESG_NOBLOCK);
} }
sWaitingAudioTask = NULL; sWaitingAudioTask = NULL;
@ -151,13 +132,13 @@ AudioTask* func_800E5000(void) {
j = 0; j = 0;
if (gAudioCtx.resetStatus == 0) { if (gAudioCtx.resetStatus == 0) {
// msg = 0000RREE R = read pos, E = End Pos // msg = 0000RREE R = read pos, E = End Pos
while (osRecvMesg(gAudioCtx.cmdProcQueueP, (OSMesg*)&sp4C, OS_MESG_NOBLOCK) != -1) { while (osRecvMesg(gAudioCtx.threadCmdProcQueueP, (OSMesg*)&sp4C, OS_MESG_NOBLOCK) != -1) {
if (1) {} if (1) {}
Audio_ProcessCmds(sp4C); AudioThread_ProcessCmds(sp4C);
j++; j++;
} }
if ((j == 0) && (gAudioCtx.cmdQueueFinished)) { if ((j == 0) && (gAudioCtx.threadCmdQueueFinished)) {
Audio_ScheduleProcessCmds(); AudioThread_ScheduleProcessCmds();
} }
} }
@ -169,9 +150,9 @@ AudioTask* func_800E5000(void) {
gAudioCtx.audioRandom = gAudioCtx.audioRandom + gAudioCtx.aiBuffers[index][gAudioCtx.totalTaskCount & 0xFF]; gAudioCtx.audioRandom = gAudioCtx.audioRandom + gAudioCtx.aiBuffers[index][gAudioCtx.totalTaskCount & 0xFF];
// gWaveSamples[8] interprets compiled assembly code as s16 samples as a way to generate sound with noise. // gWaveSamples[8] interprets compiled assembly code as s16 samples as a way to generate sound with noise.
// Start with the address of func_800E4FE0, and offset it by a random number between 0 - 0xFFF0 // Start with the address of AudioThread_Update, and offset it by a random number between 0 - 0xFFF0
// Use the resulting address as the starting address to interpret an array of samples i.e. `s16 samples[]` // Use the resulting address as the starting address to interpret an array of samples i.e. `s16 samples[]`
gWaveSamples[8] = (s16*)(((u8*)func_800E4FE0) + (gAudioCtx.audioRandom & 0xFFF0)); gWaveSamples[8] = (s16*)((u8*)AudioThread_Update + (gAudioCtx.audioRandom & 0xFFF0));
index = gAudioCtx.rspTaskIndex; index = gAudioCtx.rspTaskIndex;
gAudioCtx.curTask->msgQueue = NULL; gAudioCtx.curTask->msgQueue = NULL;
@ -208,117 +189,111 @@ AudioTask* func_800E5000(void) {
} }
} }
#define ACMD_SND_MDE ((u32)0xF0000000) void AudioThread_ProcessGlobalCmd(AudioCmd* cmd) {
#define ACMD_MUTE ((u32)0xF1000000)
void func_800E5584(AudioCmd* cmd) {
s32 i; s32 i;
s32 pad; s32 pad[3];
s32 pad2; u32 flags;
u32 temp_a1_5;
u32 temp_t7;
switch (cmd->op) { switch (cmd->op) {
case 0x81: case AUDIOCMD_OP_GLOBAL_SYNC_LOAD_SEQ_PARTS:
AudioLoad_SyncLoadSeqParts(cmd->arg1, cmd->arg2); AudioLoad_SyncLoadSeqParts(cmd->arg1, cmd->arg2);
break; break;
case 0x82: case AUDIOCMD_OP_GLOBAL_INIT_SEQPLAYER:
AudioLoad_SyncInitSeqPlayer(cmd->arg0, cmd->arg1, cmd->arg2); AudioLoad_SyncInitSeqPlayer(cmd->arg0, cmd->arg1, cmd->arg2);
func_800E59AC(cmd->arg0, cmd->asInt); AudioThread_SetFadeInTimer(cmd->arg0, cmd->asInt);
break; break;
case 0x85: case AUDIOCMD_OP_GLOBAL_INIT_SEQPLAYER_SKIP_TICKS:
AudioLoad_SyncInitSeqPlayerSkipTicks(cmd->arg0, cmd->arg1, cmd->asInt); AudioLoad_SyncInitSeqPlayerSkipTicks(cmd->arg0, cmd->arg1, cmd->asInt);
break; break;
case 0x83: case AUDIOCMD_OP_GLOBAL_DISABLE_SEQPLAYER:
if (gAudioCtx.seqPlayers[cmd->arg0].enabled) { if (gAudioCtx.seqPlayers[cmd->arg0].enabled) {
if (cmd->asInt == 0) { if (cmd->asInt == 0) {
AudioSeq_SequencePlayerDisableAsFinished(&gAudioCtx.seqPlayers[cmd->arg0]); AudioSeq_SequencePlayerDisableAsFinished(&gAudioCtx.seqPlayers[cmd->arg0]);
} else { } else {
func_800E5958(cmd->arg0, cmd->asInt); AudioThread_SetFadeOutTimer(cmd->arg0, cmd->asInt);
} }
} }
break; break;
case 0xF0: case AUDIOCMD_OP_GLOBAL_SET_SOUND_MODE:
gAudioCtx.soundMode = cmd->asUInt; gAudioCtx.soundMode = cmd->asUInt;
break; break;
case 0xF1: case AUDIOCMD_OP_GLOBAL_MUTE:
for (i = 0; i < gAudioCtx.audioBufferParameters.numSequencePlayers; i++) { for (i = 0; i < gAudioCtx.audioBufferParameters.numSequencePlayers; i++) {
SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[i]; SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[i];
seqPlayer->muted = 1; seqPlayer->muted = true;
seqPlayer->recalculateVolume = 1; seqPlayer->recalculateVolume = true;
} }
break; break;
case 0xF2: case AUDIOCMD_OP_GLOBAL_UNMUTE:
if (cmd->asUInt == 1) { if (cmd->asUInt == 1) {
for (i = 0; i < gAudioCtx.numNotes; i++) { for (i = 0; i < gAudioCtx.numNotes; i++) {
Note* note = &gAudioCtx.notes[i]; Note* note = &gAudioCtx.notes[i];
NoteSubEu* subEu = &note->noteSubEu; NoteSubEu* subEu = &note->noteSubEu;
if (subEu->bitField0.enabled && note->playbackState.unk_04 == 0) { if (subEu->bitField0.enabled && (note->playbackState.unk_04 == 0) &&
if (note->playbackState.parentLayer->channel->muteBehavior & MUTE_BEHAVIOR_3) { (note->playbackState.parentLayer->channel->muteBehavior & MUTE_BEHAVIOR_3)) {
subEu->bitField0.finished = true; subEu->bitField0.finished = true;
} }
} }
} }
}
for (i = 0; i < gAudioCtx.audioBufferParameters.numSequencePlayers; i++) { for (i = 0; i < gAudioCtx.audioBufferParameters.numSequencePlayers; i++) {
SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[i]; SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[i];
seqPlayer->muted = 0; seqPlayer->muted = false;
seqPlayer->recalculateVolume = 1; seqPlayer->recalculateVolume = true;
} }
break; break;
case 0xF3: case AUDIOCMD_OP_GLOBAL_SYNC_LOAD_INSTRUMENT:
AudioLoad_SyncLoadInstrument(cmd->arg0, cmd->arg1, cmd->arg2); AudioLoad_SyncLoadInstrument(cmd->arg0, cmd->arg1, cmd->arg2);
break; break;
case 0xF4: case AUDIOCMD_OP_GLOBAL_ASYNC_LOAD_SAMPLE_BANK:
AudioLoad_AsyncLoadSampleBank(cmd->arg0, cmd->arg1, cmd->arg2, &gAudioCtx.externalLoadQueue); AudioLoad_AsyncLoadSampleBank(cmd->arg0, cmd->arg1, cmd->arg2, &gAudioCtx.externalLoadQueue);
break; break;
case 0xF5: case AUDIOCMD_OP_GLOBAL_ASYNC_LOAD_FONT:
AudioLoad_AsyncLoadFont(cmd->arg0, cmd->arg1, cmd->arg2, &gAudioCtx.externalLoadQueue); AudioLoad_AsyncLoadFont(cmd->arg0, cmd->arg1, cmd->arg2, &gAudioCtx.externalLoadQueue);
break; break;
case 0xFC: case AUDIOCMD_OP_GLOBAL_ASYNC_LOAD_SEQ:
AudioLoad_AsyncLoadSeq(cmd->arg0, cmd->arg1, cmd->arg2, &gAudioCtx.externalLoadQueue); AudioLoad_AsyncLoadSeq(cmd->arg0, cmd->arg1, cmd->arg2, &gAudioCtx.externalLoadQueue);
break; break;
case 0xF6: case AUDIOCMD_OP_GLOBAL_DISCARD_SEQ_FONTS:
AudioLoad_DiscardSeqFonts(cmd->arg1); AudioLoad_DiscardSeqFonts(cmd->arg1);
break; break;
case 0x90: case AUDIOCMD_OP_GLOBAL_SET_CHANNEL_MASK:
gAudioCtx.unk_5BDC[cmd->arg0] = cmd->asUShort; gAudioCtx.threadCmdChannelMask[cmd->arg0] = cmd->asUShort;
break; break;
case 0xF9: case AUDIOCMD_OP_GLOBAL_RESET_AUDIO_HEAP:
gAudioCtx.resetStatus = 5; gAudioCtx.resetStatus = 5;
gAudioCtx.audioResetSpecIdToLoad = cmd->asUInt; gAudioCtx.specId = cmd->asUInt;
break; break;
case 0xFB: case AUDIOCMD_OP_GLOBAL_SET_CUSTOM_UPDATE_FUNCTION:
D_801755D0 = (void (*)(void))cmd->asUInt; gAudioCustomUpdateFunction = (AudioCustomUpdateFunction)cmd->asUInt;
break; break;
case 0xE0: case AUDIOCMD_OP_GLOBAL_SET_DRUM_FONT:
case 0xE1: case AUDIOCMD_OP_GLOBAL_SET_SFX_FONT:
case 0xE2: case AUDIOCMD_OP_GLOBAL_SET_INSTRUMENT_FONT:
Audio_SetFontInstrument(cmd->op - 0xE0, cmd->arg0, cmd->arg1, cmd->data); Audio_SetFontInstrument(cmd->op - AUDIOCMD_OP_GLOBAL_SET_DRUM_FONT, cmd->arg0, cmd->arg1, cmd->data);
break; break;
case 0xFE: case AUDIOCMD_OP_GLOBAL_DISABLE_ALL_SEQPLAYERS:
temp_t7 = cmd->asUInt; flags = cmd->asUInt;
if (temp_t7 == 1) { if (flags == 1) {
for (i = 0; i < gAudioCtx.audioBufferParameters.numSequencePlayers; i++) { for (i = 0; i < gAudioCtx.audioBufferParameters.numSequencePlayers; i++) {
SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[i]; SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[i];
@ -327,10 +302,10 @@ void func_800E5584(AudioCmd* cmd) {
} }
} }
} }
func_800E66C0(temp_t7); func_800E66C0(flags);
break; break;
case 0xE3: case AUDIOCMD_OP_GLOBAL_POP_PERSISTENT_CACHE:
AudioHeap_PopPersistentCache(cmd->asInt); AudioHeap_PopPersistentCache(cmd->asInt);
break; break;
@ -339,9 +314,8 @@ void func_800E5584(AudioCmd* cmd) {
} }
} }
// SetFadeOutTimer void AudioThread_SetFadeOutTimer(s32 seqPlayerIndex, s32 fadeTimer) {
void func_800E5958(s32 playerIdx, s32 fadeTimer) { SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[seqPlayerIndex];
SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[playerIdx];
if (fadeTimer == 0) { if (fadeTimer == 0) {
fadeTimer = 1; fadeTimer = 1;
@ -352,12 +326,11 @@ void func_800E5958(s32 playerIdx, s32 fadeTimer) {
seqPlayer->fadeTimer = fadeTimer; seqPlayer->fadeTimer = fadeTimer;
} }
// SetFadeInTimer void AudioThread_SetFadeInTimer(s32 seqPlayerIndex, s32 fadeTimer) {
void func_800E59AC(s32 playerIdx, s32 fadeTimer) {
SequencePlayer* seqPlayer; SequencePlayer* seqPlayer;
if (fadeTimer != 0) { if (fadeTimer != 0) {
seqPlayer = &gAudioCtx.seqPlayers[playerIdx]; seqPlayer = &gAudioCtx.seqPlayers[seqPlayerIndex];
seqPlayer->state = 1; seqPlayer->state = 1;
seqPlayer->fadeTimerUnkEu = fadeTimer; seqPlayer->fadeTimerUnkEu = fadeTimer;
seqPlayer->fadeTimer = fadeTimer; seqPlayer->fadeTimer = fadeTimer;
@ -366,63 +339,67 @@ void func_800E59AC(s32 playerIdx, s32 fadeTimer) {
} }
} }
void Audio_InitMesgQueuesInternal(void) { void AudioThread_InitMesgQueuesImpl(void) {
gAudioCtx.cmdWrPos = 0; gAudioCtx.threadCmdWritePos = 0;
gAudioCtx.cmdRdPos = 0; gAudioCtx.threadCmdReadPos = 0;
gAudioCtx.cmdQueueFinished = 0; gAudioCtx.threadCmdQueueFinished = false;
gAudioCtx.taskStartQueueP = &gAudioCtx.taskStartQueue; gAudioCtx.taskStartQueueP = &gAudioCtx.taskStartQueue;
gAudioCtx.cmdProcQueueP = &gAudioCtx.cmdProcQueue; gAudioCtx.threadCmdProcQueueP = &gAudioCtx.threadCmdProcQueue;
gAudioCtx.audioResetQueueP = &gAudioCtx.audioResetQueue; gAudioCtx.audioResetQueueP = &gAudioCtx.audioResetQueue;
osCreateMesgQueue(gAudioCtx.taskStartQueueP, gAudioCtx.taskStartMsgBuf, ARRAY_COUNT(gAudioCtx.taskStartMsgBuf)); osCreateMesgQueue(gAudioCtx.taskStartQueueP, gAudioCtx.taskStartMsgBuf, ARRAY_COUNT(gAudioCtx.taskStartMsgBuf));
osCreateMesgQueue(gAudioCtx.cmdProcQueueP, gAudioCtx.cmdProcMsgBuf, ARRAY_COUNT(gAudioCtx.cmdProcMsgBuf)); osCreateMesgQueue(gAudioCtx.threadCmdProcQueueP, gAudioCtx.threadCmdProcMsgBuf,
ARRAY_COUNT(gAudioCtx.threadCmdProcMsgBuf));
osCreateMesgQueue(gAudioCtx.audioResetQueueP, gAudioCtx.audioResetMsgBuf, ARRAY_COUNT(gAudioCtx.audioResetMsgBuf)); osCreateMesgQueue(gAudioCtx.audioResetQueueP, gAudioCtx.audioResetMsgBuf, ARRAY_COUNT(gAudioCtx.audioResetMsgBuf));
} }
void Audio_QueueCmd(u32 opArgs, void** data) { void AudioThread_QueueCmd(u32 opArgs, void** data) {
AudioCmd* cmd = &gAudioCtx.cmdBuf[gAudioCtx.cmdWrPos & 0xFF]; AudioCmd* cmd = &gAudioCtx.threadCmdBuf[gAudioCtx.threadCmdWritePos & 0xFF];
cmd->opArgs = opArgs; cmd->opArgs = opArgs;
cmd->data = *data; cmd->data = *data;
gAudioCtx.cmdWrPos++; gAudioCtx.threadCmdWritePos++;
if (gAudioCtx.cmdWrPos == gAudioCtx.cmdRdPos) { if (gAudioCtx.threadCmdWritePos == gAudioCtx.threadCmdReadPos) {
gAudioCtx.cmdWrPos--; gAudioCtx.threadCmdWritePos--;
} }
} }
void Audio_QueueCmdF32(u32 opArgs, f32 data) { void AudioThread_QueueCmdF32(u32 opArgs, f32 data) {
Audio_QueueCmd(opArgs, (void**)&data); AudioThread_QueueCmd(opArgs, (void**)&data);
} }
void Audio_QueueCmdS32(u32 opArgs, s32 data) { void AudioThread_QueueCmdS32(u32 opArgs, s32 data) {
Audio_QueueCmd(opArgs, (void**)&data); AudioThread_QueueCmd(opArgs, (void**)&data);
} }
void Audio_QueueCmdS8(u32 opArgs, s8 data) { void AudioThread_QueueCmdS8(u32 opArgs, s8 data) {
u32 uData = data << 0x18; u32 uData = data << 0x18;
Audio_QueueCmd(opArgs, (void**)&uData); AudioThread_QueueCmd(opArgs, (void**)&uData);
} }
void Audio_QueueCmdU16(u32 opArgs, u16 data) { void AudioThread_QueueCmdU16(u32 opArgs, u16 data) {
u32 uData = data << 0x10; u32 uData = data << 0x10;
Audio_QueueCmd(opArgs, (void**)&uData); AudioThread_QueueCmd(opArgs, (void**)&uData);
} }
s32 Audio_ScheduleProcessCmds(void) { s32 AudioThread_ScheduleProcessCmds(void) {
static s32 D_801304E8 = 0; static s32 D_801304E8 = 0;
s32 ret; s32 ret;
if (D_801304E8 < (u8)((gAudioCtx.cmdWrPos - gAudioCtx.cmdRdPos) + 0x100)) { if (D_801304E8 < (u8)((gAudioCtx.threadCmdWritePos - gAudioCtx.threadCmdReadPos) + 0x100)) {
D_801304E8 = (u8)((gAudioCtx.cmdWrPos - gAudioCtx.cmdRdPos) + 0x100); D_801304E8 = (u8)((gAudioCtx.threadCmdWritePos - gAudioCtx.threadCmdReadPos) + 0x100);
} }
ret = osSendMesg(gAudioCtx.cmdProcQueueP, ret = osSendMesg(gAudioCtx.threadCmdProcQueueP,
(OSMesg)(((gAudioCtx.cmdRdPos & 0xFF) << 8) | (gAudioCtx.cmdWrPos & 0xFF)), OS_MESG_NOBLOCK); (OSMesg)(((gAudioCtx.threadCmdReadPos & 0xFF) << 8) | (gAudioCtx.threadCmdWritePos & 0xFF)),
OS_MESG_NOBLOCK);
if (ret != -1) { if (ret != -1) {
gAudioCtx.cmdRdPos = gAudioCtx.cmdWrPos; gAudioCtx.threadCmdReadPos = gAudioCtx.threadCmdWritePos;
ret = 0; ret = 0;
} else { } else {
return -1; return -1;
@ -431,72 +408,72 @@ s32 Audio_ScheduleProcessCmds(void) {
return ret; return ret;
} }
void Audio_ResetCmdQueue(void) { void AudioThread_ResetCmdQueue(void) {
gAudioCtx.cmdQueueFinished = 0; gAudioCtx.threadCmdQueueFinished = false;
gAudioCtx.cmdRdPos = gAudioCtx.cmdWrPos; gAudioCtx.threadCmdReadPos = gAudioCtx.threadCmdWritePos;
} }
void Audio_ProcessCmd(AudioCmd* cmd) { void AudioThread_ProcessCmd(AudioCmd* cmd) {
SequencePlayer* seqPlayer; SequencePlayer* seqPlayer;
u16 phi_v0; u16 threadCmdChannelMask;
s32 i; s32 channelIndex;
if ((cmd->op & 0xF0) == 0xF0) { if ((cmd->op & 0xF0) == 0xF0) {
func_800E5584(cmd); AudioThread_ProcessGlobalCmd(cmd);
return; return;
} }
if (cmd->arg0 < gAudioCtx.audioBufferParameters.numSequencePlayers) { if (cmd->arg0 < gAudioCtx.audioBufferParameters.numSequencePlayers) {
seqPlayer = &gAudioCtx.seqPlayers[cmd->arg0]; seqPlayer = &gAudioCtx.seqPlayers[cmd->arg0];
if (cmd->op & 0x80) { if (cmd->op & 0x80) {
func_800E5584(cmd); AudioThread_ProcessGlobalCmd(cmd);
return; return;
} }
if (cmd->op & 0x40) { if (cmd->op & 0x40) {
func_800E6128(seqPlayer, cmd); AudioThread_ProcessSeqPlayerCmd(seqPlayer, cmd);
return; return;
} }
if (cmd->arg1 < 0x10) { if (cmd->arg1 < SEQ_NUM_CHANNELS) {
func_800E6300(seqPlayer->channels[cmd->arg1], cmd); AudioThread_ProcessChannelCmd(seqPlayer->channels[cmd->arg1], cmd);
return; return;
} }
if (cmd->arg1 == 0xFF) { if (cmd->arg1 == AUDIOCMD_ALL_CHANNELS) {
phi_v0 = gAudioCtx.unk_5BDC[cmd->arg0]; threadCmdChannelMask = gAudioCtx.threadCmdChannelMask[cmd->arg0];
for (i = 0; i < 16; i++) { for (channelIndex = 0; channelIndex < SEQ_NUM_CHANNELS; channelIndex++) {
if (phi_v0 & 1) { if (threadCmdChannelMask & 1) {
func_800E6300(seqPlayer->channels[i], cmd); AudioThread_ProcessChannelCmd(seqPlayer->channels[channelIndex], cmd);
} }
phi_v0 = phi_v0 >> 1; threadCmdChannelMask = threadCmdChannelMask >> 1;
} }
} }
} }
} }
void Audio_ProcessCmds(u32 msg) { void AudioThread_ProcessCmds(u32 msg) {
static u8 curCmdRdPos = 0; static u8 sCurCmdRdPos = 0;
AudioCmd* cmd; AudioCmd* cmd;
u8 endPos; u8 endPos;
if (!gAudioCtx.cmdQueueFinished) { if (!gAudioCtx.threadCmdQueueFinished) {
curCmdRdPos = msg >> 8; sCurCmdRdPos = msg >> 8;
} }
while (true) { while (true) {
endPos = msg & 0xFF; endPos = msg & 0xFF;
if (curCmdRdPos == endPos) { if (sCurCmdRdPos == endPos) {
gAudioCtx.cmdQueueFinished = 0; gAudioCtx.threadCmdQueueFinished = false;
return; return;
} }
cmd = &gAudioCtx.cmdBuf[curCmdRdPos++ & 0xFF]; cmd = &gAudioCtx.threadCmdBuf[sCurCmdRdPos++ & 0xFF];
if (cmd->op == 0xF8) { if (cmd->op == AUDIOCMD_OP_GLOBAL_STOP_AUDIOCMDS) {
gAudioCtx.cmdQueueFinished = 1; gAudioCtx.threadCmdQueueFinished = true;
return; return;
} }
Audio_ProcessCmd(cmd); AudioThread_ProcessCmd(cmd);
cmd->op = 0; cmd->op = AUDIOCMD_OP_NOOP;
} }
} }
@ -511,8 +488,8 @@ u32 func_800E5E20(u32* out) {
return sp1C >> 0x18; return sp1C >> 0x18;
} }
u8* func_800E5E84(s32 arg0, u32* arg1) { u8* AudioThread_GetFontsForSequence(s32 seqId, u32* outNumFonts) {
return AudioLoad_GetFontsForSequence(arg0, arg1); return AudioLoad_GetFontsForSequence(seqId, outNumFonts);
} }
void Audio_GetSampleBankIdsOfFont(s32 fontId, u32* sampleBankId1, u32* sampleBankId2) { void Audio_GetSampleBankIdsOfFont(s32 fontId, u32* sampleBankId1, u32* sampleBankId2) {
@ -522,11 +499,11 @@ void Audio_GetSampleBankIdsOfFont(s32 fontId, u32* sampleBankId1, u32* sampleBan
s32 func_800E5EDC(void) { s32 func_800E5EDC(void) {
s32 pad; s32 pad;
s32 sp18; s32 specId;
if (osRecvMesg(gAudioCtx.audioResetQueueP, (OSMesg*)&sp18, OS_MESG_NOBLOCK) == -1) { if (osRecvMesg(gAudioCtx.audioResetQueueP, (OSMesg*)&specId, OS_MESG_NOBLOCK) == -1) {
return 0; return 0;
} else if (gAudioCtx.audioResetSpecIdToLoad != sp18) { } else if (gAudioCtx.specId != specId) {
return -1; return -1;
} else { } else {
return 1; return 1;
@ -540,7 +517,7 @@ void func_800E5F34(void) {
// clang-format on // clang-format on
} }
s32 func_800E5F88(s32 resetPreloadID) { s32 AudioThread_ResetAudioHeap(s32 specId) {
s32 resetStatus; s32 resetStatus;
OSMesg msg; OSMesg msg;
s32 pad; s32 pad;
@ -548,11 +525,11 @@ s32 func_800E5F88(s32 resetPreloadID) {
func_800E5F34(); func_800E5F34();
resetStatus = gAudioCtx.resetStatus; resetStatus = gAudioCtx.resetStatus;
if (resetStatus != 0) { if (resetStatus != 0) {
Audio_ResetCmdQueue(); AudioThread_ResetCmdQueue();
if (gAudioCtx.audioResetSpecIdToLoad == resetPreloadID) { if (gAudioCtx.specId == specId) {
return -2; return -2;
} else if (resetStatus > 2) { } else if (resetStatus > 2) {
gAudioCtx.audioResetSpecIdToLoad = resetPreloadID; gAudioCtx.specId = specId;
return -3; return -3;
} else { } else {
osRecvMesg(gAudioCtx.audioResetQueueP, &msg, OS_MESG_BLOCK); osRecvMesg(gAudioCtx.audioResetQueueP, &msg, OS_MESG_BLOCK);
@ -560,81 +537,81 @@ s32 func_800E5F88(s32 resetPreloadID) {
} }
func_800E5F34(); func_800E5F34();
Audio_QueueCmdS32(0xF9000000, resetPreloadID); AUDIOCMD_GLOBAL_RESET_AUDIO_HEAP(specId);
return Audio_ScheduleProcessCmds(); return AudioThread_ScheduleProcessCmds();
} }
void Audio_PreNMIInternal(void) { void AudioThread_PreNMIInternal(void) {
gAudioCtx.resetTimer = 1; gAudioCtx.resetTimer = 1;
if (gAudioContextInitialized) { if (gAudioContextInitialized) {
func_800E5F88(0); AudioThread_ResetAudioHeap(0);
gAudioCtx.resetStatus = 0; gAudioCtx.resetStatus = 0;
} }
} }
s8 func_800E6070(s32 playerIdx, s32 channelIdx, s32 scriptIdx) { s8 AudioThread_GetChannelIO(s32 seqPlayerIndex, s32 channelIndex, s32 ioPort) {
SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[playerIdx]; SequencePlayer* seqPlayer = &gAudioCtx.seqPlayers[seqPlayerIndex];
SequenceChannel* channel; SequenceChannel* channel;
if (seqPlayer->enabled) { if (seqPlayer->enabled) {
channel = seqPlayer->channels[channelIdx]; channel = seqPlayer->channels[channelIndex];
return channel->soundScriptIO[scriptIdx]; return channel->seqScriptIO[ioPort];
} else { } else {
return -1; return SEQ_IO_VAL_NONE;
} }
} }
s8 func_800E60C4(s32 playerIdx, s32 port) { s8 AudioThread_GetSeqPlayerIO(s32 seqPlayerIndex, s32 ioPort) {
return gAudioCtx.seqPlayers[playerIdx].soundScriptIO[port]; return gAudioCtx.seqPlayers[seqPlayerIndex].seqScriptIO[ioPort];
} }
void Audio_InitExternalPool(void* ramAddr, u32 size) { void AudioThread_InitExternalPool(void* ramAddr, u32 size) {
AudioHeap_InitPool(&gAudioCtx.externalPool, ramAddr, size); AudioHeap_InitPool(&gAudioCtx.externalPool, ramAddr, size);
} }
void Audio_DestroyExternalPool(void) { void AudioThread_ResetExternalPool(void) {
gAudioCtx.externalPool.startRamAddr = NULL; gAudioCtx.externalPool.startRamAddr = NULL;
} }
void func_800E6128(SequencePlayer* seqPlayer, AudioCmd* cmd) { void AudioThread_ProcessSeqPlayerCmd(SequencePlayer* seqPlayer, AudioCmd* cmd) {
f32 fadeVolume; f32 fadeVolume;
switch (cmd->op) { switch (cmd->op) {
case 0x41: case AUDIOCMD_OP_SEQPLAYER_FADE_VOLUME_SCALE:
if (seqPlayer->fadeVolumeScale != cmd->asFloat) { if (seqPlayer->fadeVolumeScale != cmd->asFloat) {
seqPlayer->fadeVolumeScale = cmd->asFloat; seqPlayer->fadeVolumeScale = cmd->asFloat;
seqPlayer->recalculateVolume = 1; seqPlayer->recalculateVolume = true;
} }
break; break;
case 0x47: case AUDIOCMD_OP_SEQPLAYER_SET_TEMPO:
seqPlayer->tempo = cmd->asInt * 0x30; seqPlayer->tempo = cmd->asInt * SEQTICKS_PER_BEAT;
break; break;
case 0x49: case AUDIOCMD_OP_SEQPLAYER_CHANGE_TEMPO:
seqPlayer->unk_0C = cmd->asInt * 0x30; seqPlayer->tempoChange = cmd->asInt * SEQTICKS_PER_BEAT;
break; break;
case 0x4E: case AUDIOCMD_OP_SEQPLAYER_CHANGE_TEMPO_SEQTICKS:
seqPlayer->unk_0C = cmd->asInt; seqPlayer->tempoChange = cmd->asInt;
break; break;
case 0x48: case AUDIOCMD_OP_SEQPLAYER_SET_TRANSPOSITION:
seqPlayer->transposition = cmd->asSbyte; seqPlayer->transposition = cmd->asSbyte;
break; break;
case 0x46: case AUDIOCMD_OP_SEQPLAYER_SET_IO:
seqPlayer->soundScriptIO[cmd->arg2] = cmd->asSbyte; seqPlayer->seqScriptIO[cmd->arg2] = cmd->asSbyte;
break; break;
case 0x4A: case AUDIOCMD_OP_SEQPLAYER_FADE_TO_SET_VOLUME:
fadeVolume = (s32)cmd->arg1 / 127.0f; fadeVolume = (s32)cmd->arg1 / 127.0f;
goto block_11; goto apply_fade;
case 0x4B: case AUDIOCMD_OP_SEQPLAYER_FADE_TO_SCALED_VOLUME:
fadeVolume = ((s32)cmd->arg1 / 100.0f) * seqPlayer->fadeVolume; fadeVolume = ((s32)cmd->arg1 / 100.0f) * seqPlayer->fadeVolume;
block_11: apply_fade:
if (seqPlayer->state != 2) { if (seqPlayer->state != 2) {
seqPlayer->volume = seqPlayer->fadeVolume; seqPlayer->volume = seqPlayer->fadeVolume;
if (cmd->asInt == 0) { if (cmd->asInt == 0) {
@ -649,7 +626,7 @@ void func_800E6128(SequencePlayer* seqPlayer, AudioCmd* cmd) {
} }
break; break;
case 0x4C: case AUDIOCMD_OP_SEQPLAYER_RESET_VOLUME:
if (seqPlayer->state != 2) { if (seqPlayer->state != 2) {
if (cmd->asInt == 0) { if (cmd->asInt == 0) {
seqPlayer->fadeVolume = seqPlayer->volume; seqPlayer->fadeVolume = seqPlayer->volume;
@ -663,7 +640,7 @@ void func_800E6128(SequencePlayer* seqPlayer, AudioCmd* cmd) {
} }
break; break;
case 0x4D: case AUDIOCMD_OP_SEQPLAYER_SET_BEND:
seqPlayer->bend = cmd->asFloat; seqPlayer->bend = cmd->asFloat;
if (seqPlayer->bend == 1.0f) { if (seqPlayer->bend == 1.0f) {
seqPlayer->applyBend = false; seqPlayer->applyBend = false;
@ -677,82 +654,83 @@ void func_800E6128(SequencePlayer* seqPlayer, AudioCmd* cmd) {
} }
} }
void func_800E6300(SequenceChannel* channel, AudioCmd* cmd) { void AudioThread_ProcessChannelCmd(SequenceChannel* channel, AudioCmd* cmd) {
switch (cmd->op) { switch (cmd->op) {
case CHAN_UPD_VOL_SCALE: case AUDIOCMD_OP_CHANNEL_SET_VOL_SCALE:
if (channel->volumeScale != cmd->asFloat) { if (channel->volumeScale != cmd->asFloat) {
channel->volumeScale = cmd->asFloat; channel->volumeScale = cmd->asFloat;
channel->changes.s.volume = 1; channel->changes.s.volume = true;
} }
break; break;
case CHAN_UPD_VOL: case AUDIOCMD_OP_CHANNEL_SET_VOL:
if (channel->volume != cmd->asFloat) { if (channel->volume != cmd->asFloat) {
channel->volume = cmd->asFloat; channel->volume = cmd->asFloat;
channel->changes.s.volume = 1; channel->changes.s.volume = true;
} }
break; break;
case CHAN_UPD_PAN_SIGNED: case AUDIOCMD_OP_CHANNEL_SET_PAN:
if (channel->newPan != cmd->asSbyte) { if (channel->newPan != cmd->asSbyte) {
channel->newPan = cmd->asSbyte; channel->newPan = cmd->asSbyte;
channel->changes.s.pan = 1; channel->changes.s.pan = true;
} }
break; break;
case CHAN_UPD_PAN_UNSIGNED: case AUDIOCMD_OP_CHANNEL_SET_PAN_WEIGHT:
//! @bug: Should compare `asSbyte` to `panChannelWeight`
if (channel->newPan != cmd->asSbyte) { if (channel->newPan != cmd->asSbyte) {
channel->panChannelWeight = cmd->asSbyte; channel->panChannelWeight = cmd->asSbyte;
channel->changes.s.pan = 1; channel->changes.s.pan = true;
} }
break; break;
case CHAN_UPD_FREQ_SCALE: case AUDIOCMD_OP_CHANNEL_SET_FREQ_SCALE:
if (channel->freqScale != cmd->asFloat) { if (channel->freqScale != cmd->asFloat) {
channel->freqScale = cmd->asFloat; channel->freqScale = cmd->asFloat;
channel->changes.s.freqScale = 1; channel->changes.s.freqScale = true;
} }
break; break;
case CHAN_UPD_REVERB: case AUDIOCMD_OP_CHANNEL_SET_REVERB_VOLUME:
if (channel->reverb != cmd->asSbyte) { if (channel->targetReverbVol != cmd->asSbyte) {
channel->reverb = cmd->asSbyte; channel->targetReverbVol = cmd->asSbyte;
} }
break; break;
case CHAN_UPD_SCRIPT_IO: case AUDIOCMD_OP_CHANNEL_SET_IO:
if (cmd->arg2 < 8) { if (cmd->arg2 < ARRAY_COUNT(channel->seqScriptIO)) {
channel->soundScriptIO[cmd->arg2] = cmd->asSbyte; channel->seqScriptIO[cmd->arg2] = cmd->asSbyte;
} }
break; break;
case CHAN_UPD_STOP_SOMETHING2: case AUDIOCMD_OP_CHANNEL_SET_MUTE:
channel->stopSomething2 = cmd->asSbyte; channel->muted = cmd->asSbyte;
break; break;
case CHAN_UPD_MUTE_BEHAVE: case AUDIOCMD_OP_CHANNEL_SET_MUTE_BEHAVIOR:
channel->muteBehavior = cmd->asSbyte; channel->muteBehavior = cmd->asSbyte;
break; break;
case CHAN_UPD_VIBE_X8: case AUDIOCMD_OP_CHANNEL_SET_VIBRATO_DEPTH:
channel->vibratoExtentTarget = cmd->asUbyte * 8; channel->vibratoDepthTarget = cmd->asUbyte * 8;
channel->vibratoExtentChangeDelay = 1; channel->vibratoDepthChangeDelay = 1;
break; break;
case CHAN_UPD_VIBE_X32: case AUDIOCMD_OP_CHANNEL_SET_VIBRATO_RATE:
channel->vibratoRateTarget = cmd->asUbyte * 32; channel->vibratoRateTarget = cmd->asUbyte * 32;
channel->vibratoRateChangeDelay = 1; channel->vibratoRateChangeDelay = 1;
break; break;
case CHAN_UPD_UNK_0F: case AUDIOCMD_OP_CHANNEL_SET_COMB_FILTER_SIZE:
channel->unk_0F = cmd->asUbyte; channel->combFilterSize = cmd->asUbyte;
break; break;
case CHAN_UPD_UNK_20: case AUDIOCMD_OP_CHANNEL_SET_COMB_FILTER_GAIN:
channel->unk_20 = cmd->asUShort; channel->combFilterGain = cmd->asUShort;
break; break;
case CHAN_UPD_STEREO: case AUDIOCMD_OP_CHANNEL_SET_STEREO:
channel->stereo.asByte = cmd->asUbyte; channel->stereo.asByte = cmd->asUbyte;
break; break;
@ -761,24 +739,33 @@ void func_800E6300(SequenceChannel* channel, AudioCmd* cmd) {
} }
} }
void func_800E64B0(s32 arg0, s32 arg1, s32 arg2) { /**
Audio_QueueCmdS32(((arg0 & 0xFF) << 0x10) | 0xFA000000 | ((arg1 & 0xFF) << 8) | (arg2 & 0xFF), 1); * Call an audio-thread command that has no code to process it. Unused.
*/
void AudioThread_Noop1Cmd(s32 arg0, s32 arg1, s32 arg2) {
AUDIOCMD_GLOBAL_NOOP_1(arg0, arg1, arg2, 1);
} }
void func_800E64F8(void) { /**
Audio_QueueCmdS32(0xFA000000, 0); * Call an audio-thread command that has no code to process it. Unused.
*/
void AudioThread_Noop1CmdZeroed(void) {
AUDIOCMD_GLOBAL_NOOP_1(0, 0, 0, 0);
} }
void func_800E651C(u32 arg0, s32 arg1) { /**
Audio_QueueCmdS32((arg1 & 0xFF) | 0xFD000000, arg0); * Call an audio-thread command that has no code to process it. Unused.
*/
void AudioThread_Noop2Cmd(u32 arg0, s32 arg1) {
AUDIOCMD_GLOBAL_NOOP_2(0, 0, arg1, arg0);
} }
void Audio_WaitForAudioTask(void) { void AudioThread_WaitForAudioTask(void) {
osRecvMesg(gAudioCtx.taskStartQueueP, NULL, OS_MESG_NOBLOCK); osRecvMesg(gAudioCtx.taskStartQueueP, NULL, OS_MESG_NOBLOCK);
osRecvMesg(gAudioCtx.taskStartQueueP, NULL, OS_MESG_BLOCK); osRecvMesg(gAudioCtx.taskStartQueueP, NULL, OS_MESG_BLOCK);
} }
s32 func_800E6590(s32 playerIdx, s32 arg1, s32 arg2) { s32 func_800E6590(s32 seqPlayerIndex, s32 channelIndex, s32 layerIndex) {
SequencePlayer* seqPlayer; SequencePlayer* seqPlayer;
SequenceLayer* layer; SequenceLayer* layer;
Note* note; Note* note;
@ -786,9 +773,9 @@ s32 func_800E6590(s32 playerIdx, s32 arg1, s32 arg2) {
s32 loopEnd; s32 loopEnd;
s32 samplePos; s32 samplePos;
seqPlayer = &gAudioCtx.seqPlayers[playerIdx]; seqPlayer = &gAudioCtx.seqPlayers[seqPlayerIndex];
if (seqPlayer->enabled && seqPlayer->channels[arg1]->enabled) { if (seqPlayer->enabled && seqPlayer->channels[channelIndex]->enabled) {
layer = seqPlayer->channels[arg1]->layers[arg2]; layer = seqPlayer->channels[channelIndex]->layers[layerIndex];
if (layer == NULL) { if (layer == NULL) {
return 0; return 0;
} }
@ -826,7 +813,7 @@ void func_800E66A0(void) {
func_800E66C0(2); func_800E66C0(2);
} }
s32 func_800E66C0(s32 arg0) { s32 func_800E66C0(s32 flags) {
s32 phi_v1; s32 phi_v1;
NotePlaybackState* playbackState; NotePlaybackState* playbackState;
NoteSubEu* noteSubEu; NoteSubEu* noteSubEu;
@ -841,7 +828,7 @@ s32 func_800E66C0(s32 arg0) {
if (note->noteSubEu.bitField0.enabled) { if (note->noteSubEu.bitField0.enabled) {
noteSubEu = &note->noteSubEu; noteSubEu = &note->noteSubEu;
if (playbackState->adsr.action.s.state != 0) { if (playbackState->adsr.action.s.state != 0) {
if (arg0 >= 2) { if (flags >= 2) {
tunedSample = noteSubEu->tunedSample; tunedSample = noteSubEu->tunedSample;
if (tunedSample == NULL || noteSubEu->bitField1.isSyntheticWave) { if (tunedSample == NULL || noteSubEu->bitField1.isSyntheticWave) {
continue; continue;
@ -852,8 +839,8 @@ s32 func_800E66C0(s32 arg0) {
} }
phi_v1++; phi_v1++;
if ((arg0 & 1) == 1) { if ((flags & 1) == 1) {
playbackState->adsr.fadeOutVel = gAudioCtx.audioBufferParameters.updatesPerFrameInv; playbackState->adsr.fadeOutVel = gAudioCtx.audioBufferParameters.ticksPerUpdateInv;
playbackState->adsr.action.s.release = 1; playbackState->adsr.action.s.release = 1;
} }
} }
@ -862,14 +849,15 @@ s32 func_800E66C0(s32 arg0) {
return phi_v1; return phi_v1;
} }
u32 Audio_NextRandom(void) { u32 AudioThread_NextRandom(void) {
static u32 audRand = 0x12345678; static u32 sAudioRandom = 0x12345678;
audRand = ((osGetCount() + 0x1234567) * (audRand + gAudioCtx.totalTaskCount)); sAudioRandom = ((osGetCount() + 0x1234567) * (sAudioRandom + gAudioCtx.totalTaskCount));
audRand += gAudioCtx.audioRandom; sAudioRandom += gAudioCtx.audioRandom;
return audRand;
return sAudioRandom;
} }
void Audio_InitMesgQueues(void) { void AudioThread_InitMesgQueues(void) {
Audio_InitMesgQueuesInternal(); AudioThread_InitMesgQueuesImpl();
} }

View file

@ -7,7 +7,7 @@
* These commands are generated using `Audio_QueueSeqCmd`, and a user-friendly interface for this function * These commands are generated using `Audio_QueueSeqCmd`, and a user-friendly interface for this function
* can be found in `seqcmd.h` * can be found in `seqcmd.h`
* *
* These commands change sequences by generating internal audio commands `Audio_QueueCmd` which allows these * These commands change sequences by generating internal audio commands `AudioThread_QueueCmd` which allows these
* sequence requests to be passed onto the audio thread. It is worth noting all functions in this file are * sequence requests to be passed onto the audio thread. It is worth noting all functions in this file are
* called from the graph thread. * called from the graph thread.
* *
@ -22,14 +22,14 @@
#include "ultra64/abi.h" #include "ultra64/abi.h"
// Direct audio command (skips the queueing system) // Direct audio command (skips the queueing system)
#define SEQCMD_SET_PLAYER_VOLUME_NOW(seqPlayerIndex, duration, volume) \ #define SEQCMD_SET_SEQPLAYER_VOLUME_NOW(seqPlayerIndex, duration, volume) \
Audio_ProcessSeqCmd((SEQCMD_OP_SET_PLAYER_VOLUME << 28) | ((u8)(seqPlayerIndex) << 24) | ((u8)(duration) << 16) | \ Audio_ProcessSeqCmd((SEQCMD_OP_SET_SEQPLAYER_VOLUME << 28) | ((u8)(seqPlayerIndex) << 24) | \
((u8)((volume)*127.0f))); ((u8)(duration) << 16) | ((u8)((volume)*127.0f)));
typedef struct { typedef struct {
u8 seqId; /* 0x0 */ u8 seqId;
u8 priority; // higher values have higher priority /* 0x1 */ u8 priority; // higher values have higher priority
} SeqRequest; } SeqRequest; // size = 0x2
SeqRequest sSeqRequests[4][5]; SeqRequest sSeqRequests[4][5];
u8 sNumSeqRequests[4]; u8 sNumSeqRequests[4];
@ -38,26 +38,26 @@ ActiveSequence gActiveSeqs[4];
void Audio_StartSequence(u8 seqPlayerIndex, u8 seqId, u8 seqArgs, u16 fadeInDuration) { void Audio_StartSequence(u8 seqPlayerIndex, u8 seqId, u8 seqArgs, u16 fadeInDuration) {
u8 channelIndex; u8 channelIndex;
u16 duration; u16 skipTicks;
s32 pad; s32 pad;
if (!gStartSeqDisabled || (seqPlayerIndex == SEQ_PLAYER_SFX)) { if (!gStartSeqDisabled || (seqPlayerIndex == SEQ_PLAYER_SFX)) {
seqArgs &= 0x7F; seqArgs &= 0x7F;
if (seqArgs == 0x7F) { if (OOT_DEBUG && (seqArgs == 0x7F)) {
// `fadeInDuration` is interpreted as skip ticks // `fadeInDuration` interpreted as seconds, 60 is refresh rate and does not account for PAL
duration = (fadeInDuration >> 3) * 60 * gAudioCtx.audioBufferParameters.updatesPerFrame; skipTicks = (fadeInDuration >> 3) * 60 * gAudioCtx.audioBufferParameters.ticksPerUpdate;
Audio_QueueCmdS32(0x85000000 | _SHIFTL(seqPlayerIndex, 16, 8) | _SHIFTL(seqId, 8, 8), duration); AUDIOCMD_GLOBAL_INIT_SEQPLAYER_SKIP_TICKS((u32)seqPlayerIndex, (u32)seqId, skipTicks);
} else { } else {
// `fadeInDuration` is interpreted as number of frames at 30 fps // `fadeInDuration` interpreted as 1/30th of a second, does not account for change in refresh rate for PAL
Audio_QueueCmdS32(0x82000000 | _SHIFTL(seqPlayerIndex, 16, 8) | _SHIFTL(seqId, 8, 8), AUDIOCMD_GLOBAL_INIT_SEQPLAYER((u32)seqPlayerIndex, (u32)seqId,
(fadeInDuration * (u16)gAudioCtx.audioBufferParameters.updatesPerFrame) / 4); (fadeInDuration * (u16)gAudioCtx.audioBufferParameters.ticksPerUpdate) / 4);
} }
gActiveSeqs[seqPlayerIndex].seqId = seqId | (seqArgs << 8); gActiveSeqs[seqPlayerIndex].seqId = seqId | (seqArgs << 8);
gActiveSeqs[seqPlayerIndex].prevSeqId = seqId | (seqArgs << 8); gActiveSeqs[seqPlayerIndex].prevSeqId = seqId | (seqArgs << 8);
if (gActiveSeqs[seqPlayerIndex].volCur != 1.0f) { if (gActiveSeqs[seqPlayerIndex].volCur != 1.0f) {
Audio_QueueCmdF32(0x41000000 | _SHIFTL(seqPlayerIndex, 16, 8), gActiveSeqs[seqPlayerIndex].volCur); AUDIOCMD_SEQPLAYER_FADE_VOLUME_SCALE((u32)seqPlayerIndex, gActiveSeqs[seqPlayerIndex].volCur);
} }
gActiveSeqs[seqPlayerIndex].tempoTimer = 0; gActiveSeqs[seqPlayerIndex].tempoTimer = 0;
@ -77,8 +77,8 @@ void Audio_StartSequence(u8 seqPlayerIndex, u8 seqId, u8 seqArgs, u16 fadeInDura
} }
void Audio_StopSequence(u8 seqPlayerIndex, u16 fadeOutDuration) { void Audio_StopSequence(u8 seqPlayerIndex, u16 fadeOutDuration) {
Audio_QueueCmdS32(0x83000000 | ((u8)seqPlayerIndex << 16), AUDIOCMD_GLOBAL_DISABLE_SEQPLAYER(seqPlayerIndex,
(fadeOutDuration * (u16)gAudioCtx.audioBufferParameters.updatesPerFrame) / 4); (fadeOutDuration * (u16)gAudioCtx.audioBufferParameters.ticksPerUpdate) / 4);
gActiveSeqs[seqPlayerIndex].seqId = NA_BGM_DISABLED; gActiveSeqs[seqPlayerIndex].seqId = NA_BGM_DISABLED;
} }
@ -88,25 +88,27 @@ void Audio_ProcessSeqCmd(u32 cmd) {
u16 channelMaskDisable; u16 channelMaskDisable;
u16 fadeTimer; u16 fadeTimer;
u16 val; u16 val;
u8 oldSpec; u8 oldSpecId;
u8 spec; u8 specId;
u8 op; u8 op;
u8 subOp; u8 subOp;
u8 seqPlayerIndex; u8 seqPlayerIndex;
u8 seqId; u8 seqId;
u8 seqArgs; u8 seqArgs;
u8 found; u8 found;
u8 port; u8 ioPort;
u8 duration; u8 duration;
u8 channelIndex; u8 channelIndex;
u8 i; u8 i;
f32 freqScaleTarget; f32 freqScaleTarget;
s32 pad; s32 pad;
if (gAudioDebugPrintSeqCmd && (cmd & SEQCMD_OP_MASK) != (SEQCMD_OP_SET_PLAYER_IO << 28)) { #if OOT_DEBUG
if (gAudioDebugPrintSeqCmd && (cmd & SEQCMD_OP_MASK) != (SEQCMD_OP_SET_SEQPLAYER_IO << 28)) {
AudioDebug_ScrPrt("SEQ H", (cmd >> 16) & 0xFFFF); AudioDebug_ScrPrt("SEQ H", (cmd >> 16) & 0xFFFF);
AudioDebug_ScrPrt(" L", cmd & 0xFFFF); AudioDebug_ScrPrt(" L", cmd & 0xFFFF);
} }
#endif
op = cmd >> 28; op = cmd >> 28;
seqPlayerIndex = (cmd & 0xF000000) >> 24; seqPlayerIndex = (cmd & 0xF000000) >> 24;
@ -213,7 +215,7 @@ void Audio_ProcessSeqCmd(u32 cmd) {
} }
break; break;
case SEQCMD_OP_SET_PLAYER_VOLUME: case SEQCMD_OP_SET_SEQPLAYER_VOLUME:
// Transition volume to a target volume for an entire player // Transition volume to a target volume for an entire player
duration = (cmd & 0xFF0000) >> 15; duration = (cmd & 0xFF0000) >> 15;
val = cmd & 0xFF; val = cmd & 0xFF;
@ -229,7 +231,7 @@ void Audio_ProcessSeqCmd(u32 cmd) {
} }
break; break;
case SEQCMD_OP_SET_PLAYER_FREQ: case SEQCMD_OP_SET_SEQPLAYER_FREQ:
// Transition freq scale to a target freq for all channels // Transition freq scale to a target freq for all channels
duration = (cmd & 0xFF0000) >> 15; duration = (cmd & 0xFF0000) >> 15;
val = cmd & 0xFFFF; val = cmd & 0xFFFF;
@ -285,29 +287,27 @@ void Audio_ProcessSeqCmd(u32 cmd) {
} }
break; break;
case SEQCMD_OP_SET_PLAYER_IO: case SEQCMD_OP_SET_SEQPLAYER_IO:
// Set global io port // Set global io port
port = (cmd & 0xFF0000) >> 16; ioPort = (cmd & 0xFF0000) >> 16;
val = cmd & 0xFF; val = cmd & 0xFF;
Audio_QueueCmdS8(0x46000000 | _SHIFTL(seqPlayerIndex, 16, 8) | _SHIFTL(port, 0, 8), val); AUDIOCMD_SEQPLAYER_SET_IO(seqPlayerIndex, ioPort, val);
break; break;
case SEQCMD_OP_SET_CHANNEL_IO: case SEQCMD_OP_SET_CHANNEL_IO:
// Set io port if channel masked // Set io port if channel masked
channelIndex = (cmd & 0xF00) >> 8; channelIndex = (cmd & 0xF00) >> 8;
port = (cmd & 0xFF0000) >> 16; ioPort = (cmd & 0xFF0000) >> 16;
val = cmd & 0xFF; val = cmd & 0xFF;
if (!(gActiveSeqs[seqPlayerIndex].channelPortMask & (1 << channelIndex))) { if (!(gActiveSeqs[seqPlayerIndex].channelPortMask & (1 << channelIndex))) {
Audio_QueueCmdS8(0x06000000 | _SHIFTL(seqPlayerIndex, 16, 8) | _SHIFTL(channelIndex, 8, 8) | AUDIOCMD_CHANNEL_SET_IO(seqPlayerIndex, (u32)channelIndex, ioPort, val);
_SHIFTL(port, 0, 8),
val);
} }
break; break;
case SEQCMD_OP_SET_CHANNEL_IO_DISABLE_MASK: case SEQCMD_OP_SET_CHANNEL_IO_DISABLE_MASK:
// Disable channel io specifically for // Disable channel io specifically for `SEQCMD_OP_SET_CHANNEL_IO`.
// `SEQCMD_OP_SET_CHANNEL_IO` This can be bypassed by setting channel io through `Audio_QueueCmdS8` 0x6 // This can be bypassed by setting channel io through using `AUDIOCMD_CHANNEL_SET_IO` directly.
// directly. This is accomplished by setting a channel mask. // This is accomplished by setting a channel mask.
gActiveSeqs[seqPlayerIndex].channelPortMask = cmd & 0xFFFF; gActiveSeqs[seqPlayerIndex].channelPortMask = cmd & 0xFFFF;
break; break;
@ -318,18 +318,18 @@ void Audio_ProcessSeqCmd(u32 cmd) {
channelMaskDisable = cmd & 0xFFFF; channelMaskDisable = cmd & 0xFFFF;
if (channelMaskDisable != 0) { if (channelMaskDisable != 0) {
// Apply channel mask `channelMaskDisable` // Apply channel mask `channelMaskDisable`
Audio_QueueCmdU16(0x90000000 | _SHIFTL(seqPlayerIndex, 16, 8), channelMaskDisable); AUDIOCMD_GLOBAL_SET_CHANNEL_MASK(seqPlayerIndex, channelMaskDisable);
// Disable channels // Disable channels
Audio_QueueCmdS8(0x08000000 | _SHIFTL(seqPlayerIndex, 16, 8) | 0xFF00, 1); AUDIOCMD_CHANNEL_SET_MUTE(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, true);
} }
// Reenable channels // Reenable channels
channelMaskEnable = (channelMaskDisable ^ 0xFFFF); channelMaskEnable = (channelMaskDisable ^ 0xFFFF);
if (channelMaskEnable != 0) { if (channelMaskEnable != 0) {
// Apply channel mask `channelMaskEnable` // Apply channel mask `channelMaskEnable`
Audio_QueueCmdU16(0x90000000 | _SHIFTL(seqPlayerIndex, 16, 8), channelMaskEnable); AUDIOCMD_GLOBAL_SET_CHANNEL_MASK(seqPlayerIndex, channelMaskEnable);
// Enable channels // Enable channels
Audio_QueueCmdS8(0x08000000 | _SHIFTL(seqPlayerIndex, 16, 8) | 0xFF00, 0); AUDIOCMD_CHANNEL_SET_MUTE(seqPlayerIndex, AUDIOCMD_ALL_CHANNELS, false);
} }
break; break;
@ -371,7 +371,7 @@ void Audio_ProcessSeqCmd(u32 cmd) {
switch (subOp) { switch (subOp) {
case SEQCMD_SUB_OP_GLOBAL_SET_SOUND_MODE: case SEQCMD_SUB_OP_GLOBAL_SET_SOUND_MODE:
// Set sound mode // Set sound mode
Audio_QueueCmdS32(0xF0000000, gSoundModeList[val]); AUDIOCMD_GLOBAL_SET_SOUND_MODE(gSoundModeList[val]);
break; break;
case SEQCMD_SUB_OP_GLOBAL_DISABLE_NEW_SEQUENCES: case SEQCMD_SUB_OP_GLOBAL_DISABLE_NEW_SEQUENCES:
@ -383,13 +383,13 @@ void Audio_ProcessSeqCmd(u32 cmd) {
case SEQCMD_OP_RESET_AUDIO_HEAP: case SEQCMD_OP_RESET_AUDIO_HEAP:
// Resets the audio heap based on the audio specifications and sfx channel layout // Resets the audio heap based on the audio specifications and sfx channel layout
spec = cmd & 0xFF; specId = cmd & 0xFF;
gSfxChannelLayout = (cmd & 0xFF00) >> 8; gSfxChannelLayout = (cmd & 0xFF00) >> 8;
oldSpec = gAudioSpecId; oldSpecId = gAudioSpecId;
gAudioSpecId = spec; gAudioSpecId = specId;
func_800E5F88(spec); AudioThread_ResetAudioHeap(specId);
func_800F71BC(oldSpec); func_800F71BC(oldSpecId);
Audio_QueueCmdS32(0xF8000000, 0); AUDIOCMD_GLOBAL_STOP_AUDIOCMDS();
break; break;
} }
} }
@ -433,7 +433,7 @@ void Audio_ResetSequenceRequests(u8 seqPlayerIndex) {
/** /**
* Check if the setup command is queued. If it is, then replace the command * Check if the setup command is queued. If it is, then replace the command
* with `SEQCMD_SUB_OP_SETUP_RESTORE_VOLUME`. * with `SEQCMD_SUB_OP_SETUP_RESTORE_SEQPLAYER_VOLUME`.
* Unused * Unused
*/ */
void Audio_ReplaceSeqCmdSetupOpVolRestore(u8 seqPlayerIndex, u8 setupOpDisabled) { void Audio_ReplaceSeqCmdSetupOpVolRestore(u8 seqPlayerIndex, u8 setupOpDisabled) {
@ -462,7 +462,7 @@ void Audio_SetVolumeScale(u8 seqPlayerIndex, u8 scaleIndex, u8 targetVol, u8 vol
volScale *= gActiveSeqs[seqPlayerIndex].volScales[i] / 127.0f; volScale *= gActiveSeqs[seqPlayerIndex].volScales[i] / 127.0f;
} }
SEQCMD_SET_PLAYER_VOLUME_NOW(seqPlayerIndex, volFadeTimer, volScale); SEQCMD_SET_SEQPLAYER_VOLUME_NOW(seqPlayerIndex, volFadeTimer, volScale);
} }
} }
@ -515,7 +515,8 @@ void Audio_UpdateActiveSequences(void) {
for (j = 0; j < VOL_SCALE_INDEX_MAX; j++) { for (j = 0; j < VOL_SCALE_INDEX_MAX; j++) {
volume *= (gActiveSeqs[seqPlayerIndex].volScales[j] / 127.0f); volume *= (gActiveSeqs[seqPlayerIndex].volScales[j] / 127.0f);
} }
SEQCMD_SET_PLAYER_VOLUME(seqPlayerIndex, gActiveSeqs[seqPlayerIndex].volFadeTimer, (u8)(volume * 127.0f)); SEQCMD_SET_SEQPLAYER_VOLUME(seqPlayerIndex, gActiveSeqs[seqPlayerIndex].volFadeTimer,
(u8)(volume * 127.0f));
gActiveSeqs[seqPlayerIndex].fadeVolUpdate = false; gActiveSeqs[seqPlayerIndex].fadeVolUpdate = false;
} }
@ -528,7 +529,7 @@ void Audio_UpdateActiveSequences(void) {
gActiveSeqs[seqPlayerIndex].volCur = gActiveSeqs[seqPlayerIndex].volTarget; gActiveSeqs[seqPlayerIndex].volCur = gActiveSeqs[seqPlayerIndex].volTarget;
} }
Audio_QueueCmdF32(0x41000000 | _SHIFTL(seqPlayerIndex, 16, 8), gActiveSeqs[seqPlayerIndex].volCur); AUDIOCMD_SEQPLAYER_FADE_VOLUME_SCALE((u32)seqPlayerIndex, gActiveSeqs[seqPlayerIndex].volCur);
} }
// Process tempo // Process tempo
@ -542,7 +543,7 @@ void Audio_UpdateActiveSequences(void) {
// Process tempo commands // Process tempo commands
if (gAudioCtx.seqPlayers[seqPlayerIndex].enabled) { if (gAudioCtx.seqPlayers[seqPlayerIndex].enabled) {
tempoPrev = gAudioCtx.seqPlayers[seqPlayerIndex].tempo / TATUMS_PER_BEAT; tempoPrev = gAudioCtx.seqPlayers[seqPlayerIndex].tempo / SEQTICKS_PER_BEAT;
tempoOp = (tempoCmd & 0xF000) >> 12; tempoOp = (tempoCmd & 0xF000) >> 12;
switch (tempoOp) { switch (tempoOp) {
case SEQCMD_SUB_OP_TEMPO_SPEED_UP: case SEQCMD_SUB_OP_TEMPO_SPEED_UP:
@ -583,7 +584,7 @@ void Audio_UpdateActiveSequences(void) {
} }
gActiveSeqs[seqPlayerIndex].tempoTarget = tempoTarget; gActiveSeqs[seqPlayerIndex].tempoTarget = tempoTarget;
gActiveSeqs[seqPlayerIndex].tempoCur = gAudioCtx.seqPlayers[seqPlayerIndex].tempo / TATUMS_PER_BEAT; gActiveSeqs[seqPlayerIndex].tempoCur = gAudioCtx.seqPlayers[seqPlayerIndex].tempo / SEQTICKS_PER_BEAT;
gActiveSeqs[seqPlayerIndex].tempoStep = gActiveSeqs[seqPlayerIndex].tempoStep =
(gActiveSeqs[seqPlayerIndex].tempoCur - gActiveSeqs[seqPlayerIndex].tempoTarget) / tempoTimer; (gActiveSeqs[seqPlayerIndex].tempoCur - gActiveSeqs[seqPlayerIndex].tempoTarget) / tempoTimer;
gActiveSeqs[seqPlayerIndex].tempoTimer = tempoTimer; gActiveSeqs[seqPlayerIndex].tempoTimer = tempoTimer;
@ -599,8 +600,8 @@ void Audio_UpdateActiveSequences(void) {
} else { } else {
gActiveSeqs[seqPlayerIndex].tempoCur = gActiveSeqs[seqPlayerIndex].tempoTarget; gActiveSeqs[seqPlayerIndex].tempoCur = gActiveSeqs[seqPlayerIndex].tempoTarget;
} }
// Set tempo
Audio_QueueCmdS32(0x47000000 | _SHIFTL(seqPlayerIndex, 16, 8), gActiveSeqs[seqPlayerIndex].tempoCur); AUDIOCMD_SEQPLAYER_SET_TEMPO((u32)seqPlayerIndex, gActiveSeqs[seqPlayerIndex].tempoCur);
} }
// Update channel volumes // Update channel volumes
@ -616,8 +617,8 @@ void Audio_UpdateActiveSequences(void) {
gActiveSeqs[seqPlayerIndex].channelData[channelIndex].volTarget; gActiveSeqs[seqPlayerIndex].channelData[channelIndex].volTarget;
gActiveSeqs[seqPlayerIndex].volChannelFlags ^= (1 << channelIndex); gActiveSeqs[seqPlayerIndex].volChannelFlags ^= (1 << channelIndex);
} }
// `CHAN_UPD_VOL_SCALE`
Audio_QueueCmdF32(0x01000000 | _SHIFTL(seqPlayerIndex, 16, 8) | _SHIFTL(channelIndex, 8, 8), AUDIOCMD_CHANNEL_SET_VOL_SCALE(seqPlayerIndex, (u32)channelIndex,
gActiveSeqs[seqPlayerIndex].channelData[channelIndex].volCur); gActiveSeqs[seqPlayerIndex].channelData[channelIndex].volCur);
} }
} }
@ -636,8 +637,8 @@ void Audio_UpdateActiveSequences(void) {
gActiveSeqs[seqPlayerIndex].channelData[channelIndex].freqScaleTarget; gActiveSeqs[seqPlayerIndex].channelData[channelIndex].freqScaleTarget;
gActiveSeqs[seqPlayerIndex].freqScaleChannelFlags ^= (1 << channelIndex); gActiveSeqs[seqPlayerIndex].freqScaleChannelFlags ^= (1 << channelIndex);
} }
// `CHAN_UPD_FREQ_SCALE`
Audio_QueueCmdF32(0x04000000 | _SHIFTL(seqPlayerIndex, 16, 8) | _SHIFTL(channelIndex, 8, 8), AUDIOCMD_CHANNEL_SET_FREQ_SCALE(seqPlayerIndex, (u32)channelIndex,
gActiveSeqs[seqPlayerIndex].channelData[channelIndex].freqScaleCur); gActiveSeqs[seqPlayerIndex].channelData[channelIndex].freqScaleCur);
} }
} }
@ -670,12 +671,12 @@ void Audio_UpdateActiveSequences(void) {
setupVal1 = gActiveSeqs[seqPlayerIndex].setupCmd[j] & 0xFF; setupVal1 = gActiveSeqs[seqPlayerIndex].setupCmd[j] & 0xFF;
switch (setupOp) { switch (setupOp) {
case SEQCMD_SUB_OP_SETUP_RESTORE_VOLUME: case SEQCMD_SUB_OP_SETUP_RESTORE_SEQPLAYER_VOLUME:
// Restore `targetSeqPlayerIndex` volume back to normal levels // Restore `targetSeqPlayerIndex` volume back to normal levels
Audio_SetVolumeScale(targetSeqPlayerIndex, VOL_SCALE_INDEX_FANFARE, 0x7F, setupVal1); Audio_SetVolumeScale(targetSeqPlayerIndex, VOL_SCALE_INDEX_FANFARE, 0x7F, setupVal1);
break; break;
case SEQCMD_SUB_OP_SETUP_RESTORE_VOLUME_IF_QUEUED: case SEQCMD_SUB_OP_SETUP_RESTORE_SEQPLAYER_VOLUME_IF_QUEUED:
// Restore `targetSeqPlayerIndex` volume back to normal levels, // Restore `targetSeqPlayerIndex` volume back to normal levels,
// but only if the number of sequence queue requests from `sSeqRequests` // but only if the number of sequence queue requests from `sSeqRequests`
// exactly matches the argument to the command // exactly matches the argument to the command
@ -729,7 +730,7 @@ void Audio_UpdateActiveSequences(void) {
gActiveSeqs[seqPlayerIndex].setupFadeTimer = setupVal2; gActiveSeqs[seqPlayerIndex].setupFadeTimer = setupVal2;
break; break;
case SEQCMD_SUB_OP_SETUP_RESTORE_VOLUME_WITH_SCALE_INDEX: case SEQCMD_SUB_OP_SETUP_RESTORE_SEQPLAYER_VOLUME_WITH_SCALE_INDEX:
// Restore the volume back to default levels // Restore the volume back to default levels
// Allows a `scaleIndex` to be specified. // Allows a `scaleIndex` to be specified.
Audio_SetVolumeScale(targetSeqPlayerIndex, setupVal2, 0x7F, setupVal1); Audio_SetVolumeScale(targetSeqPlayerIndex, setupVal2, 0x7F, setupVal1);
@ -738,13 +739,13 @@ void Audio_UpdateActiveSequences(void) {
case SEQCMD_SUB_OP_SETUP_POP_PERSISTENT_CACHE: case SEQCMD_SUB_OP_SETUP_POP_PERSISTENT_CACHE:
// Discard audio data by popping one more audio caches from the audio heap // Discard audio data by popping one more audio caches from the audio heap
if (setupVal1 & (1 << SEQUENCE_TABLE)) { if (setupVal1 & (1 << SEQUENCE_TABLE)) {
Audio_QueueCmdS32(0xE3000000, SEQUENCE_TABLE); AUDIOCMD_GLOBAL_POP_PERSISTENT_CACHE(SEQUENCE_TABLE);
} }
if (setupVal1 & (1 << FONT_TABLE)) { if (setupVal1 & (1 << FONT_TABLE)) {
Audio_QueueCmdS32(0xE3000000, FONT_TABLE); AUDIOCMD_GLOBAL_POP_PERSISTENT_CACHE(FONT_TABLE);
} }
if (setupVal1 & (1 << SAMPLE_TABLE)) { if (setupVal1 & (1 << SAMPLE_TABLE)) {
Audio_QueueCmdS32(0xE3000000, SAMPLE_TABLE); AUDIOCMD_GLOBAL_POP_PERSISTENT_CACHE(SAMPLE_TABLE);
} }
break; break;
@ -754,9 +755,9 @@ void Audio_UpdateActiveSequences(void) {
SEQCMD_SET_CHANNEL_DISABLE_MASK(targetSeqPlayerIndex, channelMask); SEQCMD_SET_CHANNEL_DISABLE_MASK(targetSeqPlayerIndex, channelMask);
break; break;
case SEQCMD_SUB_OP_SETUP_SET_PLAYER_FREQ: case SEQCMD_SUB_OP_SETUP_SET_SEQPLAYER_FREQ:
// Scale all channels of `targetSeqPlayerIndex` // Scale all channels of `targetSeqPlayerIndex`
SEQCMD_SET_PLAYER_FREQ(targetSeqPlayerIndex, setupVal2, (setupVal1 * 10) & 0xFFFF); SEQCMD_SET_SEQPLAYER_FREQ(targetSeqPlayerIndex, setupVal2, (setupVal1 * 10) & 0xFFFF);
break; break;
} }
} }
@ -771,13 +772,13 @@ u8 func_800FAD34(void) {
if (D_80133418 == 1) { if (D_80133418 == 1) {
if (func_800E5EDC() == 1) { if (func_800E5EDC() == 1) {
D_80133418 = 0; D_80133418 = 0;
Audio_QueueCmdS8(0x46020000, gSfxChannelLayout); AUDIOCMD_SEQPLAYER_SET_IO(SEQ_PLAYER_SFX, 0, gSfxChannelLayout);
func_800F7170(); func_800F7170();
} }
} else if (D_80133418 == 2) { } else if (D_80133418 == 2) {
while (func_800E5EDC() != 1) {} while (func_800E5EDC() != 1) {}
D_80133418 = 0; D_80133418 = 0;
Audio_QueueCmdS8(0x46020000, gSfxChannelLayout); AUDIOCMD_SEQPLAYER_SET_IO(SEQ_PLAYER_SFX, 0, gSfxChannelLayout);
func_800F7170(); func_800F7170();
} }
} }

View file

@ -2,12 +2,12 @@
u8 D_8016F0E0[0xA0]; // unused u8 D_8016F0E0[0xA0]; // unused
AudioContext gAudioCtx; AudioContext gAudioCtx;
void (*D_801755D0)(void); AudioCustomUpdateFunction gAudioCustomUpdateFunction;
s32 D_801755D8[3]; // unused s32 D_801755D8[3]; // unused
const s16 D_8014A6C0[] = { const TempoData gTempoData = {
0x1C00, // unused 0x1C00, // unk_00
0x0030, // gTatumsPerBeat SEQTICKS_PER_BEAT, // seqTicksPerBeat
}; };
// TODO: Extract from table? // TODO: Extract from table?

View file

@ -30,7 +30,7 @@ u8 sSfxBankListEnd[7];
u8 sSfxBankFreeListStart[7]; u8 sSfxBankFreeListStart[7];
u8 sSfxBankUnused[7]; u8 sSfxBankUnused[7];
ActiveSfx gActiveSfx[7][3]; ActiveSfx gActiveSfx[7][3];
u8 sCurSfxPlayerChannelIdx; u8 sCurSfxPlayerChannelIndex;
u8 gSfxBankMuted[7]; u8 gSfxBankMuted[7];
UnusedBankLerp sUnusedBankLerp[7]; UnusedBankLerp sUnusedBankLerp[7];
u16 gAudioSfxSwapSource[10]; u16 gAudioSfxSwapSource[10];
@ -50,14 +50,14 @@ void Audio_SetSfxBanksMute(u16 muteMask) {
} }
} }
void Audio_QueueSeqCmdMute(u8 channelIdx) { void Audio_QueueSeqCmdMute(u8 channelIndex) {
D_801333D0 |= (1 << channelIdx); D_801333D0 |= (1 << channelIndex);
Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_SFX, 0x40, 0xF); Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_SFX, 0x40, 0xF);
Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, VOL_SCALE_INDEX_SFX, 0x40, 0xF); Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, VOL_SCALE_INDEX_SFX, 0x40, 0xF);
} }
void Audio_ClearBGMMute(u8 channelIdx) { void Audio_ClearBGMMute(u8 channelIndex) {
D_801333D0 &= ((1 << channelIdx) ^ 0xFFFF); D_801333D0 &= ((1 << channelIndex) ^ 0xFFFF);
if (D_801333D0 == 0) { if (D_801333D0 == 0) {
Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_SFX, 0x7F, 0xF); Audio_SetVolumeScale(SEQ_PLAYER_BGM_MAIN, VOL_SCALE_INDEX_SFX, 0x7F, 0xF);
Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, VOL_SCALE_INDEX_SFX, 0x7F, 0xF); Audio_SetVolumeScale(SEQ_PLAYER_BGM_SUB, VOL_SCALE_INDEX_SFX, 0x7F, 0xF);
@ -70,6 +70,8 @@ void Audio_PlaySfxGeneral(u16 sfxId, Vec3f* pos, u8 token, f32* freqScale, f32*
if (!gSfxBankMuted[SFX_BANK_SHIFT(sfxId)]) { if (!gSfxBankMuted[SFX_BANK_SHIFT(sfxId)]) {
req = &sSfxRequests[gSfxRequestWriteIndex]; req = &sSfxRequests[gSfxRequestWriteIndex];
#if OOT_DEBUG
if (!gAudioSfxSwapOff) { if (!gAudioSfxSwapOff) {
for (i = 0; i < 10; i++) { for (i = 0; i < 10; i++) {
if (sfxId == gAudioSfxSwapSource[i]) { if (sfxId == gAudioSfxSwapSource[i]) {
@ -89,6 +91,8 @@ void Audio_PlaySfxGeneral(u16 sfxId, Vec3f* pos, u8 token, f32* freqScale, f32*
} }
} }
} }
#endif
req->sfxId = sfxId; req->sfxId = sfxId;
req->pos = pos; req->pos = pos;
req->token = token; req->token = token;
@ -164,10 +168,14 @@ void Audio_ProcessSfxRequest(void) {
} }
bankId = SFX_BANK(req->sfxId); bankId = SFX_BANK(req->sfxId);
#if OOT_DEBUG
if ((1 << bankId) & D_801333F0) { if ((1 << bankId) & D_801333F0) {
AudioDebug_ScrPrt("SE", req->sfxId); AudioDebug_ScrPrt("SE", req->sfxId);
bankId = SFX_BANK(req->sfxId); bankId = SFX_BANK(req->sfxId);
} }
#endif
count = 0; count = 0;
index = gSfxBanks[bankId][0].next; index = gSfxBanks[bankId][0].next;
while (index != 0xFF && index != 0) { while (index != 0xFF && index != 0) {
@ -203,7 +211,7 @@ void Audio_ProcessSfxRequest(void) {
if ((req->sfxId & 0xC00) || (sfxParams->params & SFX_FLAG_2) || (index == evictIndex)) { if ((req->sfxId & 0xC00) || (sfxParams->params & SFX_FLAG_2) || (index == evictIndex)) {
if ((gSfxBanks[bankId][index].sfxParams & SFX_FLAG_3) && if ((gSfxBanks[bankId][index].sfxParams & SFX_FLAG_3) &&
gSfxBanks[bankId][index].state != SFX_STATE_QUEUED) { gSfxBanks[bankId][index].state != SFX_STATE_QUEUED) {
Audio_ClearBGMMute(gSfxBanks[bankId][index].channelIdx); Audio_ClearBGMMute(gSfxBanks[bankId][index].channelIndex);
} }
gSfxBanks[bankId][index].token = req->token; gSfxBanks[bankId][index].token = req->token;
gSfxBanks[bankId][index].sfxId = req->sfxId; gSfxBanks[bankId][index].sfxId = req->sfxId;
@ -254,7 +262,7 @@ void Audio_RemoveSfxBankEntry(u8 bankId, u8 entryIndex) {
u8 i; u8 i;
if (entry->sfxParams & SFX_FLAG_3) { if (entry->sfxParams & SFX_FLAG_3) {
Audio_ClearBGMMute(entry->channelIdx); Audio_ClearBGMMute(entry->channelIndex);
} }
if (entryIndex == sSfxBankListEnd[bankId]) { if (entryIndex == sSfxBankListEnd[bankId]) {
sSfxBankListEnd[bankId] = entry->prev; sSfxBankListEnd[bankId] = entry->prev;
@ -306,7 +314,7 @@ void Audio_ChooseActiveSfx(u8 bankId) {
gSfxBanks[bankId][entryIndex].freshness--; gSfxBanks[bankId][entryIndex].freshness--;
} else if (!(gSfxBanks[bankId][entryIndex].sfxId & 0xC00) && } else if (!(gSfxBanks[bankId][entryIndex].sfxId & 0xC00) &&
(gSfxBanks[bankId][entryIndex].state == SFX_STATE_PLAYING_2)) { (gSfxBanks[bankId][entryIndex].state == SFX_STATE_PLAYING_2)) {
Audio_QueueCmdS8((gSfxBanks[bankId][entryIndex].channelIdx << 8) | 0x6020000, 0); AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, gSfxBanks[bankId][entryIndex].channelIndex, 0, 0);
Audio_RemoveSfxBankEntry(bankId, entryIndex); Audio_RemoveSfxBankEntry(bankId, entryIndex);
} }
if (gSfxBanks[bankId][entryIndex].freshness == 0) { if (gSfxBanks[bankId][entryIndex].freshness == 0) {
@ -318,7 +326,7 @@ void Audio_ChooseActiveSfx(u8 bankId) {
entry->dist = 0.0f; entry->dist = 0.0f;
} else { } else {
tempf1 = *entry->posY * 1; tempf1 = *entry->posY * 1;
entry->dist = (SQ(*entry->posX) + SQ(tempf1) + SQ(*entry->posZ)) * 1; entry->dist = (SQ(*entry->posX) + SQ(tempf1) + SQ(*entry->posZ)) / SFX_DIST_SCALING;
} }
sfxImportance = entry->sfxImportance; sfxImportance = entry->sfxImportance;
if (entry->sfxParams & SFX_FLAG_4) { if (entry->sfxParams & SFX_FLAG_4) {
@ -338,7 +346,7 @@ void Audio_ChooseActiveSfx(u8 bankId) {
} }
if (entry->dist > SQ(1e5f)) { if (entry->dist > SQ(1e5f)) {
if (entry->state == SFX_STATE_PLAYING_1) { if (entry->state == SFX_STATE_PLAYING_1) {
Audio_QueueCmdS8((entry->channelIdx << 8) | 0x6020000, 0); AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, entry->channelIndex, 0, 0);
if (entry->sfxId & 0xC00) { if (entry->sfxId & 0xC00) {
Audio_RemoveSfxBankEntry(bankId, entryIndex); Audio_RemoveSfxBankEntry(bankId, entryIndex);
entryIndex = k; entryIndex = k;
@ -443,45 +451,51 @@ void Audio_PlayActiveSfx(u8 bankId) {
entryIndex = gActiveSfx[bankId][i].entryIndex; entryIndex = gActiveSfx[bankId][i].entryIndex;
if (entryIndex != 0xFF) { if (entryIndex != 0xFF) {
entry = &gSfxBanks[bankId][entryIndex]; entry = &gSfxBanks[bankId][entryIndex];
channel = gAudioCtx.seqPlayers[SEQ_PLAYER_SFX].channels[sCurSfxPlayerChannelIdx]; channel = gAudioCtx.seqPlayers[SEQ_PLAYER_SFX].channels[sCurSfxPlayerChannelIndex];
if (entry->state == SFX_STATE_READY) { if (entry->state == SFX_STATE_READY) {
entry->channelIdx = sCurSfxPlayerChannelIdx; entry->channelIndex = sCurSfxPlayerChannelIndex;
if (entry->sfxParams & SFX_FLAG_3) { if (entry->sfxParams & SFX_FLAG_3) {
Audio_QueueSeqCmdMute(sCurSfxPlayerChannelIdx); Audio_QueueSeqCmdMute(sCurSfxPlayerChannelIndex);
} }
if ((entry->sfxParams & SFX_PARAM_67_MASK) != (0 << SFX_PARAM_67_SHIFT)) { if ((entry->sfxParams & SFX_PARAM_67_MASK) != (0 << SFX_PARAM_67_SHIFT)) {
switch (entry->sfxParams & SFX_PARAM_67_MASK) { switch (entry->sfxParams & SFX_PARAM_67_MASK) {
case (1 << SFX_PARAM_67_SHIFT): case (1 << SFX_PARAM_67_SHIFT):
entry->unk_2F = Audio_NextRandom() & 0xF; entry->unk_2F = AudioThread_NextRandom() & 0xF;
break; break;
case (2 << SFX_PARAM_67_SHIFT): case (2 << SFX_PARAM_67_SHIFT):
entry->unk_2F = Audio_NextRandom() & 0x1F; entry->unk_2F = AudioThread_NextRandom() & 0x1F;
break; break;
case (3 << SFX_PARAM_67_SHIFT): case (3 << SFX_PARAM_67_SHIFT):
entry->unk_2F = Audio_NextRandom() & 0x3F; entry->unk_2F = AudioThread_NextRandom() & 0x3F;
break; break;
default: default:
entry->unk_2F = 0; entry->unk_2F = 0;
break; break;
} }
} }
Audio_SetSfxProperties(bankId, entryIndex, sCurSfxPlayerChannelIdx); Audio_SetSfxProperties(bankId, entryIndex, sCurSfxPlayerChannelIndex);
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((sCurSfxPlayerChannelIdx & 0xFF) << 8), 1);
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((sCurSfxPlayerChannelIdx & 0xFF) << 8) | 4, // ioPort 0, enable the sfx to play in `NA_BGM_GENERAL_SFX`
entry->sfxId & 0xFF); AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, sCurSfxPlayerChannelIndex, 0, 1);
// ioPort 4, write the lower bits sfx index for `NA_BGM_GENERAL_SFX` to find the right code to execute
AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, sCurSfxPlayerChannelIndex, 4, entry->sfxId & 0xFF);
// If the sfx bank has more than 255 entries (greater than a u8 can store),
// then store the Id in upper and lower bits
if (gIsLargeSfxBank[bankId]) { if (gIsLargeSfxBank[bankId]) {
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((sCurSfxPlayerChannelIdx & 0xFF) << 8) | 5, // ioPort 5, write the upper bits sfx index for `NA_BGM_GENERAL_SFX`, for banks with > 0xFF entries
(entry->sfxId & 0x100) >> 8); AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, sCurSfxPlayerChannelIndex, 5, (entry->sfxId & 0x100) >> 8);
} }
if (entry->sfxId & 0xC00) { if (entry->sfxId & 0xC00) {
entry->state = SFX_STATE_PLAYING_1; entry->state = SFX_STATE_PLAYING_1;
} else { } else {
entry->state = SFX_STATE_PLAYING_2; entry->state = SFX_STATE_PLAYING_2;
} }
} else if ((u8)channel->soundScriptIO[1] == (u8)SEQ_IO_VAL_NONE) { } else if ((u8)channel->seqScriptIO[1] == (u8)SEQ_IO_VAL_NONE) {
Audio_RemoveSfxBankEntry(bankId, entryIndex); Audio_RemoveSfxBankEntry(bankId, entryIndex);
} else if (entry->state == SFX_STATE_PLAYING_REFRESH) { } else if (entry->state == SFX_STATE_PLAYING_REFRESH) {
Audio_SetSfxProperties(bankId, entryIndex, sCurSfxPlayerChannelIdx); Audio_SetSfxProperties(bankId, entryIndex, sCurSfxPlayerChannelIndex);
if (entry->sfxId & 0xC00) { if (entry->sfxId & 0xC00) {
entry->state = SFX_STATE_PLAYING_1; entry->state = SFX_STATE_PLAYING_1;
} else { } else {
@ -489,7 +503,7 @@ void Audio_PlayActiveSfx(u8 bankId) {
} }
} }
} }
sCurSfxPlayerChannelIdx++; sCurSfxPlayerChannelIndex++;
} }
} }
@ -502,7 +516,7 @@ void Audio_StopSfxByBank(u8 bankId) {
while (entryIndex != 0xFF) { while (entryIndex != 0xFF) {
entry = &gSfxBanks[bankId][entryIndex]; entry = &gSfxBanks[bankId][entryIndex];
if (entry->state >= SFX_STATE_PLAYING_REFRESH) { if (entry->state >= SFX_STATE_PLAYING_REFRESH) {
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((entry->channelIdx & 0xFF) << 8), 0); AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, entry->channelIndex, 0, 0);
} }
if (entry->state != SFX_STATE_EMPTY) { if (entry->state != SFX_STATE_EMPTY) {
Audio_RemoveSfxBankEntry(bankId, entryIndex); Audio_RemoveSfxBankEntry(bankId, entryIndex);
@ -522,7 +536,7 @@ void func_800F8884(u8 bankId, Vec3f* pos) {
entry = &gSfxBanks[bankId][entryIndex]; entry = &gSfxBanks[bankId][entryIndex];
if (entry->posX == &pos->x) { if (entry->posX == &pos->x) {
if (entry->state >= SFX_STATE_PLAYING_REFRESH) { if (entry->state >= SFX_STATE_PLAYING_REFRESH) {
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((entry->channelIdx & 0xFF) << 8), 0); AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, entry->channelIndex, 0, 0);
} }
if (entry->state != SFX_STATE_EMPTY) { if (entry->state != SFX_STATE_EMPTY) {
Audio_RemoveSfxBankEntry(bankId, entryIndex); Audio_RemoveSfxBankEntry(bankId, entryIndex);
@ -564,7 +578,7 @@ void Audio_StopSfxByPosAndId(Vec3f* pos, u16 sfxId) {
entry = &gSfxBanks[SFX_BANK(sfxId)][entryIndex]; entry = &gSfxBanks[SFX_BANK(sfxId)][entryIndex];
if (entry->posX == &pos->x && entry->sfxId == sfxId) { if (entry->posX == &pos->x && entry->sfxId == sfxId) {
if (entry->state >= SFX_STATE_PLAYING_REFRESH) { if (entry->state >= SFX_STATE_PLAYING_REFRESH) {
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((entry->channelIdx & 0xFF) << 8), 0); AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, entry->channelIndex, 0, 0);
} }
if (entry->state != SFX_STATE_EMPTY) { if (entry->state != SFX_STATE_EMPTY) {
Audio_RemoveSfxBankEntry(SFX_BANK(sfxId), entryIndex); Audio_RemoveSfxBankEntry(SFX_BANK(sfxId), entryIndex);
@ -592,7 +606,7 @@ void Audio_StopSfxByTokenAndId(u8 token, u16 sfxId) {
entry = &gSfxBanks[SFX_BANK(sfxId)][entryIndex]; entry = &gSfxBanks[SFX_BANK(sfxId)][entryIndex];
if (entry->token == token && entry->sfxId == sfxId) { if (entry->token == token && entry->sfxId == sfxId) {
if (entry->state >= SFX_STATE_PLAYING_REFRESH) { if (entry->state >= SFX_STATE_PLAYING_REFRESH) {
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((entry->channelIdx & 0xFF) << 8), 0); AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, entry->channelIndex, 0, 0);
} }
if (entry->state != SFX_STATE_EMPTY) { if (entry->state != SFX_STATE_EMPTY) {
Audio_RemoveSfxBankEntry(SFX_BANK(sfxId), entryIndex); Audio_RemoveSfxBankEntry(SFX_BANK(sfxId), entryIndex);
@ -619,7 +633,7 @@ void Audio_StopSfxById(u32 sfxId) {
entry = &gSfxBanks[SFX_BANK(sfxId)][entryIndex]; entry = &gSfxBanks[SFX_BANK(sfxId)][entryIndex];
if (entry->sfxId == sfxId) { if (entry->sfxId == sfxId) {
if (entry->state >= SFX_STATE_PLAYING_REFRESH) { if (entry->state >= SFX_STATE_PLAYING_REFRESH) {
Audio_QueueCmdS8(0x6 << 24 | SEQ_PLAYER_SFX << 16 | ((entry->channelIdx & 0xFF) << 8), 0); AUDIOCMD_CHANNEL_SET_IO(SEQ_PLAYER_SFX, entry->channelIndex, 0, 0);
} }
if (entry->state != SFX_STATE_EMPTY) { if (entry->state != SFX_STATE_EMPTY) {
Audio_RemoveSfxBankEntry(SFX_BANK(sfxId), entryIndex); Audio_RemoveSfxBankEntry(SFX_BANK(sfxId), entryIndex);
@ -664,7 +678,7 @@ void func_800F8F88(void) {
u8 bankId; u8 bankId;
if (IS_SEQUENCE_CHANNEL_VALID(gAudioCtx.seqPlayers[SEQ_PLAYER_SFX].channels[0])) { if (IS_SEQUENCE_CHANNEL_VALID(gAudioCtx.seqPlayers[SEQ_PLAYER_SFX].channels[0])) {
sCurSfxPlayerChannelIdx = 0; sCurSfxPlayerChannelIndex = 0;
for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) { for (bankId = 0; bankId < ARRAY_COUNT(gSfxBanks); bankId++) {
Audio_ChooseActiveSfx(bankId); Audio_ChooseActiveSfx(bankId);
Audio_PlayActiveSfx(bankId); Audio_PlayActiveSfx(bankId);
@ -718,6 +732,8 @@ void Audio_ResetSfx(void) {
gSfxBanks[bankId][i].prev = i - 1; gSfxBanks[bankId][i].prev = i - 1;
gSfxBanks[bankId][i].next = 0xFF; gSfxBanks[bankId][i].next = 0xFF;
} }
#if OOT_DEBUG
if (D_801333F8 == 0) { if (D_801333F8 == 0) {
for (bankId = 0; bankId < 10; bankId++) { for (bankId = 0; bankId < 10; bankId++) {
gAudioSfxSwapSource[bankId] = 0; gAudioSfxSwapSource[bankId] = 0;
@ -726,4 +742,5 @@ void Audio_ResetSfx(void) {
} }
D_801333F8++; D_801333F8++;
} }
#endif
} }

View file

@ -21,7 +21,9 @@ void bootproc(void) {
gCartHandle = osCartRomInit(); gCartHandle = osCartRomInit();
osDriveRomInit(); osDriveRomInit();
#if OOT_DEBUG
isPrintfInit(); isPrintfInit();
#endif
Locale_Init(); Locale_Init();
StackCheck_Init(&sIdleThreadInfo, sIdleThreadStack, STACK_TOP(sIdleThreadStack), 0, 256, "idle"); StackCheck_Init(&sIdleThreadInfo, sIdleThreadStack, STACK_TOP(sIdleThreadStack), 0, 256, "idle");

View file

@ -56,6 +56,9 @@ void Idle_ThreadEntry(void* arg) {
gViConfigYScale = 1.0f; gViConfigYScale = 1.0f;
switch (osTvType) { switch (osTvType) {
#if !OOT_DEBUG
case OS_TV_PAL:
#endif
case OS_TV_NTSC: case OS_TV_NTSC:
gViConfigModeType = OS_VI_NTSC_LAN1; gViConfigModeType = OS_VI_NTSC_LAN1;
gViConfigMode = osViModeNtscLan1; gViConfigMode = osViModeNtscLan1;
@ -66,11 +69,13 @@ void Idle_ThreadEntry(void* arg) {
gViConfigMode = osViModeMpalLan1; gViConfigMode = osViModeMpalLan1;
break; break;
#if OOT_DEBUG
case OS_TV_PAL: case OS_TV_PAL:
gViConfigModeType = OS_VI_FPAL_LAN1; gViConfigModeType = OS_VI_FPAL_LAN1;
gViConfigMode = osViModeFpalLan1; gViConfigMode = osViModeFpalLan1;
gViConfigYScale = 0.833f; gViConfigYScale = 0.833f;
break; break;
#endif
} }
D_80009430 = 1; D_80009430 = 1;
@ -84,7 +89,5 @@ void Idle_ThreadEntry(void* arg) {
osStartThread(&gMainThread); osStartThread(&gMainThread);
osSetThreadPri(NULL, OS_PRIORITY_IDLE); osSetThreadPri(NULL, OS_PRIORITY_IDLE);
while (1) { for (;;) {}
;
}
} }

View file

@ -5,18 +5,22 @@ OSPiHandle* sISVHandle; // official name : is_Handle
#define gISVDbgPrnAdrs ((ISVDbg*)0xB3FF0000) #define gISVDbgPrnAdrs ((ISVDbg*)0xB3FF0000)
#define ASCII_TO_U32(a, b, c, d) ((u32)((a << 24) | (b << 16) | (c << 8) | (d << 0))) #define ASCII_TO_U32(a, b, c, d) ((u32)((a << 24) | (b << 16) | (c << 8) | (d << 0)))
#if OOT_DEBUG
void isPrintfInit(void) { void isPrintfInit(void) {
sISVHandle = osCartRomInit(); sISVHandle = osCartRomInit();
osEPiWriteIo(sISVHandle, (u32)&gISVDbgPrnAdrs->put, 0); osEPiWriteIo(sISVHandle, (u32)&gISVDbgPrnAdrs->put, 0);
osEPiWriteIo(sISVHandle, (u32)&gISVDbgPrnAdrs->get, 0); osEPiWriteIo(sISVHandle, (u32)&gISVDbgPrnAdrs->get, 0);
osEPiWriteIo(sISVHandle, (u32)&gISVDbgPrnAdrs->magic, ASCII_TO_U32('I', 'S', '6', '4')); osEPiWriteIo(sISVHandle, (u32)&gISVDbgPrnAdrs->magic, ASCII_TO_U32('I', 'S', '6', '4'));
} }
#endif
void osSyncPrintfUnused(const char* fmt, ...) { void osSyncPrintfUnused(const char* fmt, ...) {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
#if OOT_DEBUG
_Printf(is_proutSyncPrintf, NULL, fmt, args); _Printf(is_proutSyncPrintf, NULL, fmt, args);
#endif
va_end(args); va_end(args);
} }
@ -25,7 +29,9 @@ void osSyncPrintf(const char* fmt, ...) {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
#if OOT_DEBUG
_Printf(is_proutSyncPrintf, NULL, fmt, args); _Printf(is_proutSyncPrintf, NULL, fmt, args);
#endif
va_end(args); va_end(args);
} }
@ -35,11 +41,14 @@ void rmonPrintf(const char* fmt, ...) {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
#if OOT_DEBUG
_Printf(is_proutSyncPrintf, NULL, fmt, args); _Printf(is_proutSyncPrintf, NULL, fmt, args);
#endif
va_end(args); va_end(args);
} }
#if OOT_DEBUG
void* is_proutSyncPrintf(void* arg, const char* str, size_t count) { void* is_proutSyncPrintf(void* arg, const char* str, size_t count) {
u32 data; u32 data;
s32 pos; s32 pos;
@ -92,3 +101,4 @@ NORETURN void func_80002384(const char* exp, const char* file, u32 line) {
; ;
} }
} }
#endif

View file

@ -1,6 +1,7 @@
#include "global.h" #include "global.h"
#include "terminal.h" #include "terminal.h"
#if OOT_DEBUG
f32 LogUtils_CheckFloatRange(const char* exp, s32 line, const char* valueName, f32 value, const char* minName, f32 min, f32 LogUtils_CheckFloatRange(const char* exp, s32 line, const char* valueName, f32 value, const char* minName, f32 min,
const char* maxName, f32 max) { const char* maxName, f32 max) {
if (value < min || max < value) { if (value < min || max < value) {
@ -99,9 +100,12 @@ void LogUtils_CheckValidPointer(const char* exp, void* ptr, const char* file, s3
void LogUtils_LogThreadId(const char* name, s32 line) { void LogUtils_LogThreadId(const char* name, s32 line) {
PRINTF("<%d %s %d>", osGetThreadId(NULL), name, line); PRINTF("<%d %s %d>", osGetThreadId(NULL), name, line);
} }
#endif
void LogUtils_HungupThread(const char* name, s32 line) { void LogUtils_HungupThread(const char* name, s32 line) {
PRINTF("*** HungUp in thread %d, [%s:%d] ***\n", osGetThreadId(NULL), name, line); OSId threadId = osGetThreadId(NULL);
PRINTF("*** HungUp in thread %d, [%s:%d] ***\n", threadId, name, line);
Fault_AddHungupAndCrash(name, line); Fault_AddHungupAndCrash(name, line);
} }

View file

@ -102,9 +102,11 @@ u32 StackCheck_GetState(StackEntry* entry) {
entry->name != NULL ? entry->name : "(null)"); entry->name != NULL ? entry->name : "(null)");
PRINTF(VT_RST); PRINTF(VT_RST);
#if OOT_DEBUG
if (ret != STACK_STATUS_OK) { if (ret != STACK_STATUS_OK) {
LogUtils_LogHexDump(entry->head, (uintptr_t)entry->tail - (uintptr_t)entry->head); LogUtils_LogHexDump(entry->head, (uintptr_t)entry->tail - (uintptr_t)entry->head);
} }
#endif
return ret; return ret;
} }

View file

@ -48,16 +48,18 @@ void* Yaz0_NextDMA(u8* curSrcPos) {
return dst; return dst;
} }
void Yaz0_DecompressImpl(Yaz0Header* hdr, u8* dst) { void Yaz0_DecompressImpl(u8* src, u8* dst) {
Yaz0Header* header = (Yaz0Header*)src;
u32 bitIdx = 0; u32 bitIdx = 0;
u8* src = hdr->data; u8* dstEnd = dst + header->decSize;
u8* dstEnd = dst + hdr->decSize;
u32 chunkHeader; u32 chunkHeader;
u32 nibble; u32 nibble;
u8* backPtr; u8* backPtr;
u32 chunkSize; u32 chunkSize;
u32 off; u32 off;
src += sizeof(Yaz0Header);
do { do {
if (bitIdx == 0) { if (bitIdx == 0) {
if ((sYaz0MaxPtr < src) && (sYaz0CurSize != 0)) { if ((sYaz0MaxPtr < src) && (sYaz0CurSize != 0)) {

View file

@ -33,6 +33,7 @@ void Locale_ResetRegion(void) {
gCurrentRegion = REGION_NULL; gCurrentRegion = REGION_NULL;
} }
#if OOT_DEBUG
u32 func_80001F48(void) { u32 func_80001F48(void) {
if (gCurrentRegion == REGION_NATIVE) { if (gCurrentRegion == REGION_NATIVE) {
return 0; return 0;
@ -61,3 +62,4 @@ u32 func_80001F8C(void) {
u32 Locale_IsRegionNative(void) { u32 Locale_IsRegionNative(void) {
return gCurrentRegion == REGION_NATIVE; return gCurrentRegion == REGION_NATIVE;
} }
#endif

View file

@ -36,12 +36,15 @@ u32 sDmaMgrIsRomCompressed = false;
// dmadata filenames // dmadata filenames
#define DEFINE_DMA_ENTRY(_0, nameString) nameString, #define DEFINE_DMA_ENTRY(_0, nameString) nameString,
#if OOT_DEBUG
const char* sDmaMgrFileNames[] = { const char* sDmaMgrFileNames[] = {
#include "tables/dmadata_table.h" #include "tables/dmadata_table.h"
}; };
#endif
#undef DEFINE_DMA_ENTRY #undef DEFINE_DMA_ENTRY
#if OOT_DEBUG
/** /**
* Compares `str1` and `str2`. * Compares `str1` and `str2`.
* *
@ -67,6 +70,7 @@ s32 DmaMgr_StrCmp(const char* str1, const char* str2) {
} }
return 0; return 0;
} }
#endif
/** /**
* Transfer `size` bytes from physical ROM address `rom` to `ram`. * Transfer `size` bytes from physical ROM address `rom` to `ram`.
@ -86,7 +90,6 @@ s32 DmaMgr_DmaRomToRam(uintptr_t rom, void* ram, size_t size) {
OSMesg msg; OSMesg msg;
s32 ret; s32 ret;
size_t buffSize = gDmaMgrDmaBuffSize; size_t buffSize = gDmaMgrDmaBuffSize;
s32 pad[2];
if (buffSize == 0) { if (buffSize == 0) {
buffSize = DMAMGR_DEFAULT_BUFSIZE; buffSize = DMAMGR_DEFAULT_BUFSIZE;
@ -132,7 +135,9 @@ s32 DmaMgr_DmaRomToRam(uintptr_t rom, void* ram, size_t size) {
ram = (u8*)ram + buffSize; ram = (u8*)ram + buffSize;
} }
if (1) {} // Also necessary to match if (1) { // Also necessary to match
s32 pad[2];
}
ioMsg.hdr.pri = OS_MESG_PRI_NORMAL; ioMsg.hdr.pri = OS_MESG_PRI_NORMAL;
ioMsg.hdr.retQueue = &queue; ioMsg.hdr.retQueue = &queue;
@ -219,17 +224,18 @@ void DmaMgr_DmaFromDriveRom(void* ram, uintptr_t rom, size_t size) {
osRecvMesg(&queue, NULL, OS_MESG_BLOCK); osRecvMesg(&queue, NULL, OS_MESG_BLOCK);
} }
#if OOT_DEBUG
/** /**
* DMA error encountered, print error messages and bring up the crash screen. * DMA error encountered, print error messages and bring up the crash screen.
* *
* @param req DMA Request causing the error. * @param req DMA Request causing the error.
* @param file DMA data filename associated with the operation that errored. * @param filename DMA data filename associated with the operation that errored.
* @param errorName Error name string. * @param errorName Error name string.
* @param errorDesc Error description string. * @param errorDesc Error description string.
* *
* This function does not return. * This function does not return.
*/ */
NORETURN void DmaMgr_Error(DmaRequest* req, const char* file, const char* errorName, const char* errorDesc) { NORETURN void DmaMgr_Error(DmaRequest* req, const char* filename, const char* errorName, const char* errorDesc) {
uintptr_t vrom = req->vromAddr; uintptr_t vrom = req->vromAddr;
void* ram = req->dramAddr; void* ram = req->dramAddr;
size_t size = req->size; size_t size = req->size;
@ -241,7 +247,7 @@ NORETURN void DmaMgr_Error(DmaRequest* req, const char* file, const char* errorN
// "DMA Fatal Error" // "DMA Fatal Error"
PRINTF("DMA致命的エラー(%s)\nROM:%X RAM:%X SIZE:%X %s\n", PRINTF("DMA致命的エラー(%s)\nROM:%X RAM:%X SIZE:%X %s\n",
errorDesc != NULL ? errorDesc : (errorName != NULL ? errorName : "???"), vrom, ram, size, errorDesc != NULL ? errorDesc : (errorName != NULL ? errorName : "???"), vrom, ram, size,
file != NULL ? file : "???"); filename != NULL ? filename : "???");
if (req->filename != NULL) { // Source file name that issued the DMA request if (req->filename != NULL) { // Source file name that issued the DMA request
PRINTF("DMA ERROR: %s %d", req->filename, req->line); PRINTF("DMA ERROR: %s %d", req->filename, req->line);
@ -259,10 +265,15 @@ NORETURN void DmaMgr_Error(DmaRequest* req, const char* file, const char* errorN
sprintf(buff1, "DMA ERROR: %s", errorName != NULL ? errorName : "???"); sprintf(buff1, "DMA ERROR: %s", errorName != NULL ? errorName : "???");
} }
sprintf(buff2, "%07X %08X %X %s", vrom, ram, size, file != NULL ? file : "???"); sprintf(buff2, "%07X %08X %X %s", vrom, ram, size, filename != NULL ? filename : "???");
Fault_AddHungupAndCrashImpl(buff1, buff2); Fault_AddHungupAndCrashImpl(buff1, buff2);
} }
#define DMA_ERROR(req, filename, errorName, errorDesc, file, line) DmaMgr_Error(req, filename, errorName, errorDesc)
#else
#define DMA_ERROR(req, filename, errorName, errorDesc, file, line) Fault_AddHungupAndCrash(file, line)
#endif
/** /**
* Searches the filesystem for the entry containing the address `vrom`. Retrieves the name of this entry from * Searches the filesystem for the entry containing the address `vrom`. Retrieves the name of this entry from
* the array of file names. * the array of file names.
@ -271,6 +282,7 @@ NORETURN void DmaMgr_Error(DmaRequest* req, const char* file, const char* errorN
* @return Pointer to associated filename * @return Pointer to associated filename
*/ */
const char* DmaMgr_FindFileName(uintptr_t vrom) { const char* DmaMgr_FindFileName(uintptr_t vrom) {
#if OOT_DEBUG
DmaEntry* iter = gDmaDataTable; DmaEntry* iter = gDmaDataTable;
const char** name = sDmaMgrFileNames; const char** name = sDmaMgrFileNames;
@ -287,9 +299,13 @@ const char* DmaMgr_FindFileName(uintptr_t vrom) {
#ifdef AVOID_UB #ifdef AVOID_UB
return ""; return "";
#endif #endif
#else
return NULL;
#endif
} }
const char* DmaMgr_GetFileName(uintptr_t vrom) { const char* DmaMgr_GetFileName(uintptr_t vrom) {
#if OOT_DEBUG
const char* ret = DmaMgr_FindFileName(vrom); const char* ret = DmaMgr_FindFileName(vrom);
if (ret == NULL) { if (ret == NULL) {
@ -302,6 +318,9 @@ const char* DmaMgr_GetFileName(uintptr_t vrom) {
return NULL; return NULL;
} }
return ret; return ret;
#else
return "";
#endif
} }
void DmaMgr_ProcessRequest(DmaRequest* req) { void DmaMgr_ProcessRequest(DmaRequest* req) {
@ -314,15 +333,13 @@ void DmaMgr_ProcessRequest(DmaRequest* req) {
DmaEntry* iter; DmaEntry* iter;
const char* filename; const char* filename;
if (0) { #if OOT_DEBUG
// The string is defined in .rodata but not used, suggesting a debug print is here but was optimized out in
// some way. The last arg of this print looks like it may be filename, but filename above this block does not
// match.
PRINTF("DMA ROM:%08X RAM:%08X SIZE:%08X %s\n");
}
// Get the filename (for debugging) // Get the filename (for debugging)
filename = DmaMgr_GetFileName(vrom); filename = DmaMgr_GetFileName(vrom);
#else
// An unused empty string is defined in .rodata of retail builds, suggesting it was used near here.
filename = "";
#endif
// Iterate through the DMA data table until the region containing the vrom address for this request is found // Iterate through the DMA data table until the region containing the vrom address for this request is found
iter = gDmaDataTable; iter = gDmaDataTable;
@ -330,7 +347,11 @@ void DmaMgr_ProcessRequest(DmaRequest* req) {
if (vrom >= iter->vromStart && vrom < iter->vromEnd) { if (vrom >= iter->vromStart && vrom < iter->vromEnd) {
// Found the region this request falls into // Found the region this request falls into
if (1) {} // Necessary to match if (0) {
// The string is defined in .rodata of debug builds but not used, suggesting a debug print is here
// but was optimized out in some way.
PRINTF("DMA ROM:%08X RAM:%08X SIZE:%08X %s\n", vrom, ram, size, filename);
}
if (iter->romEnd == 0) { if (iter->romEnd == 0) {
// romEnd of 0 indicates that the file is uncompressed. Files that are stored uncompressed can have // romEnd of 0 indicates that the file is uncompressed. Files that are stored uncompressed can have
@ -340,8 +361,8 @@ void DmaMgr_ProcessRequest(DmaRequest* req) {
// Error, vrom + size ends up in a different file than it started in // Error, vrom + size ends up in a different file than it started in
// "DMA transfers cannot cross segment boundaries" // "DMA transfers cannot cross segment boundaries"
DmaMgr_Error(req, filename, "Segment Alignment Error", DMA_ERROR(req, filename, "Segment Alignment Error",
"セグメント境界をまたがってDMA転送することはできません"); "セグメント境界をまたがってDMA転送することはできません", "../z_std_dma.c", 726);
} }
DmaMgr_DmaRomToRam(iter->romStart + (vrom - iter->vromStart), ram, size); DmaMgr_DmaRomToRam(iter->romStart + (vrom - iter->vromStart), ram, size);
@ -360,16 +381,16 @@ void DmaMgr_ProcessRequest(DmaRequest* req) {
// Error, requested vrom is not the start of a file // Error, requested vrom is not the start of a file
// "DMA transfer cannot be performed from the middle of a compressed segment" // "DMA transfer cannot be performed from the middle of a compressed segment"
DmaMgr_Error(req, filename, "Can't Transfer Segment", DMA_ERROR(req, filename, "Can't Transfer Segment",
"圧縮されたセグメントの途中からはDMA転送することはできません"); "圧縮されたセグメントの途中からはDMA転送することはできません", "../z_std_dma.c", 746);
} }
if (size != iter->vromEnd - iter->vromStart) { if (size != iter->vromEnd - iter->vromStart) {
// Error, only part of the file was requested // Error, only part of the file was requested
// "It is not possible to DMA only part of a compressed segment" // "It is not possible to DMA only part of a compressed segment"
DmaMgr_Error(req, filename, "Can't Transfer Segment", DMA_ERROR(req, filename, "Can't Transfer Segment",
"圧縮されたセグメントの一部だけをDMA転送することはできません"); "圧縮されたセグメントの一部だけをDMA転送することはできません", "../z_std_dma.c", 752);
} }
// Reduce the thread priority and decompress the file, the decompression routine handles the DMA // Reduce the thread priority and decompress the file, the decompression routine handles the DMA
@ -395,7 +416,7 @@ void DmaMgr_ProcessRequest(DmaRequest* req) {
// Error, rom is compressed so DMA may only be requested within the filesystem bounds // Error, rom is compressed so DMA may only be requested within the filesystem bounds
// "Corresponding data does not exist" // "Corresponding data does not exist"
DmaMgr_Error(req, NULL, "DATA DON'T EXIST", "該当するデータが存在しません"); DMA_ERROR(req, NULL, "DATA DON'T EXIST", "該当するデータが存在しません", "../z_std_dma.c", 771);
return; return;
} else { } else {
// ROM is uncompressed, allow arbitrary DMA even if the region is not marked in the filesystem // ROM is uncompressed, allow arbitrary DMA even if the region is not marked in the filesystem
@ -460,11 +481,15 @@ s32 DmaMgr_RequestAsync(DmaRequest* req, void* ram, uintptr_t vrom, size_t size,
OSMesg msg) { OSMesg msg) {
static s32 sDmaMgrQueueFullLogged = 0; static s32 sDmaMgrQueueFullLogged = 0;
if ((1 && (ram == NULL)) || (osMemSize < OS_K0_TO_PHYSICAL(ram) + size) || (vrom & 1) || (vrom > 0x4000000) || #if OOT_DEBUG
if ((ram == NULL) || (osMemSize < OS_K0_TO_PHYSICAL(ram) + size) || (vrom & 1) || (vrom > 0x4000000) ||
(size == 0) || (size & 1)) { (size == 0) || (size & 1)) {
//! @bug `req` is passed to `DmaMgr_Error` without rom, ram and size being set // The line numbers for `DMA_ERROR` are only used in retail builds, but this usage was removed so
DmaMgr_Error(req, NULL, "ILLIGAL DMA-FUNCTION CALL", "パラメータ異常です"); // its line number is unknown.
//! @bug `req` is passed to `DMA_ERROR` without rom, ram and size being set
DMA_ERROR(req, NULL, "ILLIGAL DMA-FUNCTION CALL", "パラメータ異常です", "../z_std_dma.c", 0);
} }
#endif
req->vromAddr = vrom; req->vromAddr = vrom;
req->dramAddr = ram; req->dramAddr = ram;
@ -473,6 +498,7 @@ s32 DmaMgr_RequestAsync(DmaRequest* req, void* ram, uintptr_t vrom, size_t size,
req->notifyQueue = queue; req->notifyQueue = queue;
req->notifyMsg = msg; req->notifyMsg = msg;
#if OOT_DEBUG
if (1 && (sDmaMgrQueueFullLogged == 0) && MQ_IS_FULL(&sDmaMgrMsgQueue)) { if (1 && (sDmaMgrQueueFullLogged == 0) && MQ_IS_FULL(&sDmaMgrMsgQueue)) {
sDmaMgrQueueFullLogged++; sDmaMgrQueueFullLogged++;
PRINTF("%c", BEL); PRINTF("%c", BEL);
@ -483,6 +509,7 @@ s32 DmaMgr_RequestAsync(DmaRequest* req, void* ram, uintptr_t vrom, size_t size,
952); 952);
PRINTF(VT_RST); PRINTF(VT_RST);
} }
#endif
osSendMesg(&sDmaMgrMsgQueue, (OSMesg)req, OS_MESG_BLOCK); osSendMesg(&sDmaMgrMsgQueue, (OSMesg)req, OS_MESG_BLOCK);
return 0; return 0;
@ -523,12 +550,13 @@ void DmaMgr_Init(void) {
(u32)(_dmadataSegmentRomEnd - _dmadataSegmentRomStart)); (u32)(_dmadataSegmentRomEnd - _dmadataSegmentRomStart));
PRINTF("dma_rom_ad[]\n"); PRINTF("dma_rom_ad[]\n");
sDmaMgrIsRomCompressed = false; #if OOT_DEBUG
name = sDmaMgrFileNames; name = sDmaMgrFileNames;
iter = gDmaDataTable; iter = gDmaDataTable;
idx = 0; idx = 0;
// Check if the ROM is compressed (romEnd not 0) // Check if the ROM is compressed (romEnd not 0)
sDmaMgrIsRomCompressed = false;
while (iter->vromEnd != 0) { while (iter->vromEnd != 0) {
if (iter->romEnd != 0) { if (iter->romEnd != 0) {
sDmaMgrIsRomCompressed = true; sDmaMgrIsRomCompressed = true;
@ -545,6 +573,7 @@ void DmaMgr_Init(void) {
name++; name++;
} }
} }
#endif
// Ensure that the boot segment always follows after the makerom segment. // Ensure that the boot segment always follows after the makerom segment.
if ((uintptr_t)_bootSegmentRomStart != gDmaDataTable[0].vromEnd) { if ((uintptr_t)_bootSegmentRomStart != gDmaDataTable[0].vromEnd) {
@ -562,6 +591,7 @@ void DmaMgr_Init(void) {
osStartThread(&sDmaMgrThread); osStartThread(&sDmaMgrThread);
} }
#if OOT_DEBUG
/** /**
* Asynchronous DMA Request with source file and line info for debugging. * Asynchronous DMA Request with source file and line info for debugging.
* *
@ -597,3 +627,4 @@ s32 DmaMgr_RequestSyncDebug(void* ram, uintptr_t vrom, size_t size, const char*
osRecvMesg(&queue, NULL, OS_MESG_BLOCK); osRecvMesg(&queue, NULL, OS_MESG_BLOCK);
return 0; return 0;
} }
#endif

View file

@ -95,8 +95,8 @@ void PreRender_CopyImage(PreRender* this, Gfx** gfxP, void* img, void* imgDst) {
gSPTextureRectangle(gfx++, uls << 2, ult << 2, lrs << 2, lrt << 2, G_TX_RENDERTILE, uls << 5, ult << 5, 4 << 10, gSPTextureRectangle(gfx++, uls << 2, ult << 2, lrs << 2, lrt << 2, G_TX_RENDERTILE, uls << 5, ult << 5, 4 << 10,
1 << 10); 1 << 10);
rowsRemaining -= nRows;
curRow += nRows; curRow += nRows;
rowsRemaining -= nRows;
} }
gDPPipeSync(gfx++); gDPPipeSync(gfx++);
@ -140,7 +140,9 @@ void PreRender_CopyImageRegionImpl(PreRender* this, Gfx** gfxP) {
s32 uly; s32 uly;
// Make sure that we don't load past the end of the source image // Make sure that we don't load past the end of the source image
nRows = MIN(rowsRemaining, nRows); if (nRows > rowsRemaining) {
nRows = rowsRemaining;
}
// Determine the upper and lower bounds of the rect to draw // Determine the upper and lower bounds of the rect to draw
ult = this->ulySave + curRow; ult = this->ulySave + curRow;
@ -156,8 +158,8 @@ void PreRender_CopyImageRegionImpl(PreRender* this, Gfx** gfxP) {
gSPTextureRectangle(gfx++, this->ulx << 2, uly << 2, this->lrx << 2, (uly + nRows - 1) << 2, G_TX_RENDERTILE, gSPTextureRectangle(gfx++, this->ulx << 2, uly << 2, this->lrx << 2, (uly + nRows - 1) << 2, G_TX_RENDERTILE,
this->ulxSave << 5, ult << 5, 4 << 10, 1 << 10); this->ulxSave << 5, ult << 5, 4 << 10, 1 << 10);
rowsRemaining -= nRows;
curRow += nRows; curRow += nRows;
rowsRemaining -= nRows;
} }
// Reset the color image and scissor // Reset the color image and scissor
@ -226,8 +228,8 @@ void func_800C170C(PreRender* this, Gfx** gfxP, void* buf, void* bufSave, u32 r,
gSPTextureRectangle(gfx++, uls << 2, ult << 2, (lrs + 1) << 2, (lrt + 1) << 2, G_TX_RENDERTILE, uls << 5, gSPTextureRectangle(gfx++, uls << 2, ult << 2, (lrs + 1) << 2, (lrt + 1) << 2, G_TX_RENDERTILE, uls << 5,
ult << 5, 1 << 10, 1 << 10); ult << 5, 1 << 10, 1 << 10);
rowsRemaining -= nRows;
curRow += nRows; curRow += nRows;
rowsRemaining -= nRows;
} }
gDPPipeSync(gfx++); gDPPipeSync(gfx++);
@ -287,7 +289,9 @@ void PreRender_CoverageRgba16ToI8(PreRender* this, Gfx** gfxP, void* img, void*
s32 lrt; s32 lrt;
// Make sure that we don't load past the end of the source image // Make sure that we don't load past the end of the source image
nRows = MIN(rowsRemaining, nRows); if (nRows > rowsRemaining) {
nRows = rowsRemaining;
}
// Determine the upper and lower bounds of the rect to draw // Determine the upper and lower bounds of the rect to draw
ult = curRow; ult = curRow;
@ -319,8 +323,8 @@ void PreRender_CoverageRgba16ToI8(PreRender* this, Gfx** gfxP, void* img, void*
ult << 5, 1 << 10, 1 << 10); ult << 5, 1 << 10, 1 << 10);
// Update the number of rows remaining and index of the row being drawn // Update the number of rows remaining and index of the row being drawn
rowsRemaining -= nRows;
curRow += nRows; curRow += nRows;
rowsRemaining -= nRows;
} }
// Reset the color image to the current framebuffer // Reset the color image to the current framebuffer
@ -477,8 +481,8 @@ void func_800C213C(PreRender* this, Gfx** gfxP) {
gSPTextureRectangle(gfx++, uls << 2, ult << 2, (lrs + 1) << 2, (lrt + 1) << 2, G_TX_RENDERTILE, uls << 5, gSPTextureRectangle(gfx++, uls << 2, ult << 2, (lrs + 1) << 2, (lrt + 1) << 2, G_TX_RENDERTILE, uls << 5,
ult << 5, 1 << 10, 1 << 10); ult << 5, 1 << 10, 1 << 10);
rowsRemaining -= nRows;
curRow += nRows; curRow += nRows;
rowsRemaining -= nRows;
} }
gDPPipeSync(gfx++); gDPPipeSync(gfx++);
@ -545,7 +549,7 @@ void PreRender_AntiAliasFilter(PreRender* this, s32 x, s32 y) {
s32 buffB[5 * 3]; s32 buffB[5 * 3];
s32 xi; s32 xi;
s32 yi; s32 yi;
s32 pad; s32 invCvg;
s32 pmaxR; s32 pmaxR;
s32 pmaxG; s32 pmaxG;
s32 pmaxB; s32 pmaxB;
@ -583,10 +587,12 @@ void PreRender_AntiAliasFilter(PreRender* this, s32 x, s32 y) {
buffCvg[i] = this->cvgSave[xi + yi * this->width] >> 5; buffCvg[i] = this->cvgSave[xi + yi * this->width] >> 5;
} }
#if OOT_DEBUG
if (buffCvg[7] == 7) { if (buffCvg[7] == 7) {
PRINTF("Error, should not be in here \n"); PRINTF("Error, should not be in here \n");
return; return;
} }
#endif
pmaxR = pminR = buffR[7]; pmaxR = pminR = buffR[7];
pmaxG = pminG = buffG[7]; pmaxG = pminG = buffG[7];
@ -658,9 +664,10 @@ void PreRender_AntiAliasFilter(PreRender* this, s32 x, s32 y) {
// BackGround = (pMax + pMin) - (ForeGround) * 2 // BackGround = (pMax + pMin) - (ForeGround) * 2
// OutputColor = cvg * ForeGround + (1.0 - cvg) * BackGround // OutputColor = cvg * ForeGround + (1.0 - cvg) * BackGround
outR = buffR[7] + ((s32)((7 - buffCvg[7]) * (pmaxR + pminR - (buffR[7] * 2)) + 4) >> 3); invCvg = 7 - buffCvg[7];
outG = buffG[7] + ((s32)((7 - buffCvg[7]) * (pmaxG + pminG - (buffG[7] * 2)) + 4) >> 3); outR = buffR[7] + ((s32)(invCvg * (pmaxR + pminR - (buffR[7] * 2)) + 4) >> 3);
outB = buffB[7] + ((s32)((7 - buffCvg[7]) * (pmaxB + pminB - (buffB[7] * 2)) + 4) >> 3); outG = buffG[7] + ((s32)(invCvg * (pmaxG + pminG - (buffG[7] * 2)) + 4) >> 3);
outB = buffB[7] + ((s32)(invCvg * (pmaxB + pminB - (buffB[7] * 2)) + 4) >> 3);
pxOut.r = outR >> 3; pxOut.r = outR >> 3;
pxOut.g = outG >> 3; pxOut.g = outG >> 3;
@ -796,9 +803,11 @@ void PreRender_ApplyFilters(PreRender* this) {
} }
} }
#if OOT_DEBUG
if ((R_HREG_MODE == HREG_MODE_PRERENDER ? R_PRERENDER_DIVOT_CONTROL : 0) != 0) { if ((R_HREG_MODE == HREG_MODE_PRERENDER ? R_PRERENDER_DIVOT_CONTROL : 0) != 0) {
// Apply divot filter // Apply divot filter
PreRender_DivotFilter(this); PreRender_DivotFilter(this);
} }
#endif
} }
} }

View file

@ -1,9 +1,9 @@
#include "global.h" #include "global.h"
#include "terminal.h" #include "terminal.h"
#define FILL_ALLOCBLOCK (1 << 0) #define FILL_ALLOC_BLOCK_FLAG (1 << 0)
#define FILL_FREEBLOCK (1 << 1) #define FILL_FREE_BLOCK_FLAG (1 << 1)
#define CHECK_FREE_BLOCK (1 << 2) #define CHECK_FREE_BLOCK_FLAG (1 << 2)
#define NODE_MAGIC (0x7373) #define NODE_MAGIC (0x7373)
@ -14,37 +14,90 @@
#define BLOCK_FREE_MAGIC (0xEF) #define BLOCK_FREE_MAGIC (0xEF)
#define BLOCK_FREE_MAGIC_32 (0xEFEFEFEF) #define BLOCK_FREE_MAGIC_32 (0xEFEFEFEF)
#define NODE_IS_VALID(node) (((node) != NULL) && ((node)->magic == NODE_MAGIC))
#if OOT_DEBUG
#define NODE_GET_NEXT(node) ArenaImpl_GetNextBlock(node)
#define NODE_GET_PREV(node) ArenaImpl_GetPrevBlock(node)
#define SET_DEBUG_INFO(node, file, line, arena) ArenaImpl_SetDebugInfo(node, file, line, arena)
#define FILL_ALLOC_BLOCK(arena, alloc, size) \
if ((arena)->flag & FILL_ALLOC_BLOCK_FLAG) \
__osMemset(alloc, BLOCK_ALLOC_MAGIC, size)
#define FILL_FREE_BLOCK_HEADER(arena, node) \
if ((arena)->flag & FILL_FREE_BLOCK_FLAG) \
__osMemset(node, BLOCK_FREE_MAGIC, sizeof(ArenaNode))
#define FILL_FREE_BLOCK_CONTENTS(arena, node) \
if ((arena)->flag & FILL_FREE_BLOCK_FLAG) \
__osMemset((void*)((u32)(node) + sizeof(ArenaNode)), BLOCK_FREE_MAGIC, (node)->size)
#define CHECK_FREE_BLOCK(arena, node) \
if ((arena)->flag & CHECK_FREE_BLOCK_FLAG) \
__osMalloc_FreeBlockTest(arena, node)
#define CHECK_ALLOC_FAILURE(arena, ptr) (void)0
#else
#define NODE_GET_NEXT(node) (NODE_IS_VALID((node)->next) ? (node)->next : NULL)
#define NODE_GET_PREV(node) (NODE_IS_VALID((node)->prev) ? (node)->prev : NULL)
#define SET_DEBUG_INFO(node, file, line, arena) (void)0
#define FILL_ALLOC_BLOCK(arena, alloc, size) (void)0
#define FILL_FREE_BLOCK_HEADER(arena, node) (void)0
#define FILL_FREE_BLOCK_CONTENTS(arena, node) (void)0
#define CHECK_FREE_BLOCK(arena, node) (void)0
// Number of allocation failures across all arenas.
u32 sTotalAllocFailures = 0;
#define CHECK_ALLOC_FAILURE(arena, ptr) \
do { \
if ((ptr) == NULL) { \
sTotalAllocFailures++; \
(arena)->allocFailures++; \
} \
} while (0)
#endif
OSMesg sArenaLockMsg; OSMesg sArenaLockMsg;
#if OOT_DEBUG
u32 __osMalloc_FreeBlockTest_Enable; u32 __osMalloc_FreeBlockTest_Enable;
u32 ArenaImpl_GetFillAllocBlock(Arena* arena) { u32 ArenaImpl_GetFillAllocBlock(Arena* arena) {
return (arena->flag & FILL_ALLOCBLOCK) != 0; return (arena->flag & FILL_ALLOC_BLOCK_FLAG) != 0;
} }
u32 ArenaImpl_GetFillFreeBlock(Arena* arena) { u32 ArenaImpl_GetFillFreeBlock(Arena* arena) {
return (arena->flag & FILL_FREEBLOCK) != 0; return (arena->flag & FILL_FREE_BLOCK_FLAG) != 0;
} }
u32 ArenaImpl_GetCheckFreeBlock(Arena* arena) { u32 ArenaImpl_GetCheckFreeBlock(Arena* arena) {
return (arena->flag & CHECK_FREE_BLOCK) != 0; return (arena->flag & CHECK_FREE_BLOCK_FLAG) != 0;
} }
void ArenaImpl_SetFillAllocBlock(Arena* arena) { void ArenaImpl_SetFillAllocBlock(Arena* arena) {
arena->flag |= FILL_ALLOCBLOCK; arena->flag |= FILL_ALLOC_BLOCK_FLAG;
} }
void ArenaImpl_SetFillFreeBlock(Arena* arena) { void ArenaImpl_SetFillFreeBlock(Arena* arena) {
arena->flag |= FILL_FREEBLOCK; arena->flag |= FILL_FREE_BLOCK_FLAG;
} }
void ArenaImpl_SetCheckFreeBlock(Arena* arena) { void ArenaImpl_SetCheckFreeBlock(Arena* arena) {
arena->flag |= CHECK_FREE_BLOCK; arena->flag |= CHECK_FREE_BLOCK_FLAG;
} }
void ArenaImpl_UnsetFillAllocBlock(Arena* arena) { void ArenaImpl_UnsetFillAllocBlock(Arena* arena) {
arena->flag &= ~FILL_ALLOCBLOCK; arena->flag &= ~FILL_ALLOC_BLOCK_FLAG;
} }
void ArenaImpl_UnsetFillFreeBlock(Arena* arena) { void ArenaImpl_UnsetFillFreeBlock(Arena* arena) {
arena->flag &= ~FILL_FREEBLOCK; arena->flag &= ~FILL_FREE_BLOCK_FLAG;
} }
void ArenaImpl_UnsetCheckFreeBlock(Arena* arena) { void ArenaImpl_UnsetCheckFreeBlock(Arena* arena) {
arena->flag &= ~CHECK_FREE_BLOCK; arena->flag &= ~CHECK_FREE_BLOCK_FLAG;
} }
void ArenaImpl_SetDebugInfo(ArenaNode* node, const char* file, s32 line, Arena* arena) { void ArenaImpl_SetDebugInfo(ArenaNode* node, const char* file, s32 line, Arena* arena) {
@ -54,6 +107,7 @@ void ArenaImpl_SetDebugInfo(ArenaNode* node, const char* file, s32 line, Arena*
node->arena = arena; node->arena = arena;
node->time = osGetTime(); node->time = osGetTime();
} }
#endif
void ArenaImpl_LockInit(Arena* arena) { void ArenaImpl_LockInit(Arena* arena) {
osCreateMesgQueue(&arena->lockQueue, &sArenaLockMsg, 1); osCreateMesgQueue(&arena->lockQueue, &sArenaLockMsg, 1);
@ -67,6 +121,7 @@ void ArenaImpl_Unlock(Arena* arena) {
osRecvMesg(&arena->lockQueue, NULL, OS_MESG_BLOCK); osRecvMesg(&arena->lockQueue, NULL, OS_MESG_BLOCK);
} }
#if OOT_DEBUG
ArenaNode* ArenaImpl_GetNextBlock(ArenaNode* node) { ArenaNode* ArenaImpl_GetNextBlock(ArenaNode* node) {
ArenaNode* next = node->next; ArenaNode* next = node->next;
@ -88,16 +143,17 @@ ArenaNode* ArenaImpl_GetPrevBlock(ArenaNode* node) {
} }
return prev; return prev;
} }
#endif
ArenaNode* ArenaImpl_GetLastBlock(Arena* arena) { ArenaNode* ArenaImpl_GetLastBlock(Arena* arena) {
ArenaNode* last = NULL; ArenaNode* last = NULL;
ArenaNode* iter; ArenaNode* iter;
if (arena != NULL && arena->head != NULL && arena->head->magic == NODE_MAGIC) { if (arena != NULL && NODE_IS_VALID(arena->head)) {
iter = arena->head; iter = arena->head;
while (iter != NULL) { while (iter != NULL) {
last = iter; last = iter;
iter = ArenaImpl_GetNextBlock(iter); iter = NODE_GET_NEXT(last);
} }
} }
return last; return last;
@ -122,7 +178,9 @@ void __osMallocAddBlock(Arena* arena, void* start, s32 size) {
size2 = (size - diff) & ~0xF; size2 = (size - diff) & ~0xF;
if (size2 > (s32)sizeof(ArenaNode)) { if (size2 > (s32)sizeof(ArenaNode)) {
#if OOT_DEBUG
__osMemset(firstNode, BLOCK_UNINIT_MAGIC, size2); __osMemset(firstNode, BLOCK_UNINIT_MAGIC, size2);
#endif
firstNode->next = NULL; firstNode->next = NULL;
firstNode->prev = NULL; firstNode->prev = NULL;
firstNode->size = size2 - sizeof(ArenaNode); firstNode->size = size2 - sizeof(ArenaNode);
@ -142,6 +200,7 @@ void __osMallocAddBlock(Arena* arena, void* start, s32 size) {
} }
} }
#if OOT_DEBUG
void ArenaImpl_RemoveAllBlocks(Arena* arena) { void ArenaImpl_RemoveAllBlocks(Arena* arena) {
ArenaNode* iter; ArenaNode* iter;
ArenaNode* next; ArenaNode* next;
@ -150,16 +209,19 @@ void ArenaImpl_RemoveAllBlocks(Arena* arena) {
iter = arena->head; iter = arena->head;
while (iter != NULL) { while (iter != NULL) {
next = ArenaImpl_GetNextBlock(iter); next = NODE_GET_NEXT(iter);
__osMemset(iter, BLOCK_UNINIT_MAGIC, iter->size + sizeof(ArenaNode)); __osMemset(iter, BLOCK_UNINIT_MAGIC, iter->size + sizeof(ArenaNode));
iter = next; iter = next;
} }
ArenaImpl_Unlock(arena); ArenaImpl_Unlock(arena);
} }
#endif
void __osMallocCleanup(Arena* arena) { void __osMallocCleanup(Arena* arena) {
#if OOT_DEBUG
ArenaImpl_RemoveAllBlocks(arena); ArenaImpl_RemoveAllBlocks(arena);
#endif
bzero(arena, sizeof(*arena)); bzero(arena, sizeof(*arena));
} }
@ -167,6 +229,7 @@ u8 __osMallocIsInitialized(Arena* arena) {
return arena->isInit; return arena->isInit;
} }
#if OOT_DEBUG
void __osMalloc_FreeBlockTest(Arena* arena, ArenaNode* node) { void __osMalloc_FreeBlockTest(Arena* arena, ArenaNode* node) {
ArenaNode* node2 = node; ArenaNode* node2 = node;
u32* start; u32* start;
@ -204,13 +267,11 @@ void* __osMalloc_NoLockDebug(Arena* arena, u32 size, const char* file, s32 line)
while (iter != NULL) { while (iter != NULL) {
if (iter->isFree && iter->size >= size) { if (iter->isFree && iter->size >= size) {
if (arena->flag & CHECK_FREE_BLOCK) { CHECK_FREE_BLOCK(arena, iter);
__osMalloc_FreeBlockTest(arena, iter);
}
if (blockSize < iter->size) { if (blockSize < iter->size) {
newNode = (ArenaNode*)((u32)iter + blockSize); newNode = (ArenaNode*)((u32)iter + blockSize);
newNode->next = ArenaImpl_GetNextBlock(iter); newNode->next = NODE_GET_NEXT(iter);
newNode->prev = iter; newNode->prev = iter;
newNode->size = iter->size - blockSize; newNode->size = iter->size - blockSize;
newNode->isFree = true; newNode->isFree = true;
@ -218,23 +279,21 @@ void* __osMalloc_NoLockDebug(Arena* arena, u32 size, const char* file, s32 line)
iter->next = newNode; iter->next = newNode;
iter->size = size; iter->size = size;
next = ArenaImpl_GetNextBlock(newNode); next = NODE_GET_NEXT(newNode);
if (next) { if (next) {
next->prev = newNode; next->prev = newNode;
} }
} }
iter->isFree = false; iter->isFree = false;
ArenaImpl_SetDebugInfo(iter, file, line, arena); SET_DEBUG_INFO(iter, file, line, arena);
alloc = (void*)((u32)iter + sizeof(ArenaNode)); alloc = (void*)((u32)iter + sizeof(ArenaNode));
if (arena->flag & FILL_ALLOCBLOCK) { FILL_ALLOC_BLOCK(arena, alloc, size);
__osMemset(alloc, BLOCK_ALLOC_MAGIC, size);
}
break; break;
} }
iter = ArenaImpl_GetNextBlock(iter); iter = NODE_GET_NEXT(iter);
} }
return alloc; return alloc;
@ -263,21 +322,19 @@ void* __osMallocRDebug(Arena* arena, u32 size, const char* file, s32 line) {
while (iter != NULL) { while (iter != NULL) {
if (iter->isFree && iter->size >= size) { if (iter->isFree && iter->size >= size) {
if (arena->flag & CHECK_FREE_BLOCK) { CHECK_FREE_BLOCK(arena, iter);
__osMalloc_FreeBlockTest(arena, iter);
}
blockSize = ALIGN16(size) + sizeof(ArenaNode); blockSize = ALIGN16(size) + sizeof(ArenaNode);
if (blockSize < iter->size) { if (blockSize < iter->size) {
newNode = (ArenaNode*)((u32)iter + (iter->size - size)); newNode = (ArenaNode*)((u32)iter + (iter->size - size));
newNode->next = ArenaImpl_GetNextBlock(iter); newNode->next = NODE_GET_NEXT(iter);
newNode->prev = iter; newNode->prev = iter;
newNode->size = size; newNode->size = size;
newNode->magic = NODE_MAGIC; newNode->magic = NODE_MAGIC;
iter->next = newNode; iter->next = newNode;
iter->size -= blockSize; iter->size -= blockSize;
next = ArenaImpl_GetNextBlock(newNode); next = NODE_GET_NEXT(newNode);
if (next) { if (next) {
next->prev = newNode; next->prev = newNode;
} }
@ -285,21 +342,20 @@ void* __osMallocRDebug(Arena* arena, u32 size, const char* file, s32 line) {
} }
iter->isFree = false; iter->isFree = false;
ArenaImpl_SetDebugInfo(iter, file, line, arena); SET_DEBUG_INFO(iter, file, line, arena);
allocR = (void*)((u32)iter + sizeof(ArenaNode)); allocR = (void*)((u32)iter + sizeof(ArenaNode));
if (arena->flag & FILL_ALLOCBLOCK) { FILL_ALLOC_BLOCK(arena, allocR, size);
__osMemset(allocR, BLOCK_ALLOC_MAGIC, size);
}
break; break;
} }
iter = ArenaImpl_GetPrevBlock(iter); iter = NODE_GET_PREV(iter);
} }
ArenaImpl_Unlock(arena); ArenaImpl_Unlock(arena);
return allocR; return allocR;
} }
#endif
void* __osMalloc_NoLock(Arena* arena, u32 size) { void* __osMalloc_NoLock(Arena* arena, u32 size) {
ArenaNode* iter; ArenaNode* iter;
@ -308,20 +364,17 @@ void* __osMalloc_NoLock(Arena* arena, u32 size) {
void* alloc = NULL; void* alloc = NULL;
ArenaNode* next; ArenaNode* next;
iter = arena->head;
size = ALIGN16(size); size = ALIGN16(size);
blockSize = ALIGN16(size) + sizeof(ArenaNode); blockSize = ALIGN16(size) + sizeof(ArenaNode);
iter = arena->head;
while (iter != NULL) { while (iter != NULL) {
if (iter->isFree && iter->size >= size) { if (iter->isFree && iter->size >= size) {
if (arena->flag & CHECK_FREE_BLOCK) { CHECK_FREE_BLOCK(arena, iter);
__osMalloc_FreeBlockTest(arena, iter);
}
if (blockSize < iter->size) { if (blockSize < iter->size) {
newNode = (ArenaNode*)((u32)iter + blockSize); newNode = (ArenaNode*)((u32)iter + blockSize);
newNode->next = ArenaImpl_GetNextBlock(iter); newNode->next = NODE_GET_NEXT(iter);
newNode->prev = iter; newNode->prev = iter;
newNode->size = iter->size - blockSize; newNode->size = iter->size - blockSize;
newNode->isFree = true; newNode->isFree = true;
@ -329,24 +382,24 @@ void* __osMalloc_NoLock(Arena* arena, u32 size) {
iter->next = newNode; iter->next = newNode;
iter->size = size; iter->size = size;
next = ArenaImpl_GetNextBlock(newNode); next = NODE_GET_NEXT(newNode);
if (next) { if (next) {
next->prev = newNode; next->prev = newNode;
} }
} }
iter->isFree = false; iter->isFree = false;
ArenaImpl_SetDebugInfo(iter, NULL, 0, arena); SET_DEBUG_INFO(iter, NULL, 0, arena);
alloc = (void*)((u32)iter + sizeof(ArenaNode)); alloc = (void*)((u32)iter + sizeof(ArenaNode));
if (arena->flag & FILL_ALLOCBLOCK) { FILL_ALLOC_BLOCK(arena, alloc, size);
__osMemset(alloc, BLOCK_ALLOC_MAGIC, size);
}
break; break;
} }
iter = ArenaImpl_GetNextBlock(iter); iter = NODE_GET_NEXT(iter);
} }
CHECK_ALLOC_FAILURE(arena, alloc);
return alloc; return alloc;
} }
@ -362,32 +415,33 @@ void* __osMalloc(Arena* arena, u32 size) {
void* __osMallocR(Arena* arena, u32 size) { void* __osMallocR(Arena* arena, u32 size) {
ArenaNode* iter; ArenaNode* iter;
ArenaNode* allocNode;
ArenaNode* newNode; ArenaNode* newNode;
u32 blockSize;
ArenaNode* next; ArenaNode* next;
void* alloc = NULL; void* alloc = NULL;
u32 blockSize;
size = ALIGN16(size); size = ALIGN16(size);
blockSize = ALIGN16(size) + sizeof(ArenaNode);
ArenaImpl_Lock(arena); ArenaImpl_Lock(arena);
iter = ArenaImpl_GetLastBlock(arena); iter = ArenaImpl_GetLastBlock(arena);
while (iter != NULL) { while (iter != NULL) {
if (iter->isFree && iter->size >= size) { if (iter->isFree && iter->size >= size) {
if (arena->flag & CHECK_FREE_BLOCK) { CHECK_FREE_BLOCK(arena, iter);
__osMalloc_FreeBlockTest(arena, iter);
}
blockSize = ALIGN16(size) + sizeof(ArenaNode);
if (blockSize < iter->size) { if (blockSize < iter->size) {
newNode = (ArenaNode*)((u32)iter + (iter->size - size)); allocNode = (ArenaNode*)((u32)iter + (iter->size - size));
newNode->next = ArenaImpl_GetNextBlock(iter); allocNode->next = NODE_GET_NEXT(iter);
newNode = allocNode;
newNode->prev = iter; newNode->prev = iter;
newNode->size = size; newNode->size = size;
newNode->magic = NODE_MAGIC; newNode->magic = NODE_MAGIC;
iter->next = newNode; iter->next = newNode;
iter->size -= blockSize; iter->size -= blockSize;
next = ArenaImpl_GetNextBlock(newNode); next = NODE_GET_NEXT(newNode);
if (next) { if (next) {
next->prev = newNode; next->prev = newNode;
} }
@ -395,15 +449,16 @@ void* __osMallocR(Arena* arena, u32 size) {
} }
iter->isFree = false; iter->isFree = false;
ArenaImpl_SetDebugInfo(iter, NULL, 0, arena); SET_DEBUG_INFO(iter, NULL, 0, arena);
alloc = (void*)((u32)iter + sizeof(ArenaNode)); alloc = (void*)((u32)iter + sizeof(ArenaNode));
if (arena->flag & FILL_ALLOCBLOCK) { FILL_ALLOC_BLOCK(arena, alloc, size);
__osMemset(alloc, BLOCK_ALLOC_MAGIC, size);
}
break; break;
} }
iter = ArenaImpl_GetPrevBlock(iter); iter = NODE_GET_PREV(iter);
} }
CHECK_ALLOC_FAILURE(arena, alloc);
ArenaImpl_Unlock(arena); ArenaImpl_Unlock(arena);
return alloc; return alloc;
@ -413,7 +468,6 @@ void __osFree_NoLock(Arena* arena, void* ptr) {
ArenaNode* node; ArenaNode* node;
ArenaNode* next; ArenaNode* next;
ArenaNode* prev; ArenaNode* prev;
ArenaNode* newNext;
if (ptr == NULL) { if (ptr == NULL) {
return; return;
@ -422,40 +476,37 @@ void __osFree_NoLock(Arena* arena, void* ptr) {
node = (ArenaNode*)((u32)ptr - sizeof(ArenaNode)); node = (ArenaNode*)((u32)ptr - sizeof(ArenaNode));
if (node == NULL || node->magic != NODE_MAGIC) { if (node == NULL || node->magic != NODE_MAGIC) {
// "__osFree: Unauthorized release (%08x)" // "__osFree: Unauthorized release (%08x)"
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:不正解放(%08x)\n" VT_RST, ptr); PRINTF(VT_COL(RED, WHITE) "__osFree:不正解放(%08x)\n" VT_RST, ptr);
return; return;
} }
if (node->isFree) { if (node->isFree) {
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:二重解放(%08x)\n" VT_RST, ptr); // "__osFree: Double release (%08x)" PRINTF(VT_COL(RED, WHITE) "__osFree:二重解放(%08x)\n" VT_RST, ptr); // "__osFree: Double release (%08x)"
return; return;
} }
#if OOT_DEBUG
if (arena != node->arena && arena != NULL) { if (arena != node->arena && arena != NULL) {
// "__osFree:Tried to release in a different way than when it was secured (%08x:%08x)" // "__osFree:Tried to release in a different way than when it was secured (%08x:%08x)"
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:確保時と違う方法で解放しようとした (%08x:%08x)\n" VT_RST, arena, PRINTF(VT_COL(RED, WHITE) "__osFree:確保時と違う方法で解放しようとした (%08x:%08x)\n" VT_RST, arena,
node->arena); node->arena);
return; return;
} }
#endif
next = ArenaImpl_GetNextBlock(node); next = NODE_GET_NEXT(node);
prev = ArenaImpl_GetPrevBlock(node); prev = NODE_GET_PREV(node);
node->isFree = true; node->isFree = true;
ArenaImpl_SetDebugInfo(node, NULL, 0, arena); SET_DEBUG_INFO(node, NULL, 0, arena);
if (arena->flag & FILL_FREEBLOCK) { FILL_FREE_BLOCK_CONTENTS(arena, node);
__osMemset((void*)((u32)node + sizeof(ArenaNode)), BLOCK_FREE_MAGIC, node->size);
}
newNext = next;
if ((u32)next == (u32)node + sizeof(ArenaNode) + node->size && next->isFree) { if ((u32)next == (u32)node + sizeof(ArenaNode) + node->size && next->isFree) {
newNext = ArenaImpl_GetNextBlock(next); ArenaNode* newNext = NODE_GET_NEXT(next);
if (newNext != NULL) { if (newNext != NULL) {
newNext->prev = node; newNext->prev = node;
} }
node->size += next->size + sizeof(ArenaNode); node->size += next->size + sizeof(ArenaNode);
if (arena->flag & FILL_FREEBLOCK) { FILL_FREE_BLOCK_HEADER(arena, next);
__osMemset(next, BLOCK_FREE_MAGIC, sizeof(ArenaNode));
}
node->next = newNext; node->next = newNext;
next = newNext; next = newNext;
} }
@ -466,9 +517,7 @@ void __osFree_NoLock(Arena* arena, void* ptr) {
} }
prev->next = next; prev->next = next;
prev->size += node->size + sizeof(ArenaNode); prev->size += node->size + sizeof(ArenaNode);
if (arena->flag & FILL_FREEBLOCK) { FILL_FREE_BLOCK_HEADER(arena, node);
__osMemset(node, BLOCK_FREE_MAGIC, sizeof(ArenaNode));
}
} }
} }
@ -478,6 +527,7 @@ void __osFree(Arena* arena, void* ptr) {
ArenaImpl_Unlock(arena); ArenaImpl_Unlock(arena);
} }
#if OOT_DEBUG
void __osFree_NoLockDebug(Arena* arena, void* ptr, const char* file, s32 line) { void __osFree_NoLockDebug(Arena* arena, void* ptr, const char* file, s32 line) {
ArenaNode* node; ArenaNode* node;
ArenaNode* next; ArenaNode* next;
@ -491,41 +541,37 @@ void __osFree_NoLockDebug(Arena* arena, void* ptr, const char* file, s32 line) {
node = (ArenaNode*)((u32)ptr - sizeof(ArenaNode)); node = (ArenaNode*)((u32)ptr - sizeof(ArenaNode));
if (node == NULL || node->magic != NODE_MAGIC) { if (node == NULL || node->magic != NODE_MAGIC) {
// "__osFree: Unauthorized release (%08x)" // "__osFree: Unauthorized release (%08x)"
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:不正解放(%08x) [%s:%d ]\n" VT_RST, ptr, file, line); PRINTF(VT_COL(RED, WHITE) "__osFree:不正解放(%08x) [%s:%d ]\n" VT_RST, ptr, file, line);
return; return;
} }
if (node->isFree) { if (node->isFree) {
// "__osFree: Double release (%08x)" // "__osFree: Double release (%08x)"
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:二重解放(%08x) [%s:%d ]\n" VT_RST, ptr, file, line); PRINTF(VT_COL(RED, WHITE) "__osFree:二重解放(%08x) [%s:%d ]\n" VT_RST, ptr, file, line);
return; return;
} }
if (arena != node->arena && arena != NULL) { if (arena != node->arena && arena != NULL) {
// "__osFree:Tried to release in a different way than when it was secured (%08x:%08x)" // "__osFree:Tried to release in a different way than when it was secured (%08x:%08x)"
osSyncPrintf(VT_COL(RED, WHITE) "__osFree:確保時と違う方法で解放しようとした (%08x:%08x)\n" VT_RST, arena, PRINTF(VT_COL(RED, WHITE) "__osFree:確保時と違う方法で解放しようとした (%08x:%08x)\n" VT_RST, arena,
node->arena); node->arena);
return; return;
} }
next = ArenaImpl_GetNextBlock(node); next = NODE_GET_NEXT(node);
prev = ArenaImpl_GetPrevBlock(node); prev = NODE_GET_PREV(node);
node->isFree = true; node->isFree = true;
ArenaImpl_SetDebugInfo(node, file, line, arena); SET_DEBUG_INFO(node, file, line, arena);
if (arena->flag & FILL_FREEBLOCK) { FILL_FREE_BLOCK_CONTENTS(arena, node);
__osMemset((void*)((u32)node + sizeof(ArenaNode)), BLOCK_FREE_MAGIC, node->size);
}
newNext = node->next; newNext = node->next;
if ((u32)next == (u32)node + sizeof(ArenaNode) + node->size && next->isFree) { if ((u32)next == (u32)node + sizeof(ArenaNode) + node->size && next->isFree) {
newNext = ArenaImpl_GetNextBlock(next); newNext = NODE_GET_NEXT(next);
if (newNext != NULL) { if (newNext != NULL) {
newNext->prev = node; newNext->prev = node;
} }
node->size += next->size + sizeof(ArenaNode); node->size += next->size + sizeof(ArenaNode);
if (arena->flag & FILL_FREEBLOCK) { FILL_FREE_BLOCK_HEADER(arena, next);
__osMemset(next, BLOCK_FREE_MAGIC, sizeof(ArenaNode));
}
node->next = newNext; node->next = newNext;
next = newNext; next = newNext;
} }
@ -536,9 +582,7 @@ void __osFree_NoLockDebug(Arena* arena, void* ptr, const char* file, s32 line) {
} }
prev->next = next; prev->next = next;
prev->size += node->size + sizeof(ArenaNode); prev->size += node->size + sizeof(ArenaNode);
if (arena->flag & FILL_FREEBLOCK) { FILL_FREE_BLOCK_HEADER(arena, node);
__osMemset(node, BLOCK_FREE_MAGIC, sizeof(ArenaNode));
}
} }
} }
@ -547,10 +591,11 @@ void __osFreeDebug(Arena* arena, void* ptr, const char* file, s32 line) {
__osFree_NoLockDebug(arena, ptr, file, line); __osFree_NoLockDebug(arena, ptr, file, line);
ArenaImpl_Unlock(arena); ArenaImpl_Unlock(arena);
} }
#endif
void* __osRealloc(Arena* arena, void* ptr, u32 newSize) { void* __osRealloc(Arena* arena, void* ptr, u32 newSize) {
void* newAlloc;
ArenaNode* node; ArenaNode* node;
void* newAlloc;
ArenaNode* next; ArenaNode* next;
ArenaNode* newNext; ArenaNode* newNext;
ArenaNode* overNext; ArenaNode* overNext;
@ -577,20 +622,20 @@ void* __osRealloc(Arena* arena, void* ptr, u32 newSize) {
// "Does nothing because the memory block size does not change" // "Does nothing because the memory block size does not change"
osSyncPrintf("メモリブロックサイズが変わらないためなにもしません\n"); osSyncPrintf("メモリブロックサイズが変わらないためなにもしません\n");
} else if (node->size < newSize) { } else if (node->size < newSize) {
next = ArenaImpl_GetNextBlock(node); next = NODE_GET_NEXT(node);
sizeDiff = newSize - node->size; sizeDiff = newSize - node->size;
if ((u32)next == ((u32)node + node->size + sizeof(ArenaNode)) && next->isFree && next->size >= sizeDiff) { if ((u32)next == ((u32)node + node->size + sizeof(ArenaNode)) && next->isFree && next->size >= sizeDiff) {
// "Merge because there is a free block after the current memory block" // "Merge because there is a free block after the current memory block"
osSyncPrintf("現メモリブロックの後ろにフリーブロックがあるので結合します\n"); osSyncPrintf("現メモリブロックの後ろにフリーブロックがあるので結合します\n");
next->size -= sizeDiff; next->size -= sizeDiff;
overNext = ArenaImpl_GetNextBlock(next); overNext = NODE_GET_NEXT(next);
newNext = (ArenaNode*)((u32)next + sizeDiff); newNext = (ArenaNode*)((u32)next + sizeDiff);
if (overNext != NULL) { if (overNext != NULL) {
overNext->prev = newNext; overNext->prev = newNext;
} }
node->next = newNext; node->next = newNext;
node->size = newSize; node->size = newSize;
__osMemmove(newNext, next, sizeof(ArenaNode)); __osMemmove(node->next, next, sizeof(ArenaNode));
} else { } else {
// "Allocate a new memory block and move the contents" // "Allocate a new memory block and move the contents"
osSyncPrintf("新たにメモリブロックを確保して内容を移動します\n"); osSyncPrintf("新たにメモリブロックを確保して内容を移動します\n");
@ -602,9 +647,10 @@ void* __osRealloc(Arena* arena, void* ptr, u32 newSize) {
ptr = newAlloc; ptr = newAlloc;
} }
} else if (newSize < node->size) { } else if (newSize < node->size) {
next2 = ArenaImpl_GetNextBlock(node); next2 = NODE_GET_NEXT(node);
if (next2 != NULL && next2->isFree) { if (next2 != NULL && next2->isFree) {
blockSize = ALIGN16(newSize) + sizeof(ArenaNode); blockSize = ALIGN16(newSize) + sizeof(ArenaNode);
// "Increased free block behind current memory block" // "Increased free block behind current memory block"
osSyncPrintf("現メモリブロックの後ろのフリーブロックを大きくしました\n"); osSyncPrintf("現メモリブロックの後ろのフリーブロックを大きくしました\n");
newNext2 = (ArenaNode*)((u32)node + blockSize); newNext2 = (ArenaNode*)((u32)node + blockSize);
@ -613,23 +659,24 @@ void* __osRealloc(Arena* arena, void* ptr, u32 newSize) {
newNext2->size += node->size - newSize; newNext2->size += node->size - newSize;
node->next = newNext2; node->next = newNext2;
node->size = newSize; node->size = newSize;
overNext2 = ArenaImpl_GetNextBlock(newNext2); overNext2 = NODE_GET_NEXT(newNext2);
if (overNext2 != NULL) { if (overNext2 != NULL) {
overNext2->prev = newNext2; overNext2->prev = newNext2;
} }
} else if (newSize + sizeof(ArenaNode) < node->size) { } else if (newSize + sizeof(ArenaNode) < node->size) {
blockSize = ALIGN16(newSize) + sizeof(ArenaNode); blockSize = ALIGN16(newSize) + sizeof(ArenaNode);
// "Generated because there is no free block after the current memory block" // "Generated because there is no free block after the current memory block"
osSyncPrintf("現メモリブロックの後ろにフリーブロックがないので生成します\n"); osSyncPrintf("現メモリブロックの後ろにフリーブロックがないので生成します\n");
newNext2 = (ArenaNode*)((u32)node + blockSize); newNext2 = (ArenaNode*)((u32)node + blockSize);
newNext2->next = ArenaImpl_GetNextBlock(node); newNext2->next = NODE_GET_NEXT(node);
newNext2->prev = node; newNext2->prev = node;
newNext2->size = node->size - blockSize; newNext2->size = node->size - blockSize;
newNext2->isFree = true; newNext2->isFree = true;
newNext2->magic = NODE_MAGIC; newNext2->magic = NODE_MAGIC;
node->next = newNext2; node->next = newNext2;
node->size = newSize; node->size = newSize;
overNext2 = ArenaImpl_GetNextBlock(newNext2); overNext2 = NODE_GET_NEXT(newNext2);
if (overNext2 != NULL) { if (overNext2 != NULL) {
overNext2->prev = newNext2; overNext2->prev = newNext2;
} }
@ -639,15 +686,19 @@ void* __osRealloc(Arena* arena, void* ptr, u32 newSize) {
ptr = NULL; ptr = NULL;
} }
} }
CHECK_ALLOC_FAILURE(arena, ptr);
} }
ArenaImpl_Unlock(arena); ArenaImpl_Unlock(arena);
return ptr; return ptr;
} }
#if OOT_DEBUG
void* __osReallocDebug(Arena* arena, void* ptr, u32 newSize, const char* file, s32 line) { void* __osReallocDebug(Arena* arena, void* ptr, u32 newSize, const char* file, s32 line) {
return __osRealloc(arena, ptr, newSize); return __osRealloc(arena, ptr, newSize);
} }
#endif
void ArenaImpl_GetSizes(Arena* arena, u32* outMaxFree, u32* outFree, u32* outAlloc) { void ArenaImpl_GetSizes(Arena* arena, u32* outMaxFree, u32* outFree, u32* outAlloc) {
ArenaNode* iter; ArenaNode* iter;
@ -669,12 +720,13 @@ void ArenaImpl_GetSizes(Arena* arena, u32* outMaxFree, u32* outFree, u32* outAll
*outAlloc += iter->size; *outAlloc += iter->size;
} }
iter = ArenaImpl_GetNextBlock(iter); iter = NODE_GET_NEXT(iter);
} }
ArenaImpl_Unlock(arena); ArenaImpl_Unlock(arena);
} }
#if OOT_DEBUG
void __osDisplayArena(Arena* arena) { void __osDisplayArena(Arena* arena) {
u32 freeSize; u32 freeSize;
u32 allocatedSize; u32 allocatedSize;
@ -737,6 +789,7 @@ void __osDisplayArena(Arena* arena) {
ArenaImpl_Unlock(arena); ArenaImpl_Unlock(arena);
} }
#endif
void ArenaImpl_FaultClient(Arena* arena) { void ArenaImpl_FaultClient(Arena* arena) {
u32 freeSize; u32 freeSize;
@ -803,7 +856,7 @@ u32 __osCheckArena(Arena* arena) {
error = 1; error = 1;
break; break;
} }
iter = ArenaImpl_GetNextBlock(iter); iter = NODE_GET_NEXT(iter);
} }
if (error == 0) { if (error == 0) {
osSyncPrintf("アリーナはまだ、いけそうです\n"); // "The arena is still going well" osSyncPrintf("アリーナはまだ、いけそうです\n"); // "The arena is still going well"
@ -813,6 +866,8 @@ u32 __osCheckArena(Arena* arena) {
return error; return error;
} }
u8 func_800FF334(Arena* arena) { #if OOT_DEBUG
return arena->unk_20; u8 ArenaImpl_GetAllocFailures(Arena* arena) {
return arena->allocFailures;
} }
#endif

View file

@ -51,7 +51,7 @@ void AudioMgr_HandleRetrace(AudioMgr* audioMgr) {
// Skip update, no rsp task produced // Skip update, no rsp task produced
rspTask = NULL; rspTask = NULL;
} else { } else {
rspTask = func_800E4FE0(); rspTask = AudioThread_Update();
} }
gAudioThreadUpdateTimeAcc += osGetTime() - gAudioThreadUpdateTimeStart; gAudioThreadUpdateTimeAcc += osGetTime() - gAudioThreadUpdateTimeStart;

View file

@ -36,6 +36,7 @@ void DynaPolyActor_UpdateCarriedActorPos(CollisionContext* colCtx, s32 bgId, Act
SkinMatrix_Vec3fMtxFMultXYZ(&curTransform, &tempPos, &pos); SkinMatrix_Vec3fMtxFMultXYZ(&curTransform, &tempPos, &pos);
carriedActor->world.pos = pos; carriedActor->world.pos = pos;
#if OOT_DEBUG
if (BGCHECK_XYZ_ABSMAX <= pos.x || pos.x <= -BGCHECK_XYZ_ABSMAX || BGCHECK_XYZ_ABSMAX <= pos.y || if (BGCHECK_XYZ_ABSMAX <= pos.x || pos.x <= -BGCHECK_XYZ_ABSMAX || BGCHECK_XYZ_ABSMAX <= pos.y ||
pos.y <= -BGCHECK_XYZ_ABSMAX || BGCHECK_XYZ_ABSMAX <= pos.z || pos.z <= -BGCHECK_XYZ_ABSMAX) { pos.y <= -BGCHECK_XYZ_ABSMAX || BGCHECK_XYZ_ABSMAX <= pos.z || pos.z <= -BGCHECK_XYZ_ABSMAX) {
@ -47,6 +48,7 @@ void DynaPolyActor_UpdateCarriedActorPos(CollisionContext* colCtx, s32 bgId, Act
pos.x, pos.y, pos.z); pos.x, pos.y, pos.z);
PRINTF(VT_RST); PRINTF(VT_RST);
} }
#endif
} }
} }
} }

View file

@ -6,10 +6,10 @@
*/ */
void DynaPolyActor_Init(DynaPolyActor* dynaActor, s32 transformFlags) { void DynaPolyActor_Init(DynaPolyActor* dynaActor, s32 transformFlags) {
dynaActor->bgId = -1; dynaActor->bgId = -1;
dynaActor->transformFlags = transformFlags;
dynaActor->interactFlags = 0;
dynaActor->unk_150 = 0.0f; dynaActor->unk_150 = 0.0f;
dynaActor->unk_154 = 0.0f; dynaActor->unk_154 = 0.0f;
dynaActor->transformFlags = transformFlags;
dynaActor->interactFlags = 0;
} }
void DynaPolyActor_UnsetAllInteractFlags(DynaPolyActor* dynaActor) { void DynaPolyActor_UnsetAllInteractFlags(DynaPolyActor* dynaActor) {

View file

@ -1,15 +1,18 @@
#include "global.h" #include "global.h"
#include "terminal.h" #include "terminal.h"
#if OOT_DEBUG
u32 gIsCtrlr2Valid = false; u32 gIsCtrlr2Valid = false;
#endif
NORETURN void func_800D31A0(void) { NORETURN void func_800D31A0(void) {
PRINTF(VT_FGCOL(RED) "\n**** Freeze!! ****\n" VT_RST); PRINTF(VT_FGCOL(RED) "\n**** Freeze!! ****\n" VT_RST);
while (true) { for (;;) {
Sleep_Msec(1000); Sleep_Msec(1000);
} }
} }
#if OOT_DEBUG
void func_800D31F0(void) { void func_800D31F0(void) {
gIsCtrlr2Valid = (gPadMgr.validCtrlrsMask & 2) != 0; gIsCtrlr2Valid = (gPadMgr.validCtrlrsMask & 2) != 0;
} }
@ -17,3 +20,4 @@ void func_800D31F0(void) {
void func_800D3210(void) { void func_800D3210(void) {
gIsCtrlr2Valid = false; gIsCtrlr2Valid = false;
} }
#endif

View file

@ -26,7 +26,11 @@ void* func_800FC800(u32 size) {
size = 1; size = 1;
} }
#if OOT_DEBUG
return __osMallocDebug(&gSystemArena, size, sNew, 0); return __osMallocDebug(&gSystemArena, size, sNew, 0);
#else
return __osMalloc(&gSystemArena, size);
#endif
} }
// possibly some kind of delete() function // possibly some kind of delete() function

View file

@ -1538,18 +1538,18 @@ char DebugCamera_InitCut(s32 idx, DebugCamSub* sub) {
D_80161250[0x3F + sDebugCamCuts[idx].letter] = 'O'; D_80161250[0x3F + sDebugCamCuts[idx].letter] = 'O';
i = sub->nPoints * sizeof(CutsceneCameraPoint); i = sub->nPoints * sizeof(CutsceneCameraPoint);
sDebugCamCuts[idx].lookAt = DebugArena_MallocDebug(i, "../db_camera.c", 2748); sDebugCamCuts[idx].lookAt = DEBUG_ARENA_MALLOC(i, "../db_camera.c", 2748);
if (sDebugCamCuts[idx].lookAt == NULL) { if (sDebugCamCuts[idx].lookAt == NULL) {
// "Debug camera memory allocation failure" // "Debug camera memory allocation failure"
PRINTF("%s: %d: デバッグカメラ メモリ確保失敗!!\n", "../db_camera.c", 2751); PRINTF("%s: %d: デバッグカメラ メモリ確保失敗!!\n", "../db_camera.c", 2751);
return '?'; return '?';
} }
sDebugCamCuts[idx].position = DebugArena_MallocDebug(i, "../db_camera.c", 2754); sDebugCamCuts[idx].position = DEBUG_ARENA_MALLOC(i, "../db_camera.c", 2754);
if (sDebugCamCuts[idx].position == NULL) { if (sDebugCamCuts[idx].position == NULL) {
// "Debug camera memory allocation failure" // "Debug camera memory allocation failure"
PRINTF("%s: %d: デバッグカメラ メモリ確保失敗!!\n", "../db_camera.c", 2757); PRINTF("%s: %d: デバッグカメラ メモリ確保失敗!!\n", "../db_camera.c", 2757);
DebugArena_FreeDebug(sDebugCamCuts[idx].lookAt, "../db_camera.c", 2758); DEBUG_ARENA_FREE(sDebugCamCuts[idx].lookAt, "../db_camera.c", 2758);
sDebugCamCuts[idx].lookAt = NULL; sDebugCamCuts[idx].lookAt = NULL;
return '?'; return '?';
} }
@ -1572,8 +1572,8 @@ void DebugCamera_ResetCut(s32 idx, s32 shouldFree) {
} }
if (shouldFree) { if (shouldFree) {
DebugArena_FreeDebug(sDebugCamCuts[idx].lookAt, "../db_camera.c", 2784); DEBUG_ARENA_FREE(sDebugCamCuts[idx].lookAt, "../db_camera.c", 2784);
DebugArena_FreeDebug(sDebugCamCuts[idx].position, "../db_camera.c", 2785); DEBUG_ARENA_FREE(sDebugCamCuts[idx].position, "../db_camera.c", 2785);
} }
sDebugCamCuts[idx].letter = '?'; sDebugCamCuts[idx].letter = '?';
@ -1623,7 +1623,7 @@ s32 DebugCamera_LoadCallback(char* c) {
if (sDebugCamCuts[i].letter != '?') { if (sDebugCamCuts[i].letter != '?') {
size = sDebugCamCuts[i].nPoints * sizeof(CutsceneCameraPoint); size = sDebugCamCuts[i].nPoints * sizeof(CutsceneCameraPoint);
sDebugCamCuts[i].lookAt = DebugArena_MallocDebug(ALIGN32(size), "../db_camera.c", 2844); sDebugCamCuts[i].lookAt = DEBUG_ARENA_MALLOC(ALIGN32(size), "../db_camera.c", 2844);
if (sDebugCamCuts[i].lookAt == NULL) { if (sDebugCamCuts[i].lookAt == NULL) {
// "Debug camera memory allocation failure" // "Debug camera memory allocation failure"
PRINTF("%s: %d: デバッグカメラ メモリ確保失敗!!\n", "../db_camera.c", 2847); PRINTF("%s: %d: デバッグカメラ メモリ確保失敗!!\n", "../db_camera.c", 2847);
@ -1634,7 +1634,7 @@ s32 DebugCamera_LoadCallback(char* c) {
} }
off += ALIGN32(size); off += ALIGN32(size);
sDebugCamCuts[i].position = DebugArena_MallocDebug(ALIGN32(size), "../db_camera.c", 2855); sDebugCamCuts[i].position = DEBUG_ARENA_MALLOC(ALIGN32(size), "../db_camera.c", 2855);
if (sDebugCamCuts[i].position == NULL) { if (sDebugCamCuts[i].position == NULL) {
// "Debug camera memory allocation failure" // "Debug camera memory allocation failure"
PRINTF("%s: %d: デバッグカメラ メモリ確保失敗!!\n", "../db_camera.c", 2858); PRINTF("%s: %d: デバッグカメラ メモリ確保失敗!!\n", "../db_camera.c", 2858);

View file

@ -4,9 +4,11 @@
#define LOG_SEVERITY_ERROR 2 #define LOG_SEVERITY_ERROR 2
#define LOG_SEVERITY_VERBOSE 3 #define LOG_SEVERITY_VERBOSE 3
s32 gDebugArenaLogSeverity = LOG_SEVERITY_ERROR;
Arena sDebugArena; Arena sDebugArena;
#if OOT_DEBUG
s32 gDebugArenaLogSeverity = LOG_SEVERITY_ERROR;
void DebugArena_CheckPointer(void* ptr, u32 size, const char* name, const char* action) { void DebugArena_CheckPointer(void* ptr, u32 size, const char* name, const char* action) {
if (ptr == NULL) { if (ptr == NULL) {
if (gDebugArenaLogSeverity >= LOG_SEVERITY_ERROR) { if (gDebugArenaLogSeverity >= LOG_SEVERITY_ERROR) {
@ -21,53 +23,66 @@ void DebugArena_CheckPointer(void* ptr, u32 size, const char* name, const char*
} }
} }
#define DEBUG_ARENA_CHECK_POINTER(ptr, size, name, action) DebugArena_CheckPointer(ptr, size, name, action)
#else
#define DEBUG_ARENA_CHECK_POINTER(ptr, size, name, action) (void)0
#endif
void* DebugArena_Malloc(u32 size) { void* DebugArena_Malloc(u32 size) {
void* ptr = __osMalloc(&sDebugArena, size); void* ptr = __osMalloc(&sDebugArena, size);
DebugArena_CheckPointer(ptr, size, "debug_malloc", "確保"); // "Secure" DEBUG_ARENA_CHECK_POINTER(ptr, size, "debug_malloc", "確保"); // "Secure"
return ptr; return ptr;
} }
#if OOT_DEBUG
void* DebugArena_MallocDebug(u32 size, const char* file, s32 line) { void* DebugArena_MallocDebug(u32 size, const char* file, s32 line) {
void* ptr = __osMallocDebug(&sDebugArena, size, file, line); void* ptr = __osMallocDebug(&sDebugArena, size, file, line);
DebugArena_CheckPointer(ptr, size, "debug_malloc_DEBUG", "確保"); // "Secure" DEBUG_ARENA_CHECK_POINTER(ptr, size, "debug_malloc_DEBUG", "確保"); // "Secure"
return ptr; return ptr;
} }
#endif
void* DebugArena_MallocR(u32 size) { void* DebugArena_MallocR(u32 size) {
void* ptr = __osMallocR(&sDebugArena, size); void* ptr = __osMallocR(&sDebugArena, size);
DebugArena_CheckPointer(ptr, size, "debug_malloc_r", "確保"); // "Secure" DEBUG_ARENA_CHECK_POINTER(ptr, size, "debug_malloc_r", "確保"); // "Secure"
return ptr; return ptr;
} }
#if OOT_DEBUG
void* DebugArena_MallocRDebug(u32 size, const char* file, s32 line) { void* DebugArena_MallocRDebug(u32 size, const char* file, s32 line) {
void* ptr = __osMallocRDebug(&sDebugArena, size, file, line); void* ptr = __osMallocRDebug(&sDebugArena, size, file, line);
DebugArena_CheckPointer(ptr, size, "debug_malloc_r_DEBUG", "確保"); // "Secure" DEBUG_ARENA_CHECK_POINTER(ptr, size, "debug_malloc_r_DEBUG", "確保"); // "Secure"
return ptr; return ptr;
} }
#endif
void* DebugArena_Realloc(void* ptr, u32 newSize) { void* DebugArena_Realloc(void* ptr, u32 newSize) {
ptr = __osRealloc(&sDebugArena, ptr, newSize); ptr = __osRealloc(&sDebugArena, ptr, newSize);
DebugArena_CheckPointer(ptr, newSize, "debug_realloc", "再確保"); // "Re-securing" DEBUG_ARENA_CHECK_POINTER(ptr, newSize, "debug_realloc", "再確保"); // "Re-securing"
return ptr; return ptr;
} }
#if OOT_DEBUG
void* DebugArena_ReallocDebug(void* ptr, u32 newSize, const char* file, s32 line) { void* DebugArena_ReallocDebug(void* ptr, u32 newSize, const char* file, s32 line) {
ptr = __osReallocDebug(&sDebugArena, ptr, newSize, file, line); ptr = __osReallocDebug(&sDebugArena, ptr, newSize, file, line);
DebugArena_CheckPointer(ptr, newSize, "debug_realloc_DEBUG", "再確保"); // "Re-securing" DEBUG_ARENA_CHECK_POINTER(ptr, newSize, "debug_realloc_DEBUG", "再確保"); // "Re-securing"
return ptr; return ptr;
} }
#endif
void DebugArena_Free(void* ptr) { void DebugArena_Free(void* ptr) {
__osFree(&sDebugArena, ptr); __osFree(&sDebugArena, ptr);
} }
#if OOT_DEBUG
void DebugArena_FreeDebug(void* ptr, const char* file, s32 line) { void DebugArena_FreeDebug(void* ptr, const char* file, s32 line) {
__osFreeDebug(&sDebugArena, ptr, file, line); __osFreeDebug(&sDebugArena, ptr, file, line);
} }
#endif
void* DebugArena_Calloc(u32 num, u32 size) { void* DebugArena_Calloc(u32 num, u32 size) {
void* ret; void* ret;
@ -78,15 +93,17 @@ void* DebugArena_Calloc(u32 num, u32 size) {
bzero(ret, n); bzero(ret, n);
} }
DebugArena_CheckPointer(ret, n, "debug_calloc", "確保"); DEBUG_ARENA_CHECK_POINTER(ret, n, "debug_calloc", "確保");
return ret; return ret;
} }
#if OOT_DEBUG
void DebugArena_Display(void) { void DebugArena_Display(void) {
// "Zelda heap display" ("Zelda" should probably have been changed to "Debug") // "Zelda heap display" ("Zelda" should probably have been changed to "Debug")
PRINTF("ゼルダヒープ表示\n"); PRINTF("ゼルダヒープ表示\n");
__osDisplayArena(&sDebugArena); __osDisplayArena(&sDebugArena);
} }
#endif
void DebugArena_GetSizes(u32* outMaxFree, u32* outFree, u32* outAlloc) { void DebugArena_GetSizes(u32* outMaxFree, u32* outFree, u32* outAlloc) {
ArenaImpl_GetSizes(&sDebugArena, outMaxFree, outFree, outAlloc); ArenaImpl_GetSizes(&sDebugArena, outMaxFree, outFree, outAlloc);
@ -97,12 +114,16 @@ void DebugArena_Check(void) {
} }
void DebugArena_Init(void* start, u32 size) { void DebugArena_Init(void* start, u32 size) {
#if OOT_DEBUG
gDebugArenaLogSeverity = LOG_SEVERITY_NOLOG; gDebugArenaLogSeverity = LOG_SEVERITY_NOLOG;
#endif
__osMallocInit(&sDebugArena, start, size); __osMallocInit(&sDebugArena, start, size);
} }
void DebugArena_Cleanup(void) { void DebugArena_Cleanup(void) {
#if OOT_DEBUG
gDebugArenaLogSeverity = LOG_SEVERITY_NOLOG; gDebugArenaLogSeverity = LOG_SEVERITY_NOLOG;
#endif
__osMallocCleanup(&sDebugArena); __osMallocCleanup(&sDebugArena);
} }

View file

@ -78,7 +78,7 @@ void FlagSet_Update(PlayState* play) {
s32 pad; s32 pad;
polyOpa = POLY_OPA_DISP; polyOpa = POLY_OPA_DISP;
gfx = Graph_GfxPlusOne(polyOpa); gfx = Gfx_Open(polyOpa);
gSPDisplayList(OVERLAY_DISP++, gfx); gSPDisplayList(OVERLAY_DISP++, gfx);
GfxPrint_Init(&printer); GfxPrint_Init(&printer);
@ -171,7 +171,7 @@ void FlagSet_Update(PlayState* play) {
GfxPrint_Destroy(&printer); GfxPrint_Destroy(&printer);
gSPEndDisplayList(gfx++); gSPEndDisplayList(gfx++);
Graph_BranchDlist(polyOpa, gfx); Gfx_Close(polyOpa, gfx);
POLY_OPA_DISP = gfx; POLY_OPA_DISP = gfx;
} }

View file

@ -9,6 +9,7 @@ ViMode sViMode;
FaultClient sGameFaultClient; FaultClient sGameFaultClient;
u16 sLastButtonPressed; u16 sLastButtonPressed;
#if OOT_DEBUG
void GameState_FaultPrint(void) { void GameState_FaultPrint(void) {
static char sBtnChars[] = "ABZSuldr*+LRudlr"; static char sBtnChars[] = "ABZSuldr*+LRudlr";
s32 i; s32 i;
@ -21,6 +22,7 @@ void GameState_FaultPrint(void) {
} }
} }
} }
#endif
void GameState_SetFBFilter(Gfx** gfxP) { void GameState_SetFBFilter(Gfx** gfxP) {
Gfx* gfx = *gfxP; Gfx* gfx = *gfxP;
@ -62,6 +64,7 @@ void GameState_SetFBFilter(Gfx** gfxP) {
} }
void func_800C4344(GameState* gameState) { void func_800C4344(GameState* gameState) {
#if OOT_DEBUG
Input* selectedInput; Input* selectedInput;
s32 hexDumpSize; s32 hexDumpSize;
u16 inputCompareValue; u16 inputCompareValue;
@ -111,8 +114,10 @@ void func_800C4344(GameState* gameState) {
LogUtils_LogHexDump((void*)(0x80000000 + (R_PRINT_MEMORY_ADDR << 8)), hexDumpSize); LogUtils_LogHexDump((void*)(0x80000000 + (R_PRINT_MEMORY_ADDR << 8)), hexDumpSize);
} }
} }
#endif
} }
#if OOT_DEBUG
void GameState_DrawInputDisplay(u16 input, Gfx** gfxP) { void GameState_DrawInputDisplay(u16 input, Gfx** gfxP) {
static const u16 sInpDispBtnColors[] = { static const u16 sInpDispBtnColors[] = {
GPACK_RGBA5551(255, 255, 0, 1), GPACK_RGBA5551(255, 255, 0, 1), GPACK_RGBA5551(255, 255, 0, 1), GPACK_RGBA5551(255, 255, 0, 1), GPACK_RGBA5551(255, 255, 0, 1), GPACK_RGBA5551(255, 255, 0, 1),
@ -143,6 +148,7 @@ void GameState_DrawInputDisplay(u16 input, Gfx** gfxP) {
*gfxP = gfx; *gfxP = gfx;
} }
#endif
void GameState_Draw(GameState* gameState, GraphicsContext* gfxCtx) { void GameState_Draw(GameState* gameState, GraphicsContext* gfxCtx) {
Gfx* newDList; Gfx* newDList;
@ -150,13 +156,14 @@ void GameState_Draw(GameState* gameState, GraphicsContext* gfxCtx) {
OPEN_DISPS(gfxCtx, "../game.c", 746); OPEN_DISPS(gfxCtx, "../game.c", 746);
newDList = Graph_GfxPlusOne(polyOpaP = POLY_OPA_DISP); newDList = Gfx_Open(polyOpaP = POLY_OPA_DISP);
gSPDisplayList(OVERLAY_DISP++, newDList); gSPDisplayList(OVERLAY_DISP++, newDList);
if (R_ENABLE_FB_FILTER == 1) { if (R_ENABLE_FB_FILTER == 1) {
GameState_SetFBFilter(&newDList); GameState_SetFBFilter(&newDList);
} }
#if OOT_DEBUG
sLastButtonPressed = gameState->input[0].press.button | gameState->input[0].cur.button; sLastButtonPressed = gameState->input[0].press.button | gameState->input[0].cur.button;
if (R_DISABLE_INPUT_DISPLAY == 0) { if (R_DISABLE_INPUT_DISPLAY == 0) {
GameState_DrawInputDisplay(sLastButtonPressed, &newDList); GameState_DrawInputDisplay(sLastButtonPressed, &newDList);
@ -172,19 +179,21 @@ void GameState_Draw(GameState* gameState, GraphicsContext* gfxCtx) {
newDList = GfxPrint_Close(&printer); newDList = GfxPrint_Close(&printer);
GfxPrint_Destroy(&printer); GfxPrint_Destroy(&printer);
} }
#endif
if (R_ENABLE_ARENA_DBG < 0) { if (R_ENABLE_ARENA_DBG < 0) {
#if OOT_DEBUG
s32 pad; s32 pad;
DebugArena_Display(); DebugArena_Display();
SystemArena_Display(); SystemArena_Display();
// "%08x bytes left until the death of Hyrule (game_alloc)" // "%08x bytes left until the death of Hyrule (game_alloc)"
PRINTF("ハイラル滅亡まであと %08x バイト(game_alloc)\n", THA_GetRemaining(&gameState->tha)); PRINTF("ハイラル滅亡まであと %08x バイト(game_alloc)\n", THA_GetRemaining(&gameState->tha));
#endif
R_ENABLE_ARENA_DBG = 0; R_ENABLE_ARENA_DBG = 0;
} }
gSPEndDisplayList(newDList++); gSPEndDisplayList(newDList++);
Graph_BranchDlist(polyOpaP, newDList); Gfx_Close(polyOpaP, newDList);
POLY_OPA_DISP = newDList; POLY_OPA_DISP = newDList;
if (1) {} if (1) {}
@ -221,11 +230,11 @@ void func_800C49F4(GraphicsContext* gfxCtx) {
OPEN_DISPS(gfxCtx, "../game.c", 846); OPEN_DISPS(gfxCtx, "../game.c", 846);
newDlist = Graph_GfxPlusOne(polyOpaP = POLY_OPA_DISP); newDlist = Gfx_Open(polyOpaP = POLY_OPA_DISP);
gSPDisplayList(OVERLAY_DISP++, newDlist); gSPDisplayList(OVERLAY_DISP++, newDlist);
gSPEndDisplayList(newDlist++); gSPEndDisplayList(newDlist++);
Graph_BranchDlist(polyOpaP, newDlist); Gfx_Close(polyOpaP, newDlist);
POLY_OPA_DISP = newDlist; POLY_OPA_DISP = newDlist;
if (1) {} if (1) {}
@ -248,6 +257,7 @@ void GameState_Update(GameState* gameState) {
func_800C4344(gameState); func_800C4344(gameState);
#if OOT_DEBUG
if (SREG(63) == 1u) { if (SREG(63) == 1u) {
if (R_VI_MODE_EDIT_STATE < VI_MODE_EDIT_STATE_INACTIVE) { if (R_VI_MODE_EDIT_STATE < VI_MODE_EDIT_STATE_INACTIVE) {
R_VI_MODE_EDIT_STATE = VI_MODE_EDIT_STATE_INACTIVE; R_VI_MODE_EDIT_STATE = VI_MODE_EDIT_STATE_INACTIVE;
@ -321,6 +331,7 @@ void GameState_Update(GameState* gameState) {
D_80009430 = 1; D_80009430 = 1;
} }
} }
#endif
if (R_PAUSE_BG_PRERENDER_STATE != (u32)PAUSE_BG_PRERENDER_PROCESS) { if (R_PAUSE_BG_PRERENDER_STATE != (u32)PAUSE_BG_PRERENDER_PROCESS) {
GameState_Draw(gameState, gfxCtx); GameState_Draw(gameState, gfxCtx);
@ -334,14 +345,15 @@ void GameState_InitArena(GameState* gameState, size_t size) {
void* arena; void* arena;
PRINTF("ハイラル確保 サイズ=%u バイト\n"); // "Hyrule reserved size = %u bytes" PRINTF("ハイラル確保 サイズ=%u バイト\n"); // "Hyrule reserved size = %u bytes"
arena = GameAlloc_MallocDebug(&gameState->alloc, size, "../game.c", 992); arena = GAME_ALLOC_MALLOC(&gameState->alloc, size, "../game.c", 992);
if (arena != NULL) { if (arena != NULL) {
THA_Init(&gameState->tha, arena, size); THA_Init(&gameState->tha, arena, size);
PRINTF("ハイラル確保成功\n"); // "Successful Hyral" PRINTF("ハイラル確保成功\n"); // "Successful Hyral"
} else { } else {
THA_Init(&gameState->tha, NULL, 0); THA_Init(&gameState->tha, NULL, 0);
PRINTF("ハイラル確保失敗\n"); // "Failure to secure Hyrule" PRINTF("ハイラル確保失敗\n"); // "Failure to secure Hyrule"
Fault_AddHungupAndCrash("../game.c", 999); HUNGUP_AND_CRASH("../game.c", 999);
} }
} }
@ -369,15 +381,19 @@ void GameState_Realloc(GameState* gameState, size_t size) {
} }
PRINTF("ハイラル再確保 サイズ=%u バイト\n", size); // "Hyral reallocate size = %u bytes" PRINTF("ハイラル再確保 サイズ=%u バイト\n", size); // "Hyral reallocate size = %u bytes"
gameArena = GameAlloc_MallocDebug(alloc, size, "../game.c", 1033);
gameArena = GAME_ALLOC_MALLOC(alloc, size, "../game.c", 1033);
if (gameArena != NULL) { if (gameArena != NULL) {
THA_Init(&gameState->tha, gameArena, size); THA_Init(&gameState->tha, gameArena, size);
PRINTF("ハイラル再確保成功\n"); // "Successful reacquisition of Hyrule" PRINTF("ハイラル再確保成功\n"); // "Successful reacquisition of Hyrule"
} else { } else {
THA_Init(&gameState->tha, NULL, 0); THA_Init(&gameState->tha, NULL, 0);
PRINTF("ハイラル再確保失敗\n"); // "Failure to secure Hyral" PRINTF("ハイラル再確保失敗\n"); // "Failure to secure Hyral"
#if OOT_DEBUG
SystemArena_Display(); SystemArena_Display();
Fault_AddHungupAndCrash("../game.c", 1044); #endif
HUNGUP_AND_CRASH("../game.c", 1044);
} }
} }
@ -392,24 +408,25 @@ void GameState_Init(GameState* gameState, GameStateFunc init, GraphicsContext* g
gameState->destroy = NULL; gameState->destroy = NULL;
gameState->running = 1; gameState->running = 1;
startTime = osGetTime(); startTime = osGetTime();
gameState->size = 0; gameState->size = gameState->init = 0;
gameState->init = NULL;
endTime = osGetTime();
{
s32 requiredScopeTemp;
endTime = osGetTime();
// "game_set_next_game_null processing time %d us" // "game_set_next_game_null processing time %d us"
PRINTF("game_set_next_game_null 処理時間 %d us\n", OS_CYCLES_TO_USEC(endTime - startTime)); PRINTF("game_set_next_game_null 処理時間 %d us\n", OS_CYCLES_TO_USEC(endTime - startTime));
startTime = endTime; startTime = endTime;
GameAlloc_Init(&gameState->alloc); GameAlloc_Init(&gameState->alloc);
}
endTime = osGetTime(); endTime = osGetTime();
// "gamealloc_init processing time %d us" // "gamealloc_init processing time %d us"
PRINTF("gamealloc_init 処理時間 %d us\n", OS_CYCLES_TO_USEC(endTime - startTime)); PRINTF("gamealloc_init 処理時間 %d us\n", OS_CYCLES_TO_USEC(endTime - startTime));
startTime = endTime; startTime = endTime;
GameState_InitArena(gameState, 0x100000); GameState_InitArena(gameState, 0x100000);
R_UPDATE_RATE = 3; R_UPDATE_RATE = 3;
init(gameState); init(gameState);
endTime = osGetTime(); endTime = osGetTime();
// "init processing time %d us" // "init processing time %d us"
PRINTF("init 処理時間 %d us\n", OS_CYCLES_TO_USEC(endTime - startTime)); PRINTF("init 処理時間 %d us\n", OS_CYCLES_TO_USEC(endTime - startTime));
@ -419,18 +436,19 @@ void GameState_Init(GameState* gameState, GameStateFunc init, GraphicsContext* g
VisCvg_Init(&sVisCvg); VisCvg_Init(&sVisCvg);
VisZBuf_Init(&sVisZBuf); VisZBuf_Init(&sVisZBuf);
VisMono_Init(&sVisMono); VisMono_Init(&sVisMono);
if (R_VI_MODE_EDIT_STATE == VI_MODE_EDIT_STATE_INACTIVE) { if ((R_VI_MODE_EDIT_STATE == VI_MODE_EDIT_STATE_INACTIVE) || !OOT_DEBUG) {
ViMode_Init(&sViMode); ViMode_Init(&sViMode);
} }
SpeedMeter_Init(&D_801664D0); SpeedMeter_Init(&D_801664D0);
Rumble_Init(); Rumble_Init();
osSendMesg(&gameState->gfxCtx->queue, NULL, OS_MESG_BLOCK); osSendMesg(&gameState->gfxCtx->queue, NULL, OS_MESG_BLOCK);
endTime = osGetTime(); endTime = osGetTime();
// "Other initialization processing time %d us" // "Other initialization processing time %d us"
PRINTF("その他初期化 処理時間 %d us\n", OS_CYCLES_TO_USEC(endTime - startTime)); PRINTF("その他初期化 処理時間 %d us\n", OS_CYCLES_TO_USEC(endTime - startTime));
#if OOT_DEBUG
Fault_AddClient(&sGameFaultClient, GameState_FaultPrint, NULL, NULL); Fault_AddClient(&sGameFaultClient, GameState_FaultPrint, NULL, NULL);
#endif
PRINTF("game コンストラクタ終了\n"); // "game constructor end" PRINTF("game コンストラクタ終了\n"); // "game constructor end"
} }
@ -438,7 +456,7 @@ void GameState_Init(GameState* gameState, GameStateFunc init, GraphicsContext* g
void GameState_Destroy(GameState* gameState) { void GameState_Destroy(GameState* gameState) {
PRINTF("game デストラクタ開始\n"); // "game destructor start" PRINTF("game デストラクタ開始\n"); // "game destructor start"
AudioMgr_StopAllSfx(); AudioMgr_StopAllSfx();
func_800F3054(); Audio_Update();
osRecvMesg(&gameState->gfxCtx->queue, NULL, OS_MESG_BLOCK); osRecvMesg(&gameState->gfxCtx->queue, NULL, OS_MESG_BLOCK);
LOG_UTILS_CHECK_NULL_POINTER("this->cleanup", gameState->destroy, "../game.c", 1139); LOG_UTILS_CHECK_NULL_POINTER("this->cleanup", gameState->destroy, "../game.c", 1139);
if (gameState->destroy != NULL) { if (gameState->destroy != NULL) {
@ -449,13 +467,16 @@ void GameState_Destroy(GameState* gameState) {
VisCvg_Destroy(&sVisCvg); VisCvg_Destroy(&sVisCvg);
VisZBuf_Destroy(&sVisZBuf); VisZBuf_Destroy(&sVisZBuf);
VisMono_Destroy(&sVisMono); VisMono_Destroy(&sVisMono);
if (R_VI_MODE_EDIT_STATE == VI_MODE_EDIT_STATE_INACTIVE) { if ((R_VI_MODE_EDIT_STATE == VI_MODE_EDIT_STATE_INACTIVE) || !OOT_DEBUG) {
ViMode_Destroy(&sViMode); ViMode_Destroy(&sViMode);
} }
THA_Destroy(&gameState->tha); THA_Destroy(&gameState->tha);
GameAlloc_Cleanup(&gameState->alloc); GameAlloc_Cleanup(&gameState->alloc);
#if OOT_DEBUG
SystemArena_Display(); SystemArena_Display();
Fault_RemoveClient(&sGameFaultClient); Fault_RemoveClient(&sGameFaultClient);
#endif
PRINTF("game デストラクタ終了\n"); // "game destructor end" PRINTF("game デストラクタ終了\n"); // "game destructor end"
} }
@ -472,6 +493,7 @@ u32 GameState_IsRunning(GameState* gameState) {
return gameState->running; return gameState->running;
} }
#if OOT_DEBUG
void* GameState_Alloc(GameState* gameState, size_t size, char* file, s32 line) { void* GameState_Alloc(GameState* gameState, size_t size, char* file, s32 line) {
void* ret; void* ret;
@ -501,6 +523,7 @@ void* GameState_Alloc(GameState* gameState, size_t size, char* file, s32 line) {
void* GameState_AllocEndAlign16(GameState* gameState, size_t size) { void* GameState_AllocEndAlign16(GameState* gameState, size_t size) {
return THA_AllocTailAlign16(&gameState->tha, size); return THA_AllocTailAlign16(&gameState->tha, size);
} }
#endif
s32 GameState_GetArenaSize(GameState* gameState) { s32 GameState_GetArenaSize(GameState* gameState) {
return THA_GetRemaining(&gameState->tha); return THA_GetRemaining(&gameState->tha);

View file

@ -12,6 +12,7 @@ void GameAlloc_Log(GameAlloc* this) {
} }
} }
#if OOT_DEBUG
void* GameAlloc_MallocDebug(GameAlloc* this, u32 size, const char* file, s32 line) { void* GameAlloc_MallocDebug(GameAlloc* this, u32 size, const char* file, s32 line) {
GameAllocEntry* ptr = SystemArena_MallocDebug(size + sizeof(GameAllocEntry), file, line); GameAllocEntry* ptr = SystemArena_MallocDebug(size + sizeof(GameAllocEntry), file, line);
@ -27,6 +28,7 @@ void* GameAlloc_MallocDebug(GameAlloc* this, u32 size, const char* file, s32 lin
return NULL; return NULL;
} }
} }
#endif
void* GameAlloc_Malloc(GameAlloc* this, u32 size) { void* GameAlloc_Malloc(GameAlloc* this, u32 size) {
GameAllocEntry* ptr = SYSTEM_ARENA_MALLOC(size + sizeof(GameAllocEntry), "../gamealloc.c", 93); GameAllocEntry* ptr = SYSTEM_ARENA_MALLOC(size + sizeof(GameAllocEntry), "../gamealloc.c", 93);

25
src/code/gfxalloc.c Normal file
View file

@ -0,0 +1,25 @@
#include "global.h"
Gfx* Gfx_Open(Gfx* gfx) {
return gfx + 1;
}
Gfx* Gfx_Close(Gfx* gfx, Gfx* dst) {
gSPBranchList(gfx, dst);
return dst;
}
void* Gfx_Alloc(Gfx** gfxP, u32 size) {
u8* ptr;
Gfx* dst;
size = ALIGN8(size);
ptr = (u8*)(*gfxP + 1);
dst = (Gfx*)(ptr + size);
gSPBranchList(*gfxP, dst);
*gfxP = dst;
return ptr;
}

View file

@ -30,6 +30,7 @@ UCodeInfo D_8012D248[3] = {
{ UCODE_S2DEX, gspS2DEX2d_fifoTextStart }, { UCODE_S2DEX, gspS2DEX2d_fifoTextStart },
}; };
#if OOT_DEBUG
void Graph_FaultClient(void) { void Graph_FaultClient(void) {
void* nextFb = osViGetNextFramebuffer(); void* nextFb = osViGetNextFramebuffer();
void* newFb = (SysCfb_GetFbPtr(0) != nextFb) ? SysCfb_GetFbPtr(0) : SysCfb_GetFbPtr(1); void* newFb = (SysCfb_GetFbPtr(0) != nextFb) ? SysCfb_GetFbPtr(0) : SysCfb_GetFbPtr(1);
@ -93,6 +94,7 @@ void Graph_UCodeFaultClient(Gfx* workBuf) {
UCodeDisas_Disassemble(&disassembler, workBuf); UCodeDisas_Disassemble(&disassembler, workBuf);
UCodeDisas_Destroy(&disassembler); UCodeDisas_Destroy(&disassembler);
} }
#endif
void Graph_InitTHGA(GraphicsContext* gfxCtx) { void Graph_InitTHGA(GraphicsContext* gfxCtx) {
GfxPool* pool = &gGfxPools[gfxCtx->gfxPoolIdx & 1]; GfxPool* pool = &gGfxPools[gfxCtx->gfxPoolIdx & 1];
@ -139,13 +141,17 @@ void Graph_Init(GraphicsContext* gfxCtx) {
gfxCtx->xScale = gViConfigXScale; gfxCtx->xScale = gViConfigXScale;
gfxCtx->yScale = gViConfigYScale; gfxCtx->yScale = gViConfigYScale;
osCreateMesgQueue(&gfxCtx->queue, gfxCtx->msgBuff, ARRAY_COUNT(gfxCtx->msgBuff)); osCreateMesgQueue(&gfxCtx->queue, gfxCtx->msgBuff, ARRAY_COUNT(gfxCtx->msgBuff));
#if OOT_DEBUG
func_800D31F0(); func_800D31F0();
Fault_AddClient(&sGraphFaultClient, Graph_FaultClient, NULL, NULL); Fault_AddClient(&sGraphFaultClient, Graph_FaultClient, NULL, NULL);
#endif
} }
void Graph_Destroy(GraphicsContext* gfxCtx) { void Graph_Destroy(GraphicsContext* gfxCtx) {
#if OOT_DEBUG
func_800D3210(); func_800D3210();
Fault_RemoveClient(&sGraphFaultClient); Fault_RemoveClient(&sGraphFaultClient);
#endif
} }
void Graph_TaskSet00(GraphicsContext* gfxCtx) { void Graph_TaskSet00(GraphicsContext* gfxCtx) {
@ -157,17 +163,20 @@ void Graph_TaskSet00(GraphicsContext* gfxCtx) {
OSMesg msg; OSMesg msg;
OSTask_t* task = &gfxCtx->task.list.t; OSTask_t* task = &gfxCtx->task.list.t;
OSScTask* scTask = &gfxCtx->task; OSScTask* scTask = &gfxCtx->task;
CfbInfo* cfb;
gGfxTaskSentToNextReadyMinusAudioThreadUpdateTime = gGfxTaskSentToNextReadyMinusAudioThreadUpdateTime =
osGetTime() - sGraphPrevTaskTimeStart - gAudioThreadUpdateTimeAcc; osGetTime() - sGraphPrevTaskTimeStart - gAudioThreadUpdateTimeAcc;
{
CfbInfo* cfb;
osSetTimer(&timer, OS_USEC_TO_CYCLES(3000000), 0, &gfxCtx->queue, (OSMesg)666); osSetTimer(&timer, OS_USEC_TO_CYCLES(3000000), 0, &gfxCtx->queue, (OSMesg)666);
osRecvMesg(&gfxCtx->queue, &msg, OS_MESG_BLOCK); osRecvMesg(&gfxCtx->queue, &msg, OS_MESG_BLOCK);
osStopTimer(&timer); osStopTimer(&timer);
if (msg == (OSMesg)666) { if (msg == (OSMesg)666) {
#if OOT_DEBUG
PRINTF(VT_FGCOL(RED)); PRINTF(VT_FGCOL(RED));
PRINTF("RCPが帰ってきませんでした。"); // "RCP did not return." PRINTF("RCPが帰ってきませんでした。"); // "RCP did not return."
PRINTF(VT_RST); PRINTF(VT_RST);
@ -183,13 +192,17 @@ void Graph_TaskSet00(GraphicsContext* gfxCtx) {
R_UCODE_DISAS_LOG_LEVEL = 2; R_UCODE_DISAS_LOG_LEVEL = 2;
Graph_DisassembleUCode(sPrevTaskWorkBuffer); Graph_DisassembleUCode(sPrevTaskWorkBuffer);
} }
#endif
Fault_AddHungupAndCrashImpl("RCP is HUNG UP!!", "Oh! MY GOD!!"); Fault_AddHungupAndCrashImpl("RCP is HUNG UP!!", "Oh! MY GOD!!");
} }
osRecvMesg(&gfxCtx->queue, &msg, OS_MESG_NOBLOCK); osRecvMesg(&gfxCtx->queue, &msg, OS_MESG_NOBLOCK);
#if OOT_DEBUG
sPrevTaskWorkBuffer = gfxCtx->workBuffer; sPrevTaskWorkBuffer = gfxCtx->workBuffer;
#endif
if (gfxCtx->callback != NULL) { if (gfxCtx->callback != NULL) {
gfxCtx->callback(gfxCtx, gfxCtx->callbackParam); gfxCtx->callback(gfxCtx, gfxCtx->callbackParam);
} }
@ -225,9 +238,10 @@ void Graph_TaskSet00(GraphicsContext* gfxCtx) {
task->data_size = (uintptr_t)WORK_DISP - (uintptr_t)gfxCtx->workBuffer; task->data_size = (uintptr_t)WORK_DISP - (uintptr_t)gfxCtx->workBuffer;
CLOSE_DISPS(gfxCtx, "../graph.c", 830); CLOSE_DISPS(gfxCtx, "../graph.c", 830);
{ s32 pad2; } // Necessary to match stack usage
task->yield_data_ptr = gGfxSPTaskYieldBuffer; task->yield_data_ptr = gGfxSPTaskYieldBuffer;
if (1) {}
task->yield_data_size = sizeof(gGfxSPTaskYieldBuffer); task->yield_data_size = sizeof(gGfxSPTaskYieldBuffer);
scTask->next = NULL; scTask->next = NULL;
@ -241,9 +255,14 @@ void Graph_TaskSet00(GraphicsContext* gfxCtx) {
scTask->msgQueue = &gfxCtx->queue; scTask->msgQueue = &gfxCtx->queue;
scTask->msg = NULL; scTask->msg = NULL;
cfb = &sGraphCfbInfos[sGraphCfbInfoIdx++]; { s16 pad; }
cfb = &sGraphCfbInfos[sGraphCfbInfoIdx];
sGraphCfbInfoIdx = (sGraphCfbInfoIdx + 1) % ARRAY_COUNT(sGraphCfbInfos);
cfb->framebuffer = gfxCtx->curFrameBuffer; cfb->framebuffer = gfxCtx->curFrameBuffer;
cfb->swapBuffer = gfxCtx->curFrameBuffer; cfb->swapBuffer = gfxCtx->curFrameBuffer;
cfb->viMode = gfxCtx->viMode; cfb->viMode = gfxCtx->viMode;
cfb->viFeatures = gfxCtx->viFeatures; cfb->viFeatures = gfxCtx->viFeatures;
cfb->xScale = gfxCtx->xScale; cfb->xScale = gfxCtx->xScale;
@ -252,15 +271,15 @@ void Graph_TaskSet00(GraphicsContext* gfxCtx) {
cfb->updateRate = R_UPDATE_RATE; cfb->updateRate = R_UPDATE_RATE;
scTask->framebuffer = cfb; scTask->framebuffer = cfb;
sGraphCfbInfoIdx %= ARRAY_COUNT(sGraphCfbInfos);
if (1) {} { s16 pad2; }
gfxCtx->schedMsgQueue = &gScheduler.cmdQueue; gfxCtx->schedMsgQueue = &gScheduler.cmdQueue;
osSendMesg(&gScheduler.cmdQueue, (OSMesg)scTask, OS_MESG_BLOCK); osSendMesg(&gScheduler.cmdQueue, (OSMesg)scTask, OS_MESG_BLOCK);
Sched_Notify(&gScheduler); Sched_Notify(&gScheduler);
} }
}
void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) { void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) {
u32 problem; u32 problem;
@ -268,6 +287,7 @@ void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) {
gameState->inPreNMIState = false; gameState->inPreNMIState = false;
Graph_InitTHGA(gfxCtx); Graph_InitTHGA(gfxCtx);
#if OOT_DEBUG
OPEN_DISPS(gfxCtx, "../graph.c", 966); OPEN_DISPS(gfxCtx, "../graph.c", 966);
gDPNoOpString(WORK_DISP++, "WORK_DISP 開始", 0); gDPNoOpString(WORK_DISP++, "WORK_DISP 開始", 0);
@ -276,10 +296,12 @@ void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) {
gDPNoOpString(OVERLAY_DISP++, "OVERLAY_DISP 開始", 0); gDPNoOpString(OVERLAY_DISP++, "OVERLAY_DISP 開始", 0);
CLOSE_DISPS(gfxCtx, "../graph.c", 975); CLOSE_DISPS(gfxCtx, "../graph.c", 975);
#endif
GameState_ReqPadData(gameState); GameState_ReqPadData(gameState);
GameState_Update(gameState); GameState_Update(gameState);
#if OOT_DEBUG
OPEN_DISPS(gfxCtx, "../graph.c", 987); OPEN_DISPS(gfxCtx, "../graph.c", 987);
gDPNoOpString(WORK_DISP++, "WORK_DISP 終了", 0); gDPNoOpString(WORK_DISP++, "WORK_DISP 終了", 0);
@ -288,6 +310,7 @@ void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) {
gDPNoOpString(OVERLAY_DISP++, "OVERLAY_DISP 終了", 0); gDPNoOpString(OVERLAY_DISP++, "OVERLAY_DISP 終了", 0);
CLOSE_DISPS(gfxCtx, "../graph.c", 996); CLOSE_DISPS(gfxCtx, "../graph.c", 996);
#endif
OPEN_DISPS(gfxCtx, "../graph.c", 999); OPEN_DISPS(gfxCtx, "../graph.c", 999);
@ -300,6 +323,7 @@ void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) {
CLOSE_DISPS(gfxCtx, "../graph.c", 1028); CLOSE_DISPS(gfxCtx, "../graph.c", 1028);
#if OOT_DEBUG
if (R_HREG_MODE == HREG_MODE_PLAY && R_PLAY_ENABLE_UCODE_DISAS == 2) { if (R_HREG_MODE == HREG_MODE_PLAY && R_PLAY_ENABLE_UCODE_DISAS == 2) {
R_HREG_MODE = HREG_MODE_UCODE_DISAS; R_HREG_MODE = HREG_MODE_UCODE_DISAS;
R_UCODE_DISAS_TOGGLE = -1; R_UCODE_DISAS_TOGGLE = -1;
@ -326,6 +350,7 @@ void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) {
R_UCODE_DISAS_TOGGLE = 0; R_UCODE_DISAS_TOGGLE = 0;
} }
} }
#endif
problem = false; problem = false;
@ -373,11 +398,11 @@ void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) {
gfxCtx->fbIdx++; gfxCtx->fbIdx++;
} }
func_800F3054(); Audio_Update();
{ {
OSTime timeNow = osGetTime(); OSTime timeNow = osGetTime();
s32 pad[4]; s32 pad;
gRSPGfxTimeTotal = gRSPGfxTimeAcc; gRSPGfxTimeTotal = gRSPGfxTimeAcc;
gRSPAudioTimeTotal = gRSPAudioTimeAcc; gRSPAudioTimeTotal = gRSPAudioTimeAcc;
@ -392,6 +417,7 @@ void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) {
sGraphPrevUpdateEndTime = timeNow; sGraphPrevUpdateEndTime = timeNow;
} }
#if OOT_DEBUG
if (gIsCtrlr2Valid && CHECK_BTN_ALL(gameState->input[0].press.button, BTN_Z) && if (gIsCtrlr2Valid && CHECK_BTN_ALL(gameState->input[0].press.button, BTN_Z) &&
CHECK_BTN_ALL(gameState->input[0].cur.button, BTN_L | BTN_R)) { CHECK_BTN_ALL(gameState->input[0].cur.button, BTN_L | BTN_R)) {
gSaveContext.gameMode = GAMEMODE_NORMAL; gSaveContext.gameMode = GAMEMODE_NORMAL;
@ -405,6 +431,7 @@ void Graph_Update(GraphicsContext* gfxCtx, GameState* gameState) {
SET_NEXT_GAMESTATE(gameState, PreNMI_Init, PreNMIState); SET_NEXT_GAMESTATE(gameState, PreNMI_Init, PreNMIState);
gameState->running = false; gameState->running = false;
} }
#endif
} }
void Graph_ThreadEntry(void* arg0) { void Graph_ThreadEntry(void* arg0) {
@ -413,7 +440,6 @@ void Graph_ThreadEntry(void* arg0) {
u32 size; u32 size;
GameStateOverlay* nextOvl = &gGameStateOverlayTable[GAMESTATE_SETUP]; GameStateOverlay* nextOvl = &gGameStateOverlayTable[GAMESTATE_SETUP];
GameStateOverlay* ovl; GameStateOverlay* ovl;
char faultMsg[0x50];
PRINTF("グラフィックスレッド実行開始\n"); // "Start graphic thread execution" PRINTF("グラフィックスレッド実行開始\n"); // "Start graphic thread execution"
Graph_Init(&gfxCtx); Graph_Init(&gfxCtx);
@ -428,10 +454,15 @@ void Graph_ThreadEntry(void* arg0) {
gameState = SYSTEM_ARENA_MALLOC(size, "../graph.c", 1196); gameState = SYSTEM_ARENA_MALLOC(size, "../graph.c", 1196);
if (gameState == NULL) { if (gameState == NULL) {
#if OOT_DEBUG
char faultMsg[0x50];
PRINTF("確保失敗\n"); // "Failure to secure" PRINTF("確保失敗\n"); // "Failure to secure"
sprintf(faultMsg, "CLASS SIZE= %d bytes", size); sprintf(faultMsg, "CLASS SIZE= %d bytes", size);
Fault_AddHungupAndCrashImpl("GAME CLASS MALLOC FAILED", faultMsg); Fault_AddHungupAndCrashImpl("GAME CLASS MALLOC FAILED", faultMsg);
#else
Fault_AddHungupAndCrash("../graph.c", 1200);
#endif
} }
GameState_Init(gameState, ovl->init, &gfxCtx); GameState_Init(gameState, ovl->init, &gfxCtx);
@ -469,6 +500,7 @@ void* Graph_Alloc2(GraphicsContext* gfxCtx, size_t size) {
return THGA_AllocTail(&gfxCtx->polyOpa, ALIGN16(size)); return THGA_AllocTail(&gfxCtx->polyOpa, ALIGN16(size));
} }
#if OOT_DEBUG
void Graph_OpenDisps(Gfx** dispRefs, GraphicsContext* gfxCtx, const char* file, s32 line) { void Graph_OpenDisps(Gfx** dispRefs, GraphicsContext* gfxCtx, const char* file, s32 line) {
if (R_HREG_MODE == HREG_MODE_UCODE_DISAS && R_UCODE_DISAS_LOG_MODE != 4) { if (R_HREG_MODE == HREG_MODE_UCODE_DISAS && R_UCODE_DISAS_LOG_MODE != 4) {
dispRefs[0] = gfxCtx->polyOpa.p; dispRefs[0] = gfxCtx->polyOpa.p;
@ -502,27 +534,4 @@ void Graph_CloseDisps(Gfx** dispRefs, GraphicsContext* gfxCtx, const char* file,
} }
} }
} }
#endif
Gfx* Graph_GfxPlusOne(Gfx* gfx) {
return gfx + 1;
}
Gfx* Graph_BranchDlist(Gfx* gfx, Gfx* dst) {
gSPBranchList(gfx, dst);
return dst;
}
void* Graph_DlistAlloc(Gfx** gfxP, u32 size) {
u8* ptr;
Gfx* dst;
size = ALIGN8(size);
ptr = (u8*)(*gfxP + 1);
dst = (Gfx*)(ptr + size);
gSPBranchList(*gfxP, dst);
*gfxP = dst;
return ptr;
}

View file

@ -253,31 +253,36 @@ void IrqMgr_ThreadEntry(void* arg) {
case IRQ_RETRACE_MSG: case IRQ_RETRACE_MSG:
IrqMgr_HandleRetrace(irqMgr); IrqMgr_HandleRetrace(irqMgr);
break; break;
case IRQ_PRENMI_MSG: case IRQ_PRENMI_MSG:
PRINTF("PRE_NMI_MSG\n"); PRINTF("PRE_NMI_MSG\n");
// "Scheduler: Receives PRE_NMI message" // "Scheduler: Receives PRE_NMI message"
PRINTF("スケジューラPRE_NMIメッセージを受信\n"); PRINTF("スケジューラPRE_NMIメッセージを受信\n");
IrqMgr_HandlePreNMI(irqMgr); IrqMgr_HandlePreNMI(irqMgr);
break; break;
case IRQ_PRENMI450_MSG: case IRQ_PRENMI450_MSG:
PRINTF("PRENMI450_MSG\n"); PRINTF("PRENMI450_MSG\n");
// "Scheduler: Receives PRENMI450 message" // "Scheduler: Receives PRENMI450 message"
PRINTF("スケジューラPRENMI450メッセージを受信\n"); PRINTF("スケジューラPRENMI450メッセージを受信\n");
IrqMgr_HandlePreNMI450(irqMgr); IrqMgr_HandlePreNMI450(irqMgr);
break; break;
case IRQ_PRENMI480_MSG: case IRQ_PRENMI480_MSG:
PRINTF("PRENMI480_MSG\n"); PRINTF("PRENMI480_MSG\n");
// "Scheduler: Receives PRENMI480 message" // "Scheduler: Receives PRENMI480 message"
PRINTF("スケジューラPRENMI480メッセージを受信\n"); PRINTF("スケジューラPRENMI480メッセージを受信\n");
IrqMgr_HandlePreNMI480(irqMgr); IrqMgr_HandlePreNMI480(irqMgr);
break; break;
case IRQ_PRENMI500_MSG: case IRQ_PRENMI500_MSG:
PRINTF("PRENMI500_MSG\n"); PRINTF("PRENMI500_MSG\n");
// "Scheduler: Receives PRENMI500 message" // "Scheduler: Receives PRENMI500 message"
PRINTF("スケジューラPRENMI500メッセージを受信\n"); PRINTF("スケジューラPRENMI500メッセージを受信\n");
exit = true;
IrqMgr_HandlePreNMI500(irqMgr); IrqMgr_HandlePreNMI500(irqMgr);
exit = true;
break; break;
default: default:
// "Unexpected message received" // "Unexpected message received"
PRINTF("irqmgr.c:予期しないメッセージを受け取りました(%08x)\n", msg); PRINTF("irqmgr.c:予期しないメッセージを受け取りました(%08x)\n", msg);

View file

@ -1,20 +1,20 @@
#include "global.h" #include "global.h"
s32 Overlay_Load(uintptr_t vromStart, uintptr_t vromEnd, void* vramStart, void* vramEnd, void* allocatedRamAddr) { size_t Overlay_Load(uintptr_t vromStart, uintptr_t vromEnd, void* vramStart, void* vramEnd, void* allocatedRamAddr) {
s32 pad[3]; s32 pad[3];
uintptr_t end; uintptr_t end;
OverlayRelocationSection* ovlRelocs; OverlayRelocationSection* ovlRelocs;
u32 relocSectionOffset; u32 relocSectionOffset = 0;
size_t size; s32 size = vromEnd - vromStart;
size = vromEnd - vromStart;
end = (uintptr_t)allocatedRamAddr + size;
if (gOverlayLogSeverity >= 3) { if (gOverlayLogSeverity >= 3) {
// "Start loading dynamic link function" // "Start loading dynamic link function"
PRINTF("\nダイナミックリンクファンクションのロードを開始します\n"); PRINTF("\nダイナミックリンクファンクションのロードを開始します\n");
} }
size = vromEnd - vromStart;
end = (uintptr_t)allocatedRamAddr + size;
if (gOverlayLogSeverity >= 3) { if (gOverlayLogSeverity >= 3) {
// "DMA transfer of TEXT, DATA, RODATA + rel (%08x-%08x)" // "DMA transfer of TEXT, DATA, RODATA + rel (%08x-%08x)"
PRINTF("TEXT,DATA,RODATA+relを転送します(%08x-%08x)\n", allocatedRamAddr, end); PRINTF("TEXT,DATA,RODATA+relを転送します(%08x-%08x)\n", allocatedRamAddr, end);
@ -46,10 +46,10 @@ s32 Overlay_Load(uintptr_t vromStart, uintptr_t vromEnd, void* vramStart, void*
// "Clear BSS area (% 08x-% 08x)" // "Clear BSS area (% 08x-% 08x)"
PRINTF("BSS領域をクリアします(%08x-%08x)\n", end, end + ovlRelocs->bssSize); PRINTF("BSS領域をクリアします(%08x-%08x)\n", end, end + ovlRelocs->bssSize);
} }
bzero((void*)end, (s32)ovlRelocs->bssSize); bzero((void*)end, ovlRelocs->bssSize);
} }
size = (uintptr_t)&ovlRelocs->relocations[ovlRelocs->nRelocations] - (uintptr_t)ovlRelocs; size = (uintptr_t)(ovlRelocs->relocations + ovlRelocs->nRelocations) - (uintptr_t)ovlRelocs;
if (gOverlayLogSeverity >= 3) { if (gOverlayLogSeverity >= 3) {
// "Clear REL area (%08x-%08x)" // "Clear REL area (%08x-%08x)"
@ -68,5 +68,6 @@ s32 Overlay_Load(uintptr_t vromStart, uintptr_t vromEnd, void* vramStart, void*
// "Finish loading dynamic link function" // "Finish loading dynamic link function"
PRINTF("ダイナミックリンクファンクションのロードを終了します\n\n"); PRINTF("ダイナミックリンクファンクションのロードを終了します\n\n");
} }
return size; return size;
} }

View file

@ -25,12 +25,14 @@ AudioMgr gAudioMgr;
OSMesgQueue sSerialEventQueue; OSMesgQueue sSerialEventQueue;
OSMesg sSerialMsgBuf[1]; OSMesg sSerialMsgBuf[1];
#if OOT_DEBUG
void Main_LogSystemHeap(void) { void Main_LogSystemHeap(void) {
PRINTF(VT_FGCOL(GREEN)); PRINTF(VT_FGCOL(GREEN));
// "System heap size% 08x (% dKB) Start address% 08x" // "System heap size% 08x (% dKB) Start address% 08x"
PRINTF("システムヒープサイズ %08x(%dKB) 開始アドレス %08x\n", gSystemHeapSize, gSystemHeapSize / 1024, gSystemHeap); PRINTF("システムヒープサイズ %08x(%dKB) 開始アドレス %08x\n", gSystemHeapSize, gSystemHeapSize / 1024, gSystemHeap);
PRINTF(VT_RST); PRINTF(VT_RST);
} }
#endif
void Main(void* arg) { void Main(void* arg) {
IrqMgrClient irqClient; IrqMgrClient irqClient;
@ -38,9 +40,6 @@ void Main(void* arg) {
OSMesg irqMgrMsgBuf[60]; OSMesg irqMgrMsgBuf[60];
uintptr_t systemHeapStart; uintptr_t systemHeapStart;
uintptr_t fb; uintptr_t fb;
void* debugHeapStart;
u32 debugHeapSize;
s16* msg;
PRINTF("mainproc 実行開始\n"); // "Start running" PRINTF("mainproc 実行開始\n"); // "Start running"
gScreenWidth = SCREEN_WIDTH; gScreenWidth = SCREEN_WIDTH;
@ -55,6 +54,12 @@ void Main(void* arg) {
// "System heap initalization" // "System heap initalization"
PRINTF("システムヒープ初期化 %08x-%08x %08x\n", systemHeapStart, fb, gSystemHeapSize); PRINTF("システムヒープ初期化 %08x-%08x %08x\n", systemHeapStart, fb, gSystemHeapSize);
SystemHeap_Init((void*)systemHeapStart, gSystemHeapSize); // initializes the system heap SystemHeap_Init((void*)systemHeapStart, gSystemHeapSize); // initializes the system heap
#if OOT_DEBUG
{
void* debugHeapStart;
u32 debugHeapSize;
if (osMemSize >= 0x800000) { if (osMemSize >= 0x800000) {
debugHeapStart = SysCfb_GetFbEnd(); debugHeapStart = SysCfb_GetFbEnd();
debugHeapSize = PHYS_TO_K0(0x600000) - (uintptr_t)debugHeapStart; debugHeapSize = PHYS_TO_K0(0x600000) - (uintptr_t)debugHeapStart;
@ -62,8 +67,12 @@ void Main(void* arg) {
debugHeapSize = 0x400; debugHeapSize = 0x400;
debugHeapStart = SYSTEM_ARENA_MALLOC(debugHeapSize, "../main.c", 565); debugHeapStart = SYSTEM_ARENA_MALLOC(debugHeapSize, "../main.c", 565);
} }
PRINTF("debug_InitArena(%08x, %08x)\n", debugHeapStart, debugHeapSize); PRINTF("debug_InitArena(%08x, %08x)\n", debugHeapStart, debugHeapSize);
DebugArena_Init(debugHeapStart, debugHeapSize); DebugArena_Init(debugHeapStart, debugHeapSize);
}
#endif
Regs_Init(); Regs_Init();
R_ENABLE_ARENA_DBG = 0; R_ENABLE_ARENA_DBG = 0;
@ -71,7 +80,9 @@ void Main(void* arg) {
osCreateMesgQueue(&sSerialEventQueue, sSerialMsgBuf, ARRAY_COUNT(sSerialMsgBuf)); osCreateMesgQueue(&sSerialEventQueue, sSerialMsgBuf, ARRAY_COUNT(sSerialMsgBuf));
osSetEventMesg(OS_EVENT_SI, &sSerialEventQueue, NULL); osSetEventMesg(OS_EVENT_SI, &sSerialEventQueue, NULL);
#if OOT_DEBUG
Main_LogSystemHeap(); Main_LogSystemHeap();
#endif
osCreateMesgQueue(&irqMgrMsgQueue, irqMgrMsgBuf, ARRAY_COUNT(irqMgrMsgBuf)); osCreateMesgQueue(&irqMgrMsgQueue, irqMgrMsgBuf, ARRAY_COUNT(irqMgrMsgBuf));
StackCheck_Init(&sIrqMgrStackInfo, sIrqMgrStack, STACK_TOP(sIrqMgrStack), 0, 0x100, "irqmgr"); StackCheck_Init(&sIrqMgrStackInfo, sIrqMgrStack, STACK_TOP(sIrqMgrStack), 0, 0x100, "irqmgr");
@ -97,7 +108,8 @@ void Main(void* arg) {
osSetThreadPri(NULL, THREAD_PRI_MAIN); osSetThreadPri(NULL, THREAD_PRI_MAIN);
while (true) { while (true) {
msg = NULL; s16* msg = NULL;
osRecvMesg(&irqMgrMsgQueue, (OSMesg*)&msg, OS_MESG_BLOCK); osRecvMesg(&irqMgrMsgQueue, (OSMesg*)&msg, OS_MESG_BLOCK);
if (msg == NULL) { if (msg == NULL) {
break; break;

View file

@ -32,7 +32,7 @@
#include "terminal.h" #include "terminal.h"
#define PADMGR_LOG(controllerNum, msg) \ #define PADMGR_LOG(controllerNum, msg) \
if (1) { \ if (OOT_DEBUG) { \
PRINTF(VT_FGCOL(YELLOW)); \ PRINTF(VT_FGCOL(YELLOW)); \
/* padmgr: Controller %d: %s */ \ /* padmgr: Controller %d: %s */ \
PRINTF("padmgr: %dコン: %s\n", (controllerNum) + 1, (msg)); \ PRINTF("padmgr: %dコン: %s\n", (controllerNum) + 1, (msg)); \
@ -66,7 +66,11 @@ s32 gPadMgrLogSeverity = LOG_SEVERITY_CRITICAL;
* @see PadMgr_ReleaseSerialEventQueue * @see PadMgr_ReleaseSerialEventQueue
*/ */
OSMesgQueue* PadMgr_AcquireSerialEventQueue(PadMgr* padMgr) { OSMesgQueue* PadMgr_AcquireSerialEventQueue(PadMgr* padMgr) {
OSMesgQueue* serialEventQueue = NULL; OSMesgQueue* serialEventQueue;
#if OOT_DEBUG
serialEventQueue = NULL;
#endif
if (gPadMgrLogSeverity >= LOG_SEVERITY_VERBOSE) { if (gPadMgrLogSeverity >= LOG_SEVERITY_VERBOSE) {
// "serialMsgQ Waiting for lock" // "serialMsgQ Waiting for lock"
@ -135,13 +139,10 @@ void PadMgr_UnlockPadData(PadMgr* padMgr) {
void PadMgr_UpdateRumble(PadMgr* padMgr) { void PadMgr_UpdateRumble(PadMgr* padMgr) {
static u32 sRumbleErrorCount = 0; // original name: "errcnt" static u32 sRumbleErrorCount = 0; // original name: "errcnt"
static u32 sRumbleUpdateCounter; static u32 sRumbleUpdateCounter;
s32 motorStart = MOTOR_START; // required for matching?
s32 triedRumbleComm;
OSMesgQueue* serialEventQueue = PadMgr_AcquireSerialEventQueue(padMgr);
s32 ret;
s32 i; s32 i;
s32 ret;
triedRumbleComm = false; OSMesgQueue* serialEventQueue = PadMgr_AcquireSerialEventQueue(padMgr);
s32 triedRumbleComm = false;
for (i = 0; i < MAXCONTROLLERS; i++) { for (i = 0; i < MAXCONTROLLERS; i++) {
if (padMgr->ctrlrIsConnected[i]) { if (padMgr->ctrlrIsConnected[i]) {
@ -153,9 +154,7 @@ void PadMgr_UpdateRumble(PadMgr* padMgr) {
// "Rumble pack brrr" // "Rumble pack brrr"
PADMGR_LOG(i, "振動パック ぶるぶるぶるぶる"); PADMGR_LOG(i, "振動パック ぶるぶるぶるぶる");
// This should be the osMotorStart macro, however the temporary variable motorStart is if (osMotorStart(&padMgr->rumblePfs[i]) != 0) {
// currently required for matching
if (__osMotorAccess(&padMgr->rumblePfs[i], motorStart) != 0) {
padMgr->pakType[i] = CONT_PAK_NONE; padMgr->pakType[i] = CONT_PAK_NONE;
// "A communication error has occurred with the vibration pack" // "A communication error has occurred with the vibration pack"
@ -186,7 +185,7 @@ void PadMgr_UpdateRumble(PadMgr* padMgr) {
} }
} else { } else {
if (padMgr->pakType[i] != CONT_PAK_NONE) { if (padMgr->pakType[i] != CONT_PAK_NONE) {
if (padMgr->pakType[i] == CONT_PAK_RUMBLE) { if (padMgr->pakType[i] == CONT_PAK_RUMBLE || !OOT_DEBUG) {
// "It seems that a vibration pack was pulled out" // "It seems that a vibration pack was pulled out"
PADMGR_LOG(i, "振動パックが抜かれたようです"); PADMGR_LOG(i, "振動パックが抜かれたようです");
padMgr->pakType[i] = CONT_PAK_NONE; padMgr->pakType[i] = CONT_PAK_NONE;
@ -352,9 +351,9 @@ void PadMgr_UpdateInputs(PadMgr* padMgr) {
} }
void PadMgr_HandleRetrace(PadMgr* padMgr) { void PadMgr_HandleRetrace(PadMgr* padMgr) {
s32 i;
OSMesgQueue* serialEventQueue = PadMgr_AcquireSerialEventQueue(padMgr); OSMesgQueue* serialEventQueue = PadMgr_AcquireSerialEventQueue(padMgr);
u32 mask; u32 mask;
s32 i;
// Begin reading controller data // Begin reading controller data
osContStartReadData(serialEventQueue); osContStartReadData(serialEventQueue);
@ -368,6 +367,12 @@ void PadMgr_HandleRetrace(PadMgr* padMgr) {
osRecvMesg(serialEventQueue, NULL, OS_MESG_BLOCK); osRecvMesg(serialEventQueue, NULL, OS_MESG_BLOCK);
osContGetReadData(padMgr->pads); osContGetReadData(padMgr->pads);
#if !OOT_DEBUG
// Clear controllers 2 and 4
bzero(&padMgr->pads[1], sizeof(OSContPad));
bzero(&padMgr->pads[3], sizeof(OSContPad));
#endif
// If resetting, clear all controllers // If resetting, clear all controllers
if (padMgr->isResetting) { if (padMgr->isResetting) {
bzero(padMgr->pads, sizeof(padMgr->pads)); bzero(padMgr->pads, sizeof(padMgr->pads));

View file

@ -33,19 +33,19 @@
* - [29:24] 6-bit relocation type describing which relocation operation should be performed. Same as ELF32 MIPS. * - [29:24] 6-bit relocation type describing which relocation operation should be performed. Same as ELF32 MIPS.
* - [23: 0] 24-bit section-relative offset indicating where in the section to apply this relocation. * - [23: 0] 24-bit section-relative offset indicating where in the section to apply this relocation.
* *
* @param allocatedRamAddress Memory address the binary was loaded at. * @param allocatedRamAddr Memory address the binary was loaded at.
* @param ovlRelocs Overlay relocation section containing overlay section layout and runtime relocations. * @param ovlRelocs Overlay relocation section containing overlay section layout and runtime relocations.
* @param vramStart Virtual RAM address that the overlay was compiled at. * @param vramStart Virtual RAM address that the overlay was compiled at.
*/ */
void Overlay_Relocate(void* allocatedRamAddress, OverlayRelocationSection* ovlRelocs, void* vramStart) { void Overlay_Relocate(void* allocatedRamAddr, OverlayRelocationSection* ovlRelocs, void* vramStart) {
uintptr_t sections[RELOC_SECTION_MAX]; uintptr_t sections[RELOC_SECTION_MAX];
u32 relocatedValue;
u32 dbg;
u32 relocOffset;
u32 relocData;
uintptr_t unrelocatedAddress;
u32 i;
u32* relocDataP; u32* relocDataP;
u32 reloc;
u32 relocData;
u32 isLoNeg;
uintptr_t allocu32 = (uintptr_t)allocatedRamAddr;
u32 i;
u32* regValP;
//! MIPS ELF relocation does not generally require tracking register values, so at first glance it appears this //! MIPS ELF relocation does not generally require tracking register values, so at first glance it appears this
//! register tracking was an unnecessary complication. However there is a bug in the IDO compiler that can cause //! register tracking was an unnecessary complication. However there is a bug in the IDO compiler that can cause
//! relocations to be emitted in the wrong order under rare circumstances when the compiler attempts to reuse a //! relocations to be emitted in the wrong order under rare circumstances when the compiler attempts to reuse a
@ -54,21 +54,16 @@ void Overlay_Relocate(void* allocatedRamAddress, OverlayRelocationSection* ovlRe
//! due to the incorrect ordering. //! due to the incorrect ordering.
u32* luiRefs[32]; u32* luiRefs[32];
u32 luiVals[32]; u32 luiVals[32];
uintptr_t relocatedAddress;
u32 reloc;
u32* luiInstRef; u32* luiInstRef;
uintptr_t allocu32 = (uintptr_t)allocatedRamAddress; u32 dbg;
u32* regValP; s32 relocOffset = 0;
u32 isLoNeg; u32 relocatedValue = 0;
uintptr_t unrelocatedAddress = 0;
uintptr_t relocatedAddress = 0;
s32 pad; s32 pad;
relocOffset = 0;
relocatedValue = 0;
unrelocatedAddress = 0;
relocatedAddress = 0;
if (gOverlayLogSeverity >= 3) { if (gOverlayLogSeverity >= 3) {
PRINTF("DoRelocation(%08x, %08x, %08x)\n", allocatedRamAddress, ovlRelocs, vramStart); PRINTF("DoRelocation(%08x, %08x, %08x)\n", allocatedRamAddr, ovlRelocs, vramStart);
PRINTF("text=%08x, data=%08x, rodata=%08x, bss=%08x\n", ovlRelocs->textSize, ovlRelocs->dataSize, PRINTF("text=%08x, data=%08x, rodata=%08x, bss=%08x\n", ovlRelocs->textSize, ovlRelocs->dataSize,
ovlRelocs->rodataSize, ovlRelocs->bssSize); ovlRelocs->rodataSize, ovlRelocs->bssSize);
} }
@ -105,12 +100,13 @@ void Overlay_Relocate(void* allocatedRamAddress, OverlayRelocationSection* ovlRe
// Handles 26-bit address relocation, used for jumps and jals. // Handles 26-bit address relocation, used for jumps and jals.
// Extract the address from the target field of the J-type MIPS instruction. // Extract the address from the target field of the J-type MIPS instruction.
// Relocate the address and update the instruction. // Relocate the address and update the instruction.
if (1) {
relocOffset = PHYS_TO_K0(MIPS_JUMP_TARGET(*relocDataP)) - (uintptr_t)vramStart;
unrelocatedAddress = PHYS_TO_K0(MIPS_JUMP_TARGET(*relocDataP)); unrelocatedAddress = PHYS_TO_K0(MIPS_JUMP_TARGET(*relocDataP));
relocOffset = unrelocatedAddress - (uintptr_t)vramStart;
relocatedValue = (*relocDataP & 0xFC000000) | (((allocu32 + relocOffset) & 0x0FFFFFFF) >> 2); relocatedValue = (*relocDataP & 0xFC000000) | (((allocu32 + relocOffset) & 0x0FFFFFFF) >> 2);
relocatedAddress = PHYS_TO_K0(MIPS_JUMP_TARGET(relocatedValue)); relocatedAddress = PHYS_TO_K0(MIPS_JUMP_TARGET(relocatedValue));
*relocDataP = relocatedValue; *relocDataP = relocatedValue;
}
break; break;
case R_MIPS_HI16 << RELOC_TYPE_SHIFT: case R_MIPS_HI16 << RELOC_TYPE_SHIFT:

View file

@ -45,34 +45,43 @@
#define RDP_DONE_MSG 668 #define RDP_DONE_MSG 668
#define NOTIFY_MSG 670 // original name: ENTRY_MSG #define NOTIFY_MSG 670 // original name: ENTRY_MSG
vs32 sLogScheduler = false; vs32 sSchedDebugPrintfEnabled = false;
OSTime sRSPGfxTimeStart; OSTime sRSPGfxTimeStart;
OSTime sRSPAudioTimeStart; OSTime sRSPAudioTimeStart;
OSTime sRSPOtherTimeStart; OSTime sRSPOtherTimeStart;
OSTime sRDPTimeStart; OSTime sRDPTimeStart;
#if OOT_DEBUG
#define SCHED_DEBUG_PRINTF \
if (sSchedDebugPrintfEnabled) \
PRINTF
#elif IDO_PRINTF_WORKAROUND
#define SCHED_DEBUG_PRINTF(args) (void)0
#else
#define SCHED_DEBUG_PRINTF(format, ...) (void)0
#endif
/** /**
* Set the current framebuffer to the swapbuffer pointed to by the provided cfb * Set the current framebuffer to the swapbuffer pointed to by the provided cfb
*/ */
void Sched_SwapFrameBufferImpl(CfbInfo* cfbInfo) { void Sched_SwapFrameBufferImpl(CfbInfo* cfbInfo) {
u16 width;
LOG_UTILS_CHECK_VALID_POINTER("cfbinfo->swapbuffer", cfbInfo->swapBuffer, "../sched.c", 340); LOG_UTILS_CHECK_VALID_POINTER("cfbinfo->swapbuffer", cfbInfo->swapBuffer, "../sched.c", 340);
if (cfbInfo->swapBuffer != NULL) { if (cfbInfo->swapBuffer != NULL) {
// Register the swapbuffer to display on next VI // Register the swapbuffer to display on next VI
osViSwapBuffer(cfbInfo->swapBuffer); osViSwapBuffer(cfbInfo->swapBuffer);
cfbInfo->updateTimer = cfbInfo->updateRate; cfbInfo->updateTimer = cfbInfo->updateRate;
SCHED_DEBUG_PRINTF("osViSwapBuffer %08x %08x %08x\n", osViGetCurrentFramebuffer(), osViGetNextFramebuffer(),
if (sLogScheduler) {
PRINTF("osViSwapBuffer %08x %08x %08x\n", osViGetCurrentFramebuffer(), osViGetNextFramebuffer(),
(cfbInfo != NULL) ? cfbInfo->swapBuffer : NULL); (cfbInfo != NULL) ? cfbInfo->swapBuffer : NULL);
{
u16 width = (cfbInfo->viMode != NULL) ? cfbInfo->viMode->comRegs.width : (u32)gScreenWidth;
Fault_SetFrameBuffer(cfbInfo->swapBuffer, width, 16);
} }
width = (cfbInfo->viMode != NULL) ? cfbInfo->viMode->comRegs.width : (u32)gScreenWidth; #if OOT_DEBUG
Fault_SetFrameBuffer(cfbInfo->swapBuffer, width, 16);
if (R_HREG_MODE == HREG_MODE_SCHED && R_SCHED_INIT != HREG_MODE_SCHED) { if (R_HREG_MODE == HREG_MODE_SCHED && R_SCHED_INIT != HREG_MODE_SCHED) {
R_SCHED_TOGGLE_SPECIAL_FEATURES = 0; R_SCHED_TOGGLE_SPECIAL_FEATURES = 0;
R_SCHED_GAMMA_ON = 0; R_SCHED_GAMMA_ON = 0;
@ -100,6 +109,7 @@ void Sched_SwapFrameBufferImpl(CfbInfo* cfbInfo) {
osViSetSpecialFeatures(R_SCHED_GAMMA_DITHER_ON ? OS_VI_GAMMA_DITHER_ON : OS_VI_GAMMA_DITHER_OFF); osViSetSpecialFeatures(R_SCHED_GAMMA_DITHER_ON ? OS_VI_GAMMA_DITHER_ON : OS_VI_GAMMA_DITHER_OFF);
osViSetSpecialFeatures(R_SCHED_DIVOT_ON ? OS_VI_DIVOT_ON : OS_VI_DIVOT_OFF); osViSetSpecialFeatures(R_SCHED_DIVOT_ON ? OS_VI_DIVOT_ON : OS_VI_DIVOT_OFF);
} }
#endif
} }
cfbInfo->unk_10 = 0; cfbInfo->unk_10 = 0;
@ -117,6 +127,7 @@ void Sched_SwapFrameBuffer(Scheduler* sc, CfbInfo* cfbInfo) {
} }
void Sched_HandlePreNMI(Scheduler* sc) { void Sched_HandlePreNMI(Scheduler* sc) {
#if OOT_DEBUG
OSTime now; OSTime now;
if (sc->curRSPTask != NULL) { if (sc->curRSPTask != NULL) {
@ -143,6 +154,7 @@ void Sched_HandlePreNMI(Scheduler* sc) {
} }
} }
} }
#endif
} }
void Sched_HandleNMI(Scheduler* sc) { void Sched_HandleNMI(Scheduler* sc) {
@ -161,10 +173,9 @@ void Sched_QueueTask(Scheduler* sc, OSScTask* task) {
463); 463);
if (type == M_AUDTASK) { if (type == M_AUDTASK) {
if (sLogScheduler) {
// "You have entered an audio task" // "You have entered an audio task"
PRINTF("オーディオタスクをエントリしました\n"); SCHED_DEBUG_PRINTF("オーディオタスクをエントリしました\n");
}
// Add to audio queue // Add to audio queue
if (sc->audioListTail != NULL) { if (sc->audioListTail != NULL) {
sc->audioListTail->next = task; sc->audioListTail->next = task;
@ -176,10 +187,10 @@ void Sched_QueueTask(Scheduler* sc, OSScTask* task) {
// Set audio flag // Set audio flag
sc->doAudio = true; sc->doAudio = true;
} else { } else {
if (sLogScheduler) {
// "Entered graph task" // "Entered graph task"
PRINTF("グラフタスクをエントリしました\n"); SCHED_DEBUG_PRINTF("グラフタスクをエントリしました\n");
}
// Add to graphics queue // Add to graphics queue
if (sc->gfxListTail != NULL) { if (sc->gfxListTail != NULL) {
sc->gfxListTail->next = task; sc->gfxListTail->next = task;
@ -202,9 +213,7 @@ void Sched_Yield(Scheduler* sc) {
// Send yield request // Send yield request
osSpTaskYield(); osSpTaskYield();
if (sLogScheduler) { SCHED_DEBUG_PRINTF("%08d:osSpTaskYield\n", (u32)(OS_CYCLES_TO_USEC(osGetTime())));
PRINTF("%08d:osSpTaskYield\n", (u32)(OS_CYCLES_TO_USEC(osGetTime())));
}
} }
} }
@ -405,11 +414,9 @@ void Sched_RunTask(Scheduler* sc, OSScTask* spTask, OSScTask* dpTask) {
// Run RSP // Run RSP
osSpTaskStartGo(&spTask->list); osSpTaskStartGo(&spTask->list);
if (sLogScheduler) { SCHED_DEBUG_PRINTF(
PRINTF(
"%08d:osSpTaskStartGo(%08x) %s\n", (u32)OS_CYCLES_TO_USEC(osGetTime()), &spTask->list, "%08d:osSpTaskStartGo(%08x) %s\n", (u32)OS_CYCLES_TO_USEC(osGetTime()), &spTask->list,
(spTask->list.t.type == M_AUDTASK ? "AUDIO" : (spTask->list.t.type == M_GFXTASK ? "GRAPH" : "OTHER"))); (spTask->list.t.type == M_AUDTASK ? "AUDIO" : (spTask->list.t.type == M_GFXTASK ? "GRAPH" : "OTHER")));
}
// Set currently running RSP task // Set currently running RSP task
sc->curRSPTask = spTask; sc->curRSPTask = spTask;
@ -442,9 +449,8 @@ void Sched_HandleNotification(Scheduler* sc) {
// signal to the currently running task to yield the RSP so that the audio task may // signal to the currently running task to yield the RSP so that the audio task may
// be ran as soon as possible. // be ran as soon as possible.
if (sc->doAudio && sc->curRSPTask != NULL) { if (sc->doAudio && sc->curRSPTask != NULL) {
if (sLogScheduler) { SCHED_DEBUG_PRINTF("[YIELD B]");
PRINTF("[YIELD B]");
}
Sched_Yield(sc); Sched_Yield(sc);
return; return;
} }
@ -454,15 +460,12 @@ void Sched_HandleNotification(Scheduler* sc) {
if (Sched_Schedule(sc, &nextRSP, &nextRDP, state) != state) { if (Sched_Schedule(sc, &nextRSP, &nextRDP, state) != state) {
Sched_RunTask(sc, nextRSP, nextRDP); Sched_RunTask(sc, nextRSP, nextRDP);
} }
if (sLogScheduler) { SCHED_DEBUG_PRINTF("EN sc:%08x sp:%08x dp:%08x state:%x\n", sc, nextRSP, nextRDP, state);
PRINTF("EN sc:%08x sp:%08x dp:%08x state:%x\n", sc, nextRSP, nextRDP, state);
}
} }
void Sched_HandleRetrace(Scheduler* sc) { void Sched_HandleRetrace(Scheduler* sc) {
if (sLogScheduler) { SCHED_DEBUG_PRINTF("%08d:scHandleRetrace %08x\n", (u32)OS_CYCLES_TO_USEC(osGetTime()), osViGetCurrentFramebuffer());
PRINTF("%08d:scHandleRetrace %08x\n", (u32)OS_CYCLES_TO_USEC(osGetTime()), osViGetCurrentFramebuffer());
}
ViConfig_UpdateBlack(); ViConfig_UpdateBlack();
sc->retraceCount++; sc->retraceCount++;
@ -490,11 +493,9 @@ void Sched_HandleRetrace(Scheduler* sc) {
} }
} }
if (sLogScheduler) { SCHED_DEBUG_PRINTF("%08x %08x %08x %d\n", osViGetCurrentFramebuffer(), osViGetNextFramebuffer(),
PRINTF("%08x %08x %08x %d\n", osViGetCurrentFramebuffer(), osViGetNextFramebuffer(),
(sc->pendingSwapBuf1 != NULL) ? sc->pendingSwapBuf1->swapBuffer : NULL, (sc->pendingSwapBuf1 != NULL) ? sc->pendingSwapBuf1->swapBuffer : NULL,
(sc->curBuf != NULL) ? sc->curBuf->updateTimer : 0); (sc->curBuf != NULL) ? sc->curBuf->updateTimer : 0);
}
// Run the notification handler to enqueue any waiting tasks and possibly run one // Run the notification handler to enqueue any waiting tasks and possibly run one
Sched_HandleNotification(sc); Sched_HandleNotification(sc);
@ -524,14 +525,11 @@ void Sched_HandleRSPDone(Scheduler* sc) {
curRSPTask = sc->curRSPTask; curRSPTask = sc->curRSPTask;
sc->curRSPTask = NULL; sc->curRSPTask = NULL;
if (sLogScheduler) { SCHED_DEBUG_PRINTF("RSP DONE %d %d", curRSPTask->state & OS_SC_YIELD, osSpTaskYielded(&curRSPTask->list));
PRINTF("RSP DONE %d %d", curRSPTask->state & OS_SC_YIELD, osSpTaskYielded(&curRSPTask->list));
}
if ((curRSPTask->state & OS_SC_YIELD) && osSpTaskYielded(&curRSPTask->list)) { if ((curRSPTask->state & OS_SC_YIELD) && osSpTaskYielded(&curRSPTask->list)) {
if (sLogScheduler) { SCHED_DEBUG_PRINTF("[YIELDED]\n");
PRINTF("[YIELDED]\n");
}
// Task yielded, set yielded state // Task yielded, set yielded state
curRSPTask->state |= OS_SC_YIELDED; curRSPTask->state |= OS_SC_YIELDED;
// Add it to the front of the queue // Add it to the front of the queue
@ -541,9 +539,7 @@ void Sched_HandleRSPDone(Scheduler* sc) {
sc->gfxListTail = curRSPTask; sc->gfxListTail = curRSPTask;
} }
} else { } else {
if (sLogScheduler) { SCHED_DEBUG_PRINTF("[NOT YIELDED]\n");
PRINTF("[NOT YIELDED]\n");
}
// Task has completed on the RSP, unset RSP flag and check if the task is fully complete // Task has completed on the RSP, unset RSP flag and check if the task is fully complete
curRSPTask->state &= ~OS_SC_SP; curRSPTask->state &= ~OS_SC_SP;
Sched_TaskComplete(sc, curRSPTask); Sched_TaskComplete(sc, curRSPTask);
@ -554,9 +550,7 @@ void Sched_HandleRSPDone(Scheduler* sc) {
if (Sched_Schedule(sc, &nextRSP, &nextRDP, state) != state) { if (Sched_Schedule(sc, &nextRSP, &nextRDP, state) != state) {
Sched_RunTask(sc, nextRSP, nextRDP); Sched_RunTask(sc, nextRSP, nextRDP);
} }
if (sLogScheduler) { SCHED_DEBUG_PRINTF("SP sc:%08x sp:%08x dp:%08x state:%x\n", sc, nextRSP, nextRDP, state);
PRINTF("SP sc:%08x sp:%08x dp:%08x state:%x\n", sc, nextRSP, nextRDP, state);
}
} }
/** /**
@ -588,9 +582,7 @@ void Sched_HandleRDPDone(Scheduler* sc) {
if (Sched_Schedule(sc, &nextRSP, &nextRDP, state) != state) { if (Sched_Schedule(sc, &nextRSP, &nextRDP, state) != state) {
Sched_RunTask(sc, nextRSP, nextRDP); Sched_RunTask(sc, nextRSP, nextRDP);
} }
if (sLogScheduler) { SCHED_DEBUG_PRINTF("DP sc:%08x sp:%08x dp:%08x state:%x\n", sc, nextRSP, nextRDP, state);
PRINTF("DP sc:%08x sp:%08x dp:%08x state:%x\n", sc, nextRSP, nextRDP, state);
}
} }
/** /**
@ -601,9 +593,7 @@ void Sched_HandleRDPDone(Scheduler* sc) {
* Original name: osScKickEntryMsg * Original name: osScKickEntryMsg
*/ */
void Sched_Notify(Scheduler* sc) { void Sched_Notify(Scheduler* sc) {
if (sLogScheduler) { SCHED_DEBUG_PRINTF("osScKickEntryMsg\n");
PRINTF("osScKickEntryMsg\n");
}
osSendMesg(&sc->interruptQueue, (OSMesg)NOTIFY_MSG, OS_MESG_BLOCK); osSendMesg(&sc->interruptQueue, (OSMesg)NOTIFY_MSG, OS_MESG_BLOCK);
} }
@ -613,41 +603,38 @@ void Sched_ThreadEntry(void* arg) {
Scheduler* sc = (Scheduler*)arg; Scheduler* sc = (Scheduler*)arg;
while (true) { while (true) {
if (sLogScheduler) {
// "%08d: standby" // "%08d: standby"
PRINTF("%08d:待機中\n", (u32)OS_CYCLES_TO_USEC(osGetTime())); SCHED_DEBUG_PRINTF("%08d:待機中\n", (u32)OS_CYCLES_TO_USEC(osGetTime()));
}
// Await interrupt messages, either from the OS, IrqMgr, or another thread // Await interrupt messages, either from the OS, IrqMgr, or another thread
osRecvMesg(&sc->interruptQueue, &msg, OS_MESG_BLOCK); osRecvMesg(&sc->interruptQueue, &msg, OS_MESG_BLOCK);
switch ((s32)msg) { switch ((s32)msg) {
case NOTIFY_MSG: case NOTIFY_MSG:
if (sLogScheduler) { SCHED_DEBUG_PRINTF("%08d:ENTRY_MSG\n", (u32)OS_CYCLES_TO_USEC(osGetTime()));
PRINTF("%08d:ENTRY_MSG\n", (u32)OS_CYCLES_TO_USEC(osGetTime()));
}
Sched_HandleNotification(sc); Sched_HandleNotification(sc);
continue; continue;
case RSP_DONE_MSG: case RSP_DONE_MSG:
if (sLogScheduler) { SCHED_DEBUG_PRINTF("%08d:RSP_DONE_MSG\n", (u32)OS_CYCLES_TO_USEC(osGetTime()));
PRINTF("%08d:RSP_DONE_MSG\n", (u32)OS_CYCLES_TO_USEC(osGetTime()));
}
Sched_HandleRSPDone(sc); Sched_HandleRSPDone(sc);
continue; continue;
case RDP_DONE_MSG: case RDP_DONE_MSG:
if (sLogScheduler) { SCHED_DEBUG_PRINTF("%08d:RDP_DONE_MSG\n", (u32)OS_CYCLES_TO_USEC(osGetTime()));
PRINTF("%08d:RDP_DONE_MSG\n", (u32)OS_CYCLES_TO_USEC(osGetTime()));
}
Sched_HandleRDPDone(sc); Sched_HandleRDPDone(sc);
continue; continue;
} }
switch (((OSScMsg*)msg)->type) { switch (((OSScMsg*)msg)->type) {
case OS_SC_RETRACE_MSG: case OS_SC_RETRACE_MSG:
Sched_HandleRetrace(sc); Sched_HandleRetrace(sc);
continue; continue;
case OS_SC_PRE_NMI_MSG: case OS_SC_PRE_NMI_MSG:
Sched_HandlePreNMI(sc); Sched_HandlePreNMI(sc);
continue; continue;
case OS_SC_NMI_MSG: case OS_SC_NMI_MSG:
Sched_HandleNMI(sc); Sched_HandleNMI(sc);
continue; continue;

View file

@ -86,7 +86,7 @@ void Letterbox_Update(s32 updateRate) {
sLetterboxState = LETTERBOX_STATE_IDLE; sLetterboxState = LETTERBOX_STATE_IDLE;
} }
if (R_HREG_MODE == HREG_MODE_LETTERBOX) { if (OOT_DEBUG && (R_HREG_MODE == HREG_MODE_LETTERBOX)) {
if (R_LETTERBOX_INIT != HREG_MODE_LETTERBOX) { if (R_LETTERBOX_INIT != HREG_MODE_LETTERBOX) {
R_LETTERBOX_INIT = HREG_MODE_LETTERBOX; R_LETTERBOX_INIT = HREG_MODE_LETTERBOX;
R_LETTERBOX_ENABLE_LOGS = 0; R_LETTERBOX_ENABLE_LOGS = 0;

View file

@ -2,8 +2,8 @@
#include "terminal.h" #include "terminal.h"
/** /**
* How much time the audio update on the audio thread (`func_800E4FE0`) took in total, between scheduling the last two * How much time the audio update on the audio thread (`AudioThread_Update`) took in total, between scheduling the last
* graphics tasks. * two graphics tasks.
*/ */
volatile OSTime gAudioThreadUpdateTimeTotalPerGfxTask; volatile OSTime gAudioThreadUpdateTimeTotalPerGfxTask;

View file

@ -13,11 +13,19 @@ void SysCfb_Init(s32 n64dd) {
tmpFbEnd = 0x8044BE80; tmpFbEnd = 0x8044BE80;
if (n64dd == 1) { if (n64dd == 1) {
PRINTF("RAM 8M mode (N64DD対応)\n"); // "RAM 8M mode (N64DD compatible)" PRINTF("RAM 8M mode (N64DD対応)\n"); // "RAM 8M mode (N64DD compatible)"
#if OOT_DEBUG
sSysCfbEnd = 0x805FB000; sSysCfbEnd = 0x805FB000;
#else
sSysCfbEnd = 0x80600000;
#endif
} else { } else {
// "The margin for this version is %dK bytes" // "The margin for this version is %dK bytes"
PRINTF("このバージョンのマージンは %dK バイトです\n", (0x4BC00 / 1024)); PRINTF("このバージョンのマージンは %dK バイトです\n", (0x4BC00 / 1024));
#if OOT_DEBUG
sSysCfbEnd = tmpFbEnd; sSysCfbEnd = tmpFbEnd;
#else
sSysCfbEnd = 0x80400000;
#endif
} }
} else if (osMemSize >= 0x400000) { } else if (osMemSize >= 0x400000) {
PRINTF("RAM4M mode\n"); PRINTF("RAM4M mode\n");
@ -28,6 +36,9 @@ void SysCfb_Init(s32 n64dd) {
screenSize = SCREEN_WIDTH * SCREEN_HEIGHT; screenSize = SCREEN_WIDTH * SCREEN_HEIGHT;
sSysCfbEnd &= ~0x3F; sSysCfbEnd &= ~0x3F;
if (1) {}
// "The final address used by the system is %08x" // "The final address used by the system is %08x"
PRINTF("システムが使用する最終アドレスは %08x です\n", sSysCfbEnd); PRINTF("システムが使用する最終アドレスは %08x です\n", sSysCfbEnd);
sSysCfbFbPtr[0] = sSysCfbEnd - (screenSize * 4); sSysCfbFbPtr[0] = sSysCfbEnd - (screenSize * 4);

View file

@ -922,8 +922,7 @@ f32 Math3D_Plane(Plane* plane, Vec3f* pointOnPlane) {
* `nx`, `ny`, `nz`, and `originDist` * `nx`, `ny`, `nz`, and `originDist`
*/ */
f32 Math3D_UDistPlaneToPos(f32 nx, f32 ny, f32 nz, f32 originDist, Vec3f* p) { f32 Math3D_UDistPlaneToPos(f32 nx, f32 ny, f32 nz, f32 originDist, Vec3f* p) {
if (OOT_DEBUG && IS_ZERO(sqrtf(SQ(nx) + SQ(ny) + SQ(nz)))) {
if (IS_ZERO(sqrtf(SQ(nx) + SQ(ny) + SQ(nz)))) {
PRINTF(VT_COL(YELLOW, BLACK)); PRINTF(VT_COL(YELLOW, BLACK));
// "Math3DLengthPlaneAndPos(): Normal size is near zero %f %f %f" // "Math3DLengthPlaneAndPos(): Normal size is near zero %f %f %f"
PRINTF("Math3DLengthPlaneAndPos():法線size がゼロ近いです%f %f %f\n", nx, ny, nz); PRINTF("Math3DLengthPlaneAndPos():法線size がゼロ近いです%f %f %f\n", nx, ny, nz);
@ -1823,7 +1822,6 @@ s32 Math3D_CylTriVsIntersect(Cylinder16* cyl, TriNorm* tri, Vec3f* intersect) {
Vec3f cylIntersectCenter; Vec3f cylIntersectCenter;
Vec3f midpointv0v1; Vec3f midpointv0v1;
Vec3f diffMidpointIntersect; Vec3f diffMidpointIntersect;
f32 distFromCylYIntersectTov0v1;
s32 pad; s32 pad;
cylBottom = (f32)cyl->pos.y + cyl->yShift; cylBottom = (f32)cyl->pos.y + cyl->yShift;
@ -1865,6 +1863,7 @@ s32 Math3D_CylTriVsIntersect(Cylinder16* cyl, TriNorm* tri, Vec3f* intersect) {
if (Math3D_TriChkLineSegParaYIntersect(&tri->vtx[0], &tri->vtx[1], &tri->vtx[2], tri->plane.normal.x, if (Math3D_TriChkLineSegParaYIntersect(&tri->vtx[0], &tri->vtx[1], &tri->vtx[2], tri->plane.normal.x,
tri->plane.normal.y, tri->plane.normal.z, tri->plane.originDist, cyl->pos.z, tri->plane.normal.y, tri->plane.normal.z, tri->plane.originDist, cyl->pos.z,
cyl->pos.x, &yIntersect, cylBottom, cylTop)) { cyl->pos.x, &yIntersect, cylBottom, cylTop)) {
f32 distFromCylYIntersectTov0v1;
cylIntersectCenter.x = cyl->pos.x; cylIntersectCenter.x = cyl->pos.x;
cylIntersectCenter.y = yIntersect; cylIntersectCenter.y = yIntersect;
@ -2145,8 +2144,10 @@ s32 Math3D_YZInSphere(Sphere16* sphere, f32 y, f32 z) {
return false; return false;
} }
#if OOT_DEBUG
void Math3D_DrawSphere(PlayState* play, Sphere16* sph) { void Math3D_DrawSphere(PlayState* play, Sphere16* sph) {
} }
void Math3D_DrawCylinder(PlayState* play, Cylinder16* cyl) { void Math3D_DrawCylinder(PlayState* play, Cylinder16* cyl) {
} }
#endif

View file

@ -603,7 +603,7 @@ Mtx* Matrix_MtxFToMtx(MtxF* src, Mtx* dest) {
return dest; return dest;
} }
#ifdef OOT_DEBUG #if OOT_DEBUG
Mtx* Matrix_ToMtx(Mtx* dest, char* file, s32 line) { Mtx* Matrix_ToMtx(Mtx* dest, char* file, s32 line) {
return Matrix_MtxFToMtx(MATRIX_CHECK_FLOATS(sCurrentMatrix, file, line), dest); return Matrix_MtxFToMtx(MATRIX_CHECK_FLOATS(sCurrentMatrix, file, line), dest);
@ -969,6 +969,7 @@ void Matrix_RotateAxis(f32 angle, Vec3f* axis, u8 mode) {
} }
} }
#if OOT_DEBUG
MtxF* Matrix_CheckFloats(MtxF* mf, char* file, s32 line) { MtxF* Matrix_CheckFloats(MtxF* mf, char* file, s32 line) {
s32 i, j; s32 i, j;
@ -989,20 +990,21 @@ MtxF* Matrix_CheckFloats(MtxF* mf, char* file, s32 line) {
return mf; return mf;
} }
#endif
void Matrix_SetTranslateUniformScaleMtxF(MtxF* mf, f32 scale, f32 translateX, f32 translateY, f32 translateZ) { void Matrix_SetTranslateUniformScaleMtxF(MtxF* mf, f32 scale, f32 translateX, f32 translateY, f32 translateZ) {
mf->xx = scale;
mf->yx = 0.0f; mf->yx = 0.0f;
mf->zx = 0.0f; mf->zx = 0.0f;
mf->wx = 0.0f; mf->wx = 0.0f;
mf->xy = 0.0f; mf->xy = 0.0f;
mf->yy = scale;
mf->zy = 0.0f; mf->zy = 0.0f;
mf->wy = 0.0f; mf->wy = 0.0f;
mf->xz = 0.0f; mf->xz = 0.0f;
mf->yz = 0.0f; mf->yz = 0.0f;
mf->wz = 0.0f;
mf->xx = scale;
mf->yy = scale;
mf->zz = scale; mf->zz = scale;
mf->wz = 0.0f;
mf->xw = translateX; mf->xw = translateX;
mf->yw = translateY; mf->yw = translateY;
mf->zw = translateZ; mf->zw = translateZ;

View file

@ -147,5 +147,7 @@ void RumbleMgr_Init(RumbleMgr* rumbleMgr) {
} }
void RumbleMgr_Destroy(RumbleMgr* rumbleMgr) { void RumbleMgr_Destroy(RumbleMgr* rumbleMgr) {
#if OOT_DEBUG
bzero(rumbleMgr, sizeof(RumbleMgr)); bzero(rumbleMgr, sizeof(RumbleMgr));
#endif
} }

View file

@ -4,9 +4,11 @@
#define LOG_SEVERITY_ERROR 2 #define LOG_SEVERITY_ERROR 2
#define LOG_SEVERITY_VERBOSE 3 #define LOG_SEVERITY_VERBOSE 3
s32 gSystemArenaLogSeverity = LOG_SEVERITY_NOLOG;
Arena gSystemArena; Arena gSystemArena;
#if OOT_DEBUG
s32 gSystemArenaLogSeverity = LOG_SEVERITY_NOLOG;
void SystemArena_CheckPointer(void* ptr, u32 size, const char* name, const char* action) { void SystemArena_CheckPointer(void* ptr, u32 size, const char* name, const char* action) {
if (ptr == NULL) { if (ptr == NULL) {
if (gSystemArenaLogSeverity >= LOG_SEVERITY_ERROR) { if (gSystemArenaLogSeverity >= LOG_SEVERITY_ERROR) {
@ -21,53 +23,66 @@ void SystemArena_CheckPointer(void* ptr, u32 size, const char* name, const char*
} }
} }
#define SYSTEM_ARENA_CHECK_POINTER(ptr, size, name, action) SystemArena_CheckPointer(ptr, size, name, action)
#else
#define SYSTEM_ARENA_CHECK_POINTER(ptr, size, name, action) (void)0
#endif
void* SystemArena_Malloc(u32 size) { void* SystemArena_Malloc(u32 size) {
void* ptr = __osMalloc(&gSystemArena, size); void* ptr = __osMalloc(&gSystemArena, size);
SystemArena_CheckPointer(ptr, size, "malloc", "確保"); // "Secure" SYSTEM_ARENA_CHECK_POINTER(ptr, size, "malloc", "確保"); // "Secure"
return ptr; return ptr;
} }
#if OOT_DEBUG
void* SystemArena_MallocDebug(u32 size, const char* file, s32 line) { void* SystemArena_MallocDebug(u32 size, const char* file, s32 line) {
void* ptr = __osMallocDebug(&gSystemArena, size, file, line); void* ptr = __osMallocDebug(&gSystemArena, size, file, line);
SystemArena_CheckPointer(ptr, size, "malloc_DEBUG", "確保"); // "Secure" SYSTEM_ARENA_CHECK_POINTER(ptr, size, "malloc_DEBUG", "確保"); // "Secure"
return ptr; return ptr;
} }
#endif
void* SystemArena_MallocR(u32 size) { void* SystemArena_MallocR(u32 size) {
void* ptr = __osMallocR(&gSystemArena, size); void* ptr = __osMallocR(&gSystemArena, size);
SystemArena_CheckPointer(ptr, size, "malloc_r", "確保"); // "Secure" SYSTEM_ARENA_CHECK_POINTER(ptr, size, "malloc_r", "確保"); // "Secure"
return ptr; return ptr;
} }
#if OOT_DEBUG
void* SystemArena_MallocRDebug(u32 size, const char* file, s32 line) { void* SystemArena_MallocRDebug(u32 size, const char* file, s32 line) {
void* ptr = __osMallocRDebug(&gSystemArena, size, file, line); void* ptr = __osMallocRDebug(&gSystemArena, size, file, line);
SystemArena_CheckPointer(ptr, size, "malloc_r_DEBUG", "確保"); // "Secure" SYSTEM_ARENA_CHECK_POINTER(ptr, size, "malloc_r_DEBUG", "確保"); // "Secure"
return ptr; return ptr;
} }
#endif
void* SystemArena_Realloc(void* ptr, u32 newSize) { void* SystemArena_Realloc(void* ptr, u32 newSize) {
ptr = __osRealloc(&gSystemArena, ptr, newSize); ptr = __osRealloc(&gSystemArena, ptr, newSize);
SystemArena_CheckPointer(ptr, newSize, "realloc", "再確保"); // "Re-securing" SYSTEM_ARENA_CHECK_POINTER(ptr, newSize, "realloc", "再確保"); // "Re-securing"
return ptr; return ptr;
} }
#if OOT_DEBUG
void* SystemArena_ReallocDebug(void* ptr, u32 newSize, const char* file, s32 line) { void* SystemArena_ReallocDebug(void* ptr, u32 newSize, const char* file, s32 line) {
ptr = __osReallocDebug(&gSystemArena, ptr, newSize, file, line); ptr = __osReallocDebug(&gSystemArena, ptr, newSize, file, line);
SystemArena_CheckPointer(ptr, newSize, "realloc_DEBUG", "再確保"); // "Re-securing" SYSTEM_ARENA_CHECK_POINTER(ptr, newSize, "realloc_DEBUG", "再確保"); // "Re-securing"
return ptr; return ptr;
} }
#endif
void SystemArena_Free(void* ptr) { void SystemArena_Free(void* ptr) {
__osFree(&gSystemArena, ptr); __osFree(&gSystemArena, ptr);
} }
#if OOT_DEBUG
void SystemArena_FreeDebug(void* ptr, const char* file, s32 line) { void SystemArena_FreeDebug(void* ptr, const char* file, s32 line) {
__osFreeDebug(&gSystemArena, ptr, file, line); __osFreeDebug(&gSystemArena, ptr, file, line);
} }
#endif
void* SystemArena_Calloc(u32 num, u32 size) { void* SystemArena_Calloc(u32 num, u32 size) {
void* ret; void* ret;
@ -78,14 +93,16 @@ void* SystemArena_Calloc(u32 num, u32 size) {
bzero(ret, n); bzero(ret, n);
} }
SystemArena_CheckPointer(ret, n, "calloc", "確保"); SYSTEM_ARENA_CHECK_POINTER(ret, n, "calloc", "確保");
return ret; return ret;
} }
#if OOT_DEBUG
void SystemArena_Display(void) { void SystemArena_Display(void) {
PRINTF("システムヒープ表示\n"); // "System heap display" PRINTF("システムヒープ表示\n"); // "System heap display"
__osDisplayArena(&gSystemArena); __osDisplayArena(&gSystemArena);
} }
#endif
void SystemArena_GetSizes(u32* outMaxFree, u32* outFree, u32* outAlloc) { void SystemArena_GetSizes(u32* outMaxFree, u32* outFree, u32* outAlloc) {
ArenaImpl_GetSizes(&gSystemArena, outMaxFree, outFree, outAlloc); ArenaImpl_GetSizes(&gSystemArena, outMaxFree, outFree, outAlloc);
@ -96,12 +113,16 @@ void SystemArena_Check(void) {
} }
void SystemArena_Init(void* start, u32 size) { void SystemArena_Init(void* start, u32 size) {
#if OOT_DEBUG
gSystemArenaLogSeverity = LOG_SEVERITY_NOLOG; gSystemArenaLogSeverity = LOG_SEVERITY_NOLOG;
#endif
__osMallocInit(&gSystemArena, start, size); __osMallocInit(&gSystemArena, start, size);
} }
void SystemArena_Cleanup(void) { void SystemArena_Cleanup(void) {
#if OOT_DEBUG
gSystemArenaLogSeverity = LOG_SEVERITY_NOLOG; gSystemArenaLogSeverity = LOG_SEVERITY_NOLOG;
#endif
__osMallocCleanup(&gSystemArena); __osMallocCleanup(&gSystemArena);
} }

View file

@ -69,7 +69,12 @@ F3dzexFlag sUCodeDisasMtxFlags[] = {
F3DZEX_FLAG(G_MTX_PUSH, G_MTX_NOPUSH), F3DZEX_FLAG(G_MTX_PUSH, G_MTX_NOPUSH),
}; };
typedef enum { COMBINER_A = 1, COMBINER_B, COMBINER_C, COMBINER_D } CombinerArg; typedef enum {
COMBINER_A = 1,
COMBINER_B,
COMBINER_C,
COMBINER_D
} CombinerArg;
const char* UCodeDisas_GetCombineColorName(u32 value, u32 arg) { const char* UCodeDisas_GetCombineColorName(u32 value, u32 arg) {
const char* ret = "?"; const char* ret = "?";

View file

@ -11,6 +11,16 @@
static CollisionPoly* sCurCeilingPoly; static CollisionPoly* sCurCeilingPoly;
static s32 sCurCeilingBgId; static s32 sCurCeilingBgId;
#if OOT_DEBUG
#define ACTOR_DEBUG_PRINTF \
if (R_ENABLE_ACTOR_DEBUG_PRINTF) \
PRINTF
#elif IDO_PRINTF_WORKAROUND
#define ACTOR_DEBUG_PRINTF(args) (void)0
#else
#define ACTOR_DEBUG_PRINTF(format, ...) (void)0
#endif
void ActorShape_Init(ActorShape* shape, f32 yOffset, ActorShadowFunc shadowDraw, f32 shadowScale) { void ActorShape_Init(ActorShape* shape, f32 yOffset, ActorShadowFunc shadowDraw, f32 shadowScale) {
shape->yOffset = yOffset; shape->yOffset = yOffset;
shape->shadowDraw = shadowDraw; shape->shadowDraw = shadowDraw;
@ -23,7 +33,10 @@ void ActorShadow_Draw(Actor* actor, Lights* lights, PlayState* play, Gfx* dlist,
f32 temp2; f32 temp2;
MtxF sp60; MtxF sp60;
if (actor->floorPoly != NULL) { if (actor->floorPoly == NULL) {
return;
}
temp1 = actor->world.pos.y - actor->floorHeight; temp1 = actor->world.pos.y - actor->floorHeight;
if (temp1 >= -50.0f && temp1 < 500.0f) { if (temp1 >= -50.0f && temp1 < 500.0f) {
@ -54,14 +67,12 @@ void ActorShadow_Draw(Actor* actor, Lights* lights, PlayState* play, Gfx* dlist,
temp2 = (1.0f - (temp1 * (1.0f / 350))) * actor->shape.shadowScale; temp2 = (1.0f - (temp1 * (1.0f / 350))) * actor->shape.shadowScale;
Matrix_Scale(actor->scale.x * temp2, 1.0f, actor->scale.z * temp2, MTXMODE_APPLY); Matrix_Scale(actor->scale.x * temp2, 1.0f, actor->scale.z * temp2, MTXMODE_APPLY);
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEW(play->state.gfxCtx, "../z_actor.c", 1588), gSPMatrix(POLY_OPA_DISP++, MATRIX_NEW(play->state.gfxCtx, "../z_actor.c", 1588), G_MTX_MODELVIEW | G_MTX_LOAD);
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, dlist); gSPDisplayList(POLY_OPA_DISP++, dlist);
CLOSE_DISPS(play->state.gfxCtx, "../z_actor.c", 1594); CLOSE_DISPS(play->state.gfxCtx, "../z_actor.c", 1594);
} }
} }
}
void ActorShadow_DrawCircle(Actor* actor, Lights* lights, PlayState* play) { void ActorShadow_DrawCircle(Actor* actor, Lights* lights, PlayState* play) {
ActorShadow_Draw(actor, lights, play, gCircleShadowDL, NULL); ActorShadow_Draw(actor, lights, play, gCircleShadowDL, NULL);
@ -148,6 +159,8 @@ void ActorShadow_DrawFeet(Actor* actor, Lights* lights, PlayState* play) {
actor->shape.feetFloorFlag <<= 1; actor->shape.feetFloorFlag <<= 1;
distToFloor = feetPosPtr->y - *floorHeightPtr; distToFloor = feetPosPtr->y - *floorHeightPtr;
if (1) {}
if ((-1.0f <= distToFloor) && (distToFloor < 500.0f)) { if ((-1.0f <= distToFloor) && (distToFloor < 500.0f)) {
if (distToFloor <= 0.0f) { if (distToFloor <= 0.0f) {
actor->shape.feetFloorFlag++; actor->shape.feetFloorFlag++;
@ -284,13 +297,11 @@ void Actor_SetNaviToActor(TargetContext* targetCtx, Actor* actor, s32 actorCateg
} }
void func_8002C0C0(TargetContext* targetCtx, Actor* actor, PlayState* play) { void func_8002C0C0(TargetContext* targetCtx, Actor* actor, PlayState* play) {
targetCtx->arrowPointedActor = NULL; targetCtx->arrowPointedActor = targetCtx->targetedActor = targetCtx->unk_8C = targetCtx->bgmEnemy = NULL;
targetCtx->targetedActor = NULL;
targetCtx->unk_40 = 0.0f;
targetCtx->unk_8C = NULL;
targetCtx->bgmEnemy = NULL;
targetCtx->unk_4B = 0; targetCtx->unk_4B = 0;
targetCtx->unk_4C = 0; targetCtx->unk_4C = 0;
targetCtx->unk_40 = 0.0f;
Actor_SetNaviToActor(targetCtx, actor, actor->category, play); Actor_SetNaviToActor(targetCtx, actor, actor->category, play);
func_8002BE98(targetCtx, actor->category, play); func_8002BE98(targetCtx, actor->category, play);
} }
@ -304,13 +315,12 @@ void func_8002C124(TargetContext* targetCtx, PlayState* play) {
TargetContextEntry* entry; TargetContextEntry* entry;
Player* player; Player* player;
s16 spCE; s16 spCE;
f32 temp1; f32 var1;
Vec3f projTargetCenter; Vec3f projTargetCenter;
s32 spB8; s32 spB8;
f32 projTargetCappedInvW; f32 projTargetCappedInvW;
s32 spB0; s32 spB0;
s32 spAC; s32 spAC;
f32 var1;
f32 var2; f32 var2;
s32 i; s32 i;
@ -417,13 +427,6 @@ void func_8002C7BC(TargetContext* targetCtx, Player* player, Actor* actorArg, Pl
s32 actorCategory; s32 actorCategory;
Vec3f projectedFocusPos; Vec3f projectedFocusPos;
f32 cappedInvWDest; f32 cappedInvWDest;
f32 temp1;
f32 temp2;
f32 temp3;
f32 temp4;
f32 temp5;
f32 temp6;
s32 lockOnSfxId;
unkActor = NULL; unkActor = NULL;
@ -458,10 +461,12 @@ void func_8002C7BC(TargetContext* targetCtx, Player* player, Actor* actorArg, Pl
} }
if (Math_StepToF(&targetCtx->unk_40, 0.0f, 0.25f) == 0) { if (Math_StepToF(&targetCtx->unk_40, 0.0f, 0.25f) == 0) {
temp1 = 0.25f / targetCtx->unk_40; f32 temp1 = 0.25f / targetCtx->unk_40;
temp2 = unkActor->world.pos.x - targetCtx->naviRefPos.x; f32 temp2 = unkActor->world.pos.x - targetCtx->naviRefPos.x;
temp3 = (unkActor->world.pos.y + (unkActor->targetArrowOffset * unkActor->scale.y)) - targetCtx->naviRefPos.y; f32 temp3 =
temp4 = unkActor->world.pos.z - targetCtx->naviRefPos.z; (unkActor->world.pos.y + (unkActor->targetArrowOffset * unkActor->scale.y)) - targetCtx->naviRefPos.y;
f32 temp4 = unkActor->world.pos.z - targetCtx->naviRefPos.z;
targetCtx->naviRefPos.x += temp2 * temp1; targetCtx->naviRefPos.x += temp2 * temp1;
targetCtx->naviRefPos.y += temp3 * temp1; targetCtx->naviRefPos.y += temp3 * temp1;
targetCtx->naviRefPos.z += temp4 * temp1; targetCtx->naviRefPos.z += temp4 * temp1;
@ -479,6 +484,8 @@ void func_8002C7BC(TargetContext* targetCtx, Player* player, Actor* actorArg, Pl
if (actorArg != NULL) { if (actorArg != NULL) {
if (actorArg != targetCtx->targetedActor) { if (actorArg != targetCtx->targetedActor) {
s32 lockOnSfxId;
func_8002BE98(targetCtx, actorArg->category, play); func_8002BE98(targetCtx, actorArg->category, play);
targetCtx->targetedActor = actorArg; targetCtx->targetedActor = actorArg;
@ -496,8 +503,9 @@ void func_8002C7BC(TargetContext* targetCtx, Player* player, Actor* actorArg, Pl
targetCtx->targetCenterPos.z = actorArg->world.pos.z; targetCtx->targetCenterPos.z = actorArg->world.pos.z;
if (targetCtx->unk_4B == 0) { if (targetCtx->unk_4B == 0) {
temp5 = (500.0f - targetCtx->unk_44) * 3.0f; f32 temp5 = (500.0f - targetCtx->unk_44) * 3.0f;
temp6 = (temp5 < 30.0f) ? 30.0f : ((100.0f < temp5) ? 100.0f : temp5); f32 temp6 = (temp5 < 30.0f) ? 30.0f : ((100.0f < temp5) ? 100.0f : temp5);
if (Math_StepToF(&targetCtx->unk_44, 80.0f, temp6) != 0) { if (Math_StepToF(&targetCtx->unk_44, 80.0f, temp6) != 0) {
targetCtx->unk_4B++; targetCtx->unk_4B++;
} }
@ -715,9 +723,9 @@ void TitleCard_Draw(PlayState* play, TitleCardContext* titleCtx) {
if (titleCtx->alpha != 0) { if (titleCtx->alpha != 0) {
width = titleCtx->width; width = titleCtx->width;
height = titleCtx->height; height = titleCtx->height;
doubleWidth = width * 2;
titleX = (titleCtx->x * 4) - (width * 2); titleX = (titleCtx->x * 4) - (width * 2);
titleY = (titleCtx->y * 4) - (height * 2); titleY = (titleCtx->y * 4) - (height * 2);
doubleWidth = width * 2;
OPEN_DISPS(play->state.gfxCtx, "../z_actor.c", 2824); OPEN_DISPS(play->state.gfxCtx, "../z_actor.c", 2824);
@ -832,11 +840,13 @@ void Actor_Destroy(Actor* actor, PlayState* play) {
actor->destroy(actor, play); actor->destroy(actor, play);
actor->destroy = NULL; actor->destroy = NULL;
} else { } else {
#if OOT_DEBUG
overlayEntry = actor->overlayEntry; overlayEntry = actor->overlayEntry;
name = overlayEntry->name != NULL ? overlayEntry->name : ""; name = overlayEntry->name != NULL ? overlayEntry->name : "";
// "No Actor class destruct [%s]" // "No Actor class destruct [%s]"
PRINTF("Actorクラス デストラクトがありません [%s]\n" VT_RST, name); PRINTF("Actorクラス デストラクトがありません [%s]\n" VT_RST, name);
#endif
} }
} }
@ -1291,12 +1301,6 @@ void Actor_UpdateBgCheckInfo(PlayState* play, Actor* actor, f32 wallCheckHeight,
f32 sp74; f32 sp74;
s32 pad; s32 pad;
Vec3f sp64; Vec3f sp64;
s32 bgId;
CollisionPoly* wallPoly;
f32 sp58;
WaterBox* waterBox;
f32 waterBoxYSurface;
Vec3f ripplePos;
sp74 = actor->world.pos.y - actor->prevPos.y; sp74 = actor->world.pos.y - actor->prevPos.y;
@ -1305,12 +1309,16 @@ void Actor_UpdateBgCheckInfo(PlayState* play, Actor* actor, f32 wallCheckHeight,
} }
if (flags & UPDBGCHECKINFO_FLAG_0) { if (flags & UPDBGCHECKINFO_FLAG_0) {
s32 bgId;
if ((!(flags & UPDBGCHECKINFO_FLAG_7) && if ((!(flags & UPDBGCHECKINFO_FLAG_7) &&
BgCheck_EntitySphVsWall3(&play->colCtx, &sp64, &actor->world.pos, &actor->prevPos, wallCheckRadius, BgCheck_EntitySphVsWall3(&play->colCtx, &sp64, &actor->world.pos, &actor->prevPos, wallCheckRadius,
&actor->wallPoly, &bgId, actor, wallCheckHeight)) || &actor->wallPoly, &bgId, actor, wallCheckHeight)) ||
((flags & UPDBGCHECKINFO_FLAG_7) && ((flags & UPDBGCHECKINFO_FLAG_7) &&
BgCheck_EntitySphVsWall4(&play->colCtx, &sp64, &actor->world.pos, &actor->prevPos, wallCheckRadius, BgCheck_EntitySphVsWall4(&play->colCtx, &sp64, &actor->world.pos, &actor->prevPos, wallCheckRadius,
&actor->wallPoly, &bgId, actor, wallCheckHeight))) { &actor->wallPoly, &bgId, actor, wallCheckHeight))) {
CollisionPoly* wallPoly;
wallPoly = actor->wallPoly; wallPoly = actor->wallPoly;
Math_Vec3f_Copy(&actor->world.pos, &sp64); Math_Vec3f_Copy(&actor->world.pos, &sp64);
actor->wallYaw = Math_Atan2S(wallPoly->normal.z, wallPoly->normal.x); actor->wallYaw = Math_Atan2S(wallPoly->normal.z, wallPoly->normal.x);
@ -1325,6 +1333,8 @@ void Actor_UpdateBgCheckInfo(PlayState* play, Actor* actor, f32 wallCheckHeight,
sp64.z = actor->world.pos.z; sp64.z = actor->world.pos.z;
if (flags & UPDBGCHECKINFO_FLAG_1) { if (flags & UPDBGCHECKINFO_FLAG_1) {
f32 sp58;
sp64.y = actor->prevPos.y + 10.0f; sp64.y = actor->prevPos.y + 10.0f;
if (BgCheck_EntityCheckCeiling(&play->colCtx, &sp58, &sp64, (ceilingCheckHeight + sp74) - 10.0f, if (BgCheck_EntityCheckCeiling(&play->colCtx, &sp58, &sp64, (ceilingCheckHeight + sp74) - 10.0f,
&sCurCeilingPoly, &sCurCeilingBgId, actor)) { &sCurCeilingPoly, &sCurCeilingBgId, actor)) {
@ -1336,6 +1346,9 @@ void Actor_UpdateBgCheckInfo(PlayState* play, Actor* actor, f32 wallCheckHeight,
} }
if (flags & UPDBGCHECKINFO_FLAG_2) { if (flags & UPDBGCHECKINFO_FLAG_2) {
WaterBox* waterBox;
f32 waterBoxYSurface;
sp64.y = actor->prevPos.y; sp64.y = actor->prevPos.y;
func_8002E2AC(play, actor, &sp64, flags); func_8002E2AC(play, actor, &sp64, flags);
waterBoxYSurface = actor->world.pos.y; waterBoxYSurface = actor->world.pos.y;
@ -1346,6 +1359,8 @@ void Actor_UpdateBgCheckInfo(PlayState* play, Actor* actor, f32 wallCheckHeight,
actor->bgCheckFlags &= ~(BGCHECKFLAG_WATER | BGCHECKFLAG_WATER_TOUCH); actor->bgCheckFlags &= ~(BGCHECKFLAG_WATER | BGCHECKFLAG_WATER_TOUCH);
} else { } else {
if (!(actor->bgCheckFlags & BGCHECKFLAG_WATER)) { if (!(actor->bgCheckFlags & BGCHECKFLAG_WATER)) {
Vec3f ripplePos;
actor->bgCheckFlags |= BGCHECKFLAG_WATER_TOUCH; actor->bgCheckFlags |= BGCHECKFLAG_WATER_TOUCH;
if (!(flags & UPDBGCHECKINFO_FLAG_6)) { if (!(flags & UPDBGCHECKINFO_FLAG_6)) {
ripplePos.x = actor->world.pos.x; ripplePos.x = actor->world.pos.x;
@ -1377,12 +1392,15 @@ Gfx* func_8002E830(Vec3f* object, Vec3f* eye, Vec3f* lightDir, GraphicsContext*
*hilite = GRAPH_ALLOC(gfxCtx, sizeof(Hilite)); *hilite = GRAPH_ALLOC(gfxCtx, sizeof(Hilite));
#if OOT_DEBUG
if (R_HREG_MODE == HREG_MODE_PRINT_HILITE_INFO) { if (R_HREG_MODE == HREG_MODE_PRINT_HILITE_INFO) {
PRINTF("z_actor.c 3529 eye=[%f(%f) %f %f] object=[%f %f %f] light_direction=[%f %f %f]\n", correctedEyeX, PRINTF("z_actor.c 3529 eye=[%f(%f) %f %f] object=[%f %f %f] light_direction=[%f %f %f]\n", correctedEyeX,
eye->x, eye->y, eye->z, object->x, object->y, object->z, lightDir->x, lightDir->y, lightDir->z); eye->x, eye->y, eye->z, object->x, object->y, object->z, lightDir->x, lightDir->y, lightDir->z);
} }
#endif
VIEW_ERROR_CHECK_EYE_POS(correctedEyeX, eye->y, eye->z);
View_ErrorCheckEyePosition(correctedEyeX, eye->y, eye->z);
guLookAtHilite(&D_8015BBA8, lookAt, *hilite, correctedEyeX, eye->y, eye->z, object->x, object->y, object->z, 0.0f, guLookAtHilite(&D_8015BBA8, lookAt, *hilite, correctedEyeX, eye->y, eye->z, object->x, object->y, object->z, 0.0f,
1.0f, 0.0f, lightDir->x, lightDir->y, lightDir->z, lightDir->x, lightDir->y, lightDir->z, 16, 16); 1.0f, 0.0f, lightDir->x, lightDir->y, lightDir->z, lightDir->x, lightDir->y, lightDir->z, 16, 16);
@ -1773,8 +1791,8 @@ void func_8002F698(PlayState* play, Actor* actor, f32 arg2, s16 arg3, f32 arg4,
player->unk_8A0 = arg6; player->unk_8A0 = arg6;
player->unk_8A1 = arg5; player->unk_8A1 = arg5;
player->unk_8A2 = arg3;
player->unk_8A4 = arg2; player->unk_8A4 = arg2;
player->unk_8A2 = arg3;
player->unk_8A8 = arg4; player->unk_8A8 = arg4;
} }
@ -1903,11 +1921,12 @@ void func_8002FA60(PlayState* play) {
gSaveContext.respawn[RESPAWN_MODE_TOP].pos.z = 0.0f; gSaveContext.respawn[RESPAWN_MODE_TOP].pos.z = 0.0f;
} }
lightPos.x = gSaveContext.respawn[RESPAWN_MODE_TOP].pos.x; // clang-format off
lightPos.y = gSaveContext.respawn[RESPAWN_MODE_TOP].pos.y + 80.0f; lightPos.x = gSaveContext.respawn[RESPAWN_MODE_TOP].pos.x; \
lightPos.z = gSaveContext.respawn[RESPAWN_MODE_TOP].pos.z; lightPos.y = gSaveContext.respawn[RESPAWN_MODE_TOP].pos.y + 80.0f; \
lightPos.z = gSaveContext.respawn[RESPAWN_MODE_TOP].pos.z; \
Lights_PointNoGlowSetInfo(&D_8015BC00, lightPos.x, lightPos.y, lightPos.z, 0xFF, 0xFF, 0xFF, -1); Lights_PointNoGlowSetInfo(&D_8015BC00, lightPos.x, lightPos.y, lightPos.z, 0xFF, 0xFF, 0xFF, -1);
// clang-format on
D_8015BC10 = LightContext_InsertLight(play, &play->lightCtx, &D_8015BC00); D_8015BC10 = LightContext_InsertLight(play, &play->lightCtx, &D_8015BC00);
D_8015BC14 = 0; D_8015BC14 = 0;
@ -2137,7 +2156,7 @@ u32 sCategoryFreezeMasks[ACTORCAT_MAX] = {
}; };
void Actor_UpdateAll(PlayState* play, ActorContext* actorCtx) { void Actor_UpdateAll(PlayState* play, ActorContext* actorCtx) {
Actor* refActor; s32 i;
Actor* actor; Actor* actor;
Player* player; Player* player;
u32* categoryFreezeMaskP; u32* categoryFreezeMaskP;
@ -2145,7 +2164,6 @@ void Actor_UpdateAll(PlayState* play, ActorContext* actorCtx) {
u32 canFreezeCategory; u32 canFreezeCategory;
Actor* sp74; Actor* sp74;
ActorEntry* actorEntry; ActorEntry* actorEntry;
s32 i;
player = GET_PLAYER(play); player = GET_PLAYER(play);
@ -2169,12 +2187,15 @@ void Actor_UpdateAll(PlayState* play, ActorContext* actorCtx) {
actorCtx->unk_02--; actorCtx->unk_02--;
} }
#if OOT_DEBUG
if (KREG(0) == -100) { if (KREG(0) == -100) {
refActor = &GET_PLAYER(play)->actor; Actor* player = &GET_PLAYER(play)->actor;
KREG(0) = 0; KREG(0) = 0;
Actor_Spawn(&play->actorCtx, play, ACTOR_EN_CLEAR_TAG, refActor->world.pos.x, refActor->world.pos.y + 100.0f, Actor_Spawn(&play->actorCtx, play, ACTOR_EN_CLEAR_TAG, player->world.pos.x, player->world.pos.y + 100.0f,
refActor->world.pos.z, 0, 0, 0, 1); player->world.pos.z, 0, 0, 0, 1);
} }
#endif
categoryFreezeMaskP = &sCategoryFreezeMasks[0]; categoryFreezeMaskP = &sCategoryFreezeMasks[0];
@ -2288,10 +2309,14 @@ void Actor_FaultPrint(Actor* actor, char* command) {
FaultDrawer_Printf("ACTOR NAME is NULL"); FaultDrawer_Printf("ACTOR NAME is NULL");
} }
#if OOT_DEBUG
overlayEntry = actor->overlayEntry; overlayEntry = actor->overlayEntry;
name = overlayEntry->name != NULL ? overlayEntry->name : ""; name = overlayEntry->name != NULL ? overlayEntry->name : "";
PRINTF("アクターの名前(%08x:%s)\n", actor, name); // "Actor name (%08x:%s)" PRINTF("アクターの名前(%08x:%s)\n", actor, name); // "Actor name (%08x:%s)"
#else
name = "";
#endif
if (command != NULL) { if (command != NULL) {
PRINTF("コメント:%s\n", command); // "Command:%s" PRINTF("コメント:%s\n", command); // "Command:%s"
@ -2537,20 +2562,22 @@ void func_800315AC(PlayState* play, ActorContext* actorCtx) {
gDPNoOpString(POLY_OPA_DISP++, actorName, i); gDPNoOpString(POLY_OPA_DISP++, actorName, i);
gDPNoOpString(POLY_XLU_DISP++, actorName, i); gDPNoOpString(POLY_XLU_DISP++, actorName, i);
if (OOT_DEBUG) {
HREG(66) = i; HREG(66) = i;
}
if ((HREG(64) != 1) || ((HREG(65) != -1) && (HREG(65) != HREG(66))) || (HREG(68) == 0)) { if (!OOT_DEBUG || (HREG(64) != 1) || ((HREG(65) != -1) && (HREG(65) != HREG(66))) || (HREG(68) == 0)) {
SkinMatrix_Vec3fMtxFMultXYZW(&play->viewProjectionMtxF, &actor->world.pos, &actor->projectedPos, SkinMatrix_Vec3fMtxFMultXYZW(&play->viewProjectionMtxF, &actor->world.pos, &actor->projectedPos,
&actor->projectedW); &actor->projectedW);
} }
if ((HREG(64) != 1) || ((HREG(65) != -1) && (HREG(65) != HREG(66))) || (HREG(69) == 0)) { if (!OOT_DEBUG || (HREG(64) != 1) || ((HREG(65) != -1) && (HREG(65) != HREG(66))) || (HREG(69) == 0)) {
if (actor->sfx != 0) { if (actor->sfx != 0) {
func_80030ED8(actor); func_80030ED8(actor);
} }
} }
if ((HREG(64) != 1) || ((HREG(65) != -1) && (HREG(65) != HREG(66))) || (HREG(70) == 0)) { if (!OOT_DEBUG || (HREG(64) != 1) || ((HREG(65) != -1) && (HREG(65) != HREG(66))) || (HREG(70) == 0)) {
if (func_800314B0(play, actor)) { if (func_800314B0(play, actor)) {
actor->flags |= ACTOR_FLAG_6; actor->flags |= ACTOR_FLAG_6;
} else { } else {
@ -2560,7 +2587,7 @@ void func_800315AC(PlayState* play, ActorContext* actorCtx) {
actor->isDrawn = false; actor->isDrawn = false;
if ((HREG(64) != 1) || ((HREG(65) != -1) && (HREG(65) != HREG(66))) || (HREG(71) == 0)) { if (!OOT_DEBUG || (HREG(64) != 1) || ((HREG(65) != -1) && (HREG(65) != HREG(66))) || (HREG(71) == 0)) {
if ((actor->init == NULL) && (actor->draw != NULL) && (actor->flags & (ACTOR_FLAG_5 | ACTOR_FLAG_6))) { if ((actor->init == NULL) && (actor->draw != NULL) && (actor->flags & (ACTOR_FLAG_5 | ACTOR_FLAG_6))) {
if ((actor->flags & ACTOR_FLAG_REACT_TO_LENS) && if ((actor->flags & ACTOR_FLAG_REACT_TO_LENS) &&
((play->roomCtx.curRoom.lensMode == LENS_MODE_HIDE_ACTORS) || play->actorCtx.lensActive || ((play->roomCtx.curRoom.lensMode == LENS_MODE_HIDE_ACTORS) || play->actorCtx.lensActive ||
@ -2570,7 +2597,8 @@ void func_800315AC(PlayState* play, ActorContext* actorCtx) {
invisibleActors[invisibleActorCounter] = actor; invisibleActors[invisibleActorCounter] = actor;
invisibleActorCounter++; invisibleActorCounter++;
} else { } else {
if ((HREG(64) != 1) || ((HREG(65) != -1) && (HREG(65) != HREG(66))) || (HREG(72) == 0)) { if (!OOT_DEBUG || (HREG(64) != 1) || ((HREG(65) != -1) && (HREG(65) != HREG(66))) ||
(HREG(72) == 0)) {
Actor_Draw(play, actor); Actor_Draw(play, actor);
actor->isDrawn = true; actor->isDrawn = true;
} }
@ -2582,15 +2610,15 @@ void func_800315AC(PlayState* play, ActorContext* actorCtx) {
} }
} }
if ((HREG(64) != 1) || (HREG(73) != 0)) { if (!OOT_DEBUG || (HREG(64) != 1) || (HREG(73) != 0)) {
Effect_DrawAll(play->state.gfxCtx); Effect_DrawAll(play->state.gfxCtx);
} }
if ((HREG(64) != 1) || (HREG(74) != 0)) { if (!OOT_DEBUG || (HREG(64) != 1) || (HREG(74) != 0)) {
EffectSs_DrawAll(play); EffectSs_DrawAll(play);
} }
if ((HREG(64) != 1) || (HREG(72) != 0)) { if (!OOT_DEBUG || (HREG(64) != 1) || (HREG(72) != 0)) {
if (play->actorCtx.lensActive) { if (play->actorCtx.lensActive) {
Actor_DrawLensActors(play, invisibleActorCounter, invisibleActors); Actor_DrawLensActors(play, invisibleActorCounter, invisibleActors);
if ((play->csCtx.state != CS_STATE_IDLE) || Player_InCsMode(play)) { if ((play->csCtx.state != CS_STATE_IDLE) || Player_InCsMode(play)) {
@ -2605,13 +2633,15 @@ void func_800315AC(PlayState* play, ActorContext* actorCtx) {
Lights_DrawGlow(play); Lights_DrawGlow(play);
} }
if ((HREG(64) != 1) || (HREG(75) != 0)) { if (!OOT_DEBUG || (HREG(64) != 1) || (HREG(75) != 0)) {
TitleCard_Draw(play, &actorCtx->titleCtx); TitleCard_Draw(play, &actorCtx->titleCtx);
} }
#if OOT_DEBUG
if ((HREG(64) != 1) || (HREG(76) != 0)) { if ((HREG(64) != 1) || (HREG(76) != 0)) {
CollisionCheck_DrawCollision(play, &play->colChkCtx); CollisionCheck_DrawCollision(play, &play->colChkCtx);
} }
#endif
CLOSE_DISPS(play->state.gfxCtx, "../z_actor.c", 6563); CLOSE_DISPS(play->state.gfxCtx, "../z_actor.c", 6563);
} }
@ -2693,9 +2723,7 @@ void func_80031C3C(ActorContext* actorCtx, PlayState* play) {
} }
} }
if (HREG(20) != 0) { ACTOR_DEBUG_PRINTF("絶対魔法領域解放\n"); // "Absolute magic field deallocation"
PRINTF("絶対魔法領域解放\n"); // "Absolute magic field deallocation"
}
if (actorCtx->absoluteSpace != NULL) { if (actorCtx->absoluteSpace != NULL) {
ZELDA_ARENA_FREE(actorCtx->absoluteSpace, "../z_actor.c", 6731); ZELDA_ARENA_FREE(actorCtx->absoluteSpace, "../z_actor.c", 6731);
@ -2765,32 +2793,24 @@ void Actor_FreeOverlay(ActorOverlay* actorOverlay) {
PRINTF(VT_FGCOL(CYAN)); PRINTF(VT_FGCOL(CYAN));
if (actorOverlay->numLoaded == 0) { if (actorOverlay->numLoaded == 0) {
if (HREG(20) != 0) { ACTOR_DEBUG_PRINTF("アクタークライアントが0になりました\n"); // "Actor client is now 0"
PRINTF("アクタークライアントが0になりました\n"); // "Actor client is now 0"
}
if (actorOverlay->loadedRamAddr != NULL) { if (actorOverlay->loadedRamAddr != NULL) {
if (actorOverlay->allocType & ACTOROVL_ALLOC_PERSISTENT) { if (actorOverlay->allocType & ACTOROVL_ALLOC_PERSISTENT) {
if (HREG(20) != 0) { ACTOR_DEBUG_PRINTF("オーバーレイ解放しません\n"); // "Overlay will not be deallocated"
PRINTF("オーバーレイ解放しません\n"); // "Overlay will not be deallocated"
}
} else if (actorOverlay->allocType & ACTOROVL_ALLOC_ABSOLUTE) { } else if (actorOverlay->allocType & ACTOROVL_ALLOC_ABSOLUTE) {
if (HREG(20) != 0) {
// "Absolute magic field reserved, so deallocation will not occur" // "Absolute magic field reserved, so deallocation will not occur"
PRINTF("絶対魔法領域確保なので解放しません\n"); ACTOR_DEBUG_PRINTF("絶対魔法領域確保なので解放しません\n");
}
actorOverlay->loadedRamAddr = NULL; actorOverlay->loadedRamAddr = NULL;
} else { } else {
if (HREG(20) != 0) { ACTOR_DEBUG_PRINTF("オーバーレイ解放します\n"); // "Overlay deallocated"
PRINTF("オーバーレイ解放します\n"); // "Overlay deallocated"
}
ZELDA_ARENA_FREE(actorOverlay->loadedRamAddr, "../z_actor.c", 6834); ZELDA_ARENA_FREE(actorOverlay->loadedRamAddr, "../z_actor.c", 6834);
actorOverlay->loadedRamAddr = NULL; actorOverlay->loadedRamAddr = NULL;
} }
} }
} else if (HREG(20) != 0) { } else {
// "%d of actor client remains" // "%d of actor client remains"
PRINTF("アクタークライアントはあと %d 残っています\n", actorOverlay->numLoaded); ACTOR_DEBUG_PRINTF("アクタークライアントはあと %d 残っています\n", actorOverlay->numLoaded);
} }
PRINTF(VT_RST); PRINTF(VT_RST);
@ -2810,13 +2830,14 @@ Actor* Actor_Spawn(ActorContext* actorCtx, PlayState* play, s16 actorId, f32 pos
overlayEntry = &gActorOverlayTable[actorId]; overlayEntry = &gActorOverlayTable[actorId];
ASSERT(actorId < ACTOR_ID_MAX, "profile < ACTOR_DLF_MAX", "../z_actor.c", 6883); ASSERT(actorId < ACTOR_ID_MAX, "profile < ACTOR_DLF_MAX", "../z_actor.c", 6883);
#if OOT_DEBUG
name = overlayEntry->name != NULL ? overlayEntry->name : ""; name = overlayEntry->name != NULL ? overlayEntry->name : "";
#endif
overlaySize = (uintptr_t)overlayEntry->vramEnd - (uintptr_t)overlayEntry->vramStart; overlaySize = (uintptr_t)overlayEntry->vramEnd - (uintptr_t)overlayEntry->vramStart;
if (HREG(20) != 0) {
// "Actor class addition [%d:%s]" // "Actor class addition [%d:%s]"
PRINTF("アクタークラス追加 [%d:%s]\n", actorId, name); ACTOR_DEBUG_PRINTF("アクタークラス追加 [%d:%s]\n", actorId, name);
}
if (actorCtx->total > ACTOR_NUMBER_MAX) { if (actorCtx->total > ACTOR_NUMBER_MAX) {
// " set number exceeded" // " set number exceeded"
@ -2825,16 +2846,12 @@ Actor* Actor_Spawn(ActorContext* actorCtx, PlayState* play, s16 actorId, f32 pos
} }
if (overlayEntry->vramStart == NULL) { if (overlayEntry->vramStart == NULL) {
if (HREG(20) != 0) { ACTOR_DEBUG_PRINTF("オーバーレイではありません\n"); // "Not an overlay"
PRINTF("オーバーレイではありません\n"); // "Not an overlay"
}
actorInit = overlayEntry->initInfo; actorInit = overlayEntry->initInfo;
} else { } else {
if (overlayEntry->loadedRamAddr != NULL) { if (overlayEntry->loadedRamAddr != NULL) {
if (HREG(20) != 0) { ACTOR_DEBUG_PRINTF("既にロードされています\n"); // "Already loaded"
PRINTF("既にロードされています\n"); // "Already loaded"
}
} else { } else {
if (overlayEntry->allocType & ACTOROVL_ALLOC_ABSOLUTE) { if (overlayEntry->allocType & ACTOROVL_ALLOC_ABSOLUTE) {
ASSERT(overlaySize <= ACTOROVL_ABSOLUTE_SPACE_SIZE, "actor_segsize <= AM_FIELD_SIZE", "../z_actor.c", ASSERT(overlaySize <= ACTOROVL_ABSOLUTE_SPACE_SIZE, "actor_segsize <= AM_FIELD_SIZE", "../z_actor.c",
@ -2843,10 +2860,8 @@ Actor* Actor_Spawn(ActorContext* actorCtx, PlayState* play, s16 actorId, f32 pos
if (actorCtx->absoluteSpace == NULL) { if (actorCtx->absoluteSpace == NULL) {
// "AMF: absolute magic field" // "AMF: absolute magic field"
actorCtx->absoluteSpace = ZELDA_ARENA_MALLOC_R(ACTOROVL_ABSOLUTE_SPACE_SIZE, "AMF:絶対魔法領域", 0); actorCtx->absoluteSpace = ZELDA_ARENA_MALLOC_R(ACTOROVL_ABSOLUTE_SPACE_SIZE, "AMF:絶対魔法領域", 0);
if (HREG(20) != 0) {
// "Absolute magic field reservation - %d bytes reserved" // "Absolute magic field reservation - %d bytes reserved"
PRINTF("絶対魔法領域確保 %d バイト確保\n", ACTOROVL_ABSOLUTE_SPACE_SIZE); ACTOR_DEBUG_PRINTF("絶対魔法領域確保 %d バイト確保\n", ACTOROVL_ABSOLUTE_SPACE_SIZE);
}
} }
overlayEntry->loadedRamAddr = actorCtx->absoluteSpace; overlayEntry->loadedRamAddr = actorCtx->absoluteSpace;
@ -2908,10 +2923,10 @@ Actor* Actor_Spawn(ActorContext* actorCtx, PlayState* play, s16 actorId, f32 pos
overlayEntry->numLoaded++; overlayEntry->numLoaded++;
if (HREG(20) != 0) { if (1) {}
// "Actor client No. %d" // "Actor client No. %d"
PRINTF("アクタークライアントは %d 個目です\n", overlayEntry->numLoaded); ACTOR_DEBUG_PRINTF("アクタークライアントは %d 個目です\n", overlayEntry->numLoaded);
}
Lib_MemSet((u8*)actor, actorInit->instanceSize, 0); Lib_MemSet((u8*)actor, actorInit->instanceSize, 0);
actor->overlayEntry = overlayEntry; actor->overlayEntry = overlayEntry;
@ -3009,9 +3024,7 @@ Actor* Actor_Delete(ActorContext* actorCtx, Actor* actor, PlayState* play) {
overlayEntry = actor->overlayEntry; overlayEntry = actor->overlayEntry;
name = overlayEntry->name != NULL ? overlayEntry->name : ""; name = overlayEntry->name != NULL ? overlayEntry->name : "";
if (HREG(20) != 0) { ACTOR_DEBUG_PRINTF("アクタークラス削除 [%s]\n", name); // "Actor class deleted [%s]"
PRINTF("アクタークラス削除 [%s]\n", name); // "Actor class deleted [%s]"
}
if ((player != NULL) && (actor == player->unk_664)) { if ((player != NULL) && (actor == player->unk_664)) {
func_8008EDF0(player); func_8008EDF0(player);
@ -3038,9 +3051,7 @@ Actor* Actor_Delete(ActorContext* actorCtx, Actor* actor, PlayState* play) {
ZELDA_ARENA_FREE(actor, "../z_actor.c", 7242); ZELDA_ARENA_FREE(actor, "../z_actor.c", 7242);
if (overlayEntry->vramStart == NULL) { if (overlayEntry->vramStart == NULL) {
if (HREG(20) != 0) { ACTOR_DEBUG_PRINTF("オーバーレイではありません\n"); // "Not an overlay"
PRINTF("オーバーレイではありません\n"); // "Not an overlay"
}
} else { } else {
ASSERT(overlayEntry->loadedRamAddr != NULL, "actor_dlftbl->allocp != NULL", "../z_actor.c", 7251); ASSERT(overlayEntry->loadedRamAddr != NULL, "actor_dlftbl->allocp != NULL", "../z_actor.c", 7251);
ASSERT(overlayEntry->numLoaded > 0, "actor_dlftbl->clients > 0", "../z_actor.c", 7252); ASSERT(overlayEntry->numLoaded > 0, "actor_dlftbl->clients > 0", "../z_actor.c", 7252);
@ -3714,7 +3725,7 @@ void Actor_DrawDoorLock(PlayState* play, s32 frame, s32 type) {
f32 chainRotZ; f32 chainRotZ;
f32 chainsTranslateX; f32 chainsTranslateX;
f32 chainsTranslateY; f32 chainsTranslateY;
f32 rotZStep; s32 pad;
entry = &sDoorLocksInfo[type]; entry = &sDoorLocksInfo[type];
chainRotZ = entry->chainsRotZInit; chainRotZ = entry->chainsRotZInit;
@ -3724,10 +3735,14 @@ void Actor_DrawDoorLock(PlayState* play, s32 frame, s32 type) {
Matrix_Translate(0.0f, entry->yShift, 500.0f, MTXMODE_APPLY); Matrix_Translate(0.0f, entry->yShift, 500.0f, MTXMODE_APPLY);
Matrix_Get(&baseMtxF); Matrix_Get(&baseMtxF);
{
f32 rotZStep;
chainsTranslateX = sinf(entry->chainAngle - chainRotZ) * -(10 - frame) * 0.1f * entry->chainLength; chainsTranslateX = sinf(entry->chainAngle - chainRotZ) * -(10 - frame) * 0.1f * entry->chainLength;
chainsTranslateY = cosf(entry->chainAngle - chainRotZ) * (10 - frame) * 0.1f * entry->chainLength; chainsTranslateY = cosf(entry->chainAngle - chainRotZ) * (10 - frame) * 0.1f * entry->chainLength;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
Matrix_Put(&baseMtxF); Matrix_Put(&baseMtxF);
Matrix_RotateZ(chainRotZ, MTXMODE_APPLY); Matrix_RotateZ(chainRotZ, MTXMODE_APPLY);
Matrix_Translate(chainsTranslateX, chainsTranslateY, 0.0f, MTXMODE_APPLY); Matrix_Translate(chainsTranslateX, chainsTranslateY, 0.0f, MTXMODE_APPLY);
@ -3736,7 +3751,8 @@ void Actor_DrawDoorLock(PlayState* play, s32 frame, s32 type) {
Matrix_Scale(entry->chainsScale, entry->chainsScale, entry->chainsScale, MTXMODE_APPLY); Matrix_Scale(entry->chainsScale, entry->chainsScale, entry->chainsScale, MTXMODE_APPLY);
} }
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEW(play->state.gfxCtx, "../z_actor.c", 8299), G_MTX_MODELVIEW | G_MTX_LOAD); gSPMatrix(POLY_OPA_DISP++, MATRIX_NEW(play->state.gfxCtx, "../z_actor.c", 8299),
G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, entry->chainDL); gSPDisplayList(POLY_OPA_DISP++, entry->chainDL);
if (i % 2) { if (i % 2) {
@ -3747,6 +3763,7 @@ void Actor_DrawDoorLock(PlayState* play, s32 frame, s32 type) {
chainRotZ += rotZStep; chainRotZ += rotZStep;
} }
}
Matrix_Put(&baseMtxF); Matrix_Put(&baseMtxF);
Matrix_Scale(frame * 0.1f, frame * 0.1f, frame * 0.1f, MTXMODE_APPLY); Matrix_Scale(frame * 0.1f, frame * 0.1f, frame * 0.1f, MTXMODE_APPLY);
@ -4404,6 +4421,7 @@ Actor* func_800358DC(Actor* actor, Vec3f* spawnPos, Vec3s* spawnRot, f32* arg3,
} }
void func_800359B8(Actor* actor, s16 arg1, Vec3s* arg2) { void func_800359B8(Actor* actor, s16 arg1, Vec3s* arg2) {
if (actor->floorPoly != NULL) {
f32 floorPolyNormalX; f32 floorPolyNormalX;
f32 floorPolyNormalY; f32 floorPolyNormalY;
f32 floorPolyNormalZ; f32 floorPolyNormalZ;
@ -4416,7 +4434,6 @@ void func_800359B8(Actor* actor, s16 arg1, Vec3s* arg2) {
CollisionPoly* floorPoly; CollisionPoly* floorPoly;
s32 pad; s32 pad;
if (actor->floorPoly != NULL) {
floorPoly = actor->floorPoly; floorPoly = actor->floorPoly;
floorPolyNormalX = COLPOLY_GET_NORMAL(floorPoly->normal.x); floorPolyNormalX = COLPOLY_GET_NORMAL(floorPoly->normal.x);
floorPolyNormalY = COLPOLY_GET_NORMAL(floorPoly->normal.y); floorPolyNormalY = COLPOLY_GET_NORMAL(floorPoly->normal.y);

View file

@ -52,6 +52,7 @@ s32 gMaxActorId = 0;
static FaultClient sFaultClient; static FaultClient sFaultClient;
void ActorOverlayTable_LogPrint(void) { void ActorOverlayTable_LogPrint(void) {
#if OOT_DEBUG
ActorOverlay* overlayEntry; ActorOverlay* overlayEntry;
u32 i; u32 i;
@ -63,6 +64,7 @@ void ActorOverlayTable_LogPrint(void) {
overlayEntry->vramStart, overlayEntry->vramEnd, overlayEntry->loadedRamAddr, &overlayEntry->initInfo->id, overlayEntry->vramStart, overlayEntry->vramEnd, overlayEntry->loadedRamAddr, &overlayEntry->initInfo->id,
overlayEntry->name != NULL ? overlayEntry->name : "?"); overlayEntry->name != NULL ? overlayEntry->name : "?");
} }
#endif
} }
void ActorOverlayTable_FaultPrint(void* arg0, void* arg1) { void ActorOverlayTable_FaultPrint(void* arg0, void* arg1) {
@ -80,7 +82,7 @@ void ActorOverlayTable_FaultPrint(void* arg0, void* arg1) {
if (overlayEntry->loadedRamAddr != NULL) { if (overlayEntry->loadedRamAddr != NULL) {
FaultDrawer_Printf("%3d %08x-%08x %3d %s\n", i, overlayEntry->loadedRamAddr, FaultDrawer_Printf("%3d %08x-%08x %3d %s\n", i, overlayEntry->loadedRamAddr,
(uintptr_t)overlayEntry->loadedRamAddr + overlaySize, overlayEntry->numLoaded, (uintptr_t)overlayEntry->loadedRamAddr + overlaySize, overlayEntry->numLoaded,
overlayEntry->name != NULL ? overlayEntry->name : ""); (OOT_DEBUG && overlayEntry->name != NULL) ? overlayEntry->name : "");
} }
} }
} }

View file

@ -4409,6 +4409,7 @@ s32 func_800427B4(CollisionPoly* polyA, CollisionPoly* polyB, Vec3f* pointA, Vec
return result; return result;
} }
#if OOT_DEBUG
/** /**
* Draw a list of dyna polys, specified by `ssList` * Draw a list of dyna polys, specified by `ssList`
*/ */
@ -4556,3 +4557,4 @@ void BgCheck_DrawStaticCollision(PlayState* play, CollisionContext* colCtx) {
BgCheck_DrawStaticPolyList(play, colCtx, &lookup->ceiling, 255, 0, 0); BgCheck_DrawStaticPolyList(play, colCtx, &lookup->ceiling, 255, 0, 0);
} }
} }
#endif

View file

@ -7,6 +7,7 @@ typedef void (*ColChkApplyFunc)(PlayState*, CollisionCheckContext*, Collider*);
typedef void (*ColChkVsFunc)(PlayState*, CollisionCheckContext*, Collider*, Collider*); typedef void (*ColChkVsFunc)(PlayState*, CollisionCheckContext*, Collider*, Collider*);
typedef s32 (*ColChkLineFunc)(PlayState*, CollisionCheckContext*, Collider*, Vec3f*, Vec3f*); typedef s32 (*ColChkLineFunc)(PlayState*, CollisionCheckContext*, Collider*, Vec3f*, Vec3f*);
#if OOT_DEBUG
/** /**
* Draws a red triangle with vertices vA, vB, and vC. * Draws a red triangle with vertices vA, vB, and vC.
*/ */
@ -69,6 +70,7 @@ void Collider_DrawPoly(GraphicsContext* gfxCtx, Vec3f* vA, Vec3f* vB, Vec3f* vC,
CLOSE_DISPS(gfxCtx, "../z_collision_check.c", 757); CLOSE_DISPS(gfxCtx, "../z_collision_check.c", 757);
} }
#endif
s32 Collider_InitBase(PlayState* play, Collider* col) { s32 Collider_InitBase(PlayState* play, Collider* col) {
static Collider init = { static Collider init = {
@ -1000,9 +1002,12 @@ s32 Collider_ResetLineOC(PlayState* play, OcLine* line) {
void CollisionCheck_InitContext(PlayState* play, CollisionCheckContext* colChkCtx) { void CollisionCheck_InitContext(PlayState* play, CollisionCheckContext* colChkCtx) {
colChkCtx->sacFlags = 0; colChkCtx->sacFlags = 0;
CollisionCheck_ClearContext(play, colChkCtx); CollisionCheck_ClearContext(play, colChkCtx);
#if OOT_DEBUG
AREG(21) = true; AREG(21) = true;
AREG(22) = true; AREG(22) = true;
AREG(23) = true; AREG(23) = true;
#endif
} }
void CollisionCheck_DestroyContext(PlayState* play, CollisionCheckContext* colChkCtx) { void CollisionCheck_DestroyContext(PlayState* play, CollisionCheckContext* colChkCtx) {
@ -1052,6 +1057,7 @@ void CollisionCheck_DisableSAC(PlayState* play, CollisionCheckContext* colChkCtx
colChkCtx->sacFlags &= ~SAC_ENABLE; colChkCtx->sacFlags &= ~SAC_ENABLE;
} }
#if OOT_DEBUG
/** /**
* Draws a collider of any shape. * Draws a collider of any shape.
* Math3D_DrawSphere and Math3D_DrawCylinder are noops, so JntSph and Cylinder are not drawn. * Math3D_DrawSphere and Math3D_DrawCylinder are noops, so JntSph and Cylinder are not drawn.
@ -1130,6 +1136,7 @@ void CollisionCheck_DrawCollision(PlayState* play, CollisionCheckContext* colChk
} }
} }
} }
#endif
static ColChkResetFunc sATResetFuncs[] = { static ColChkResetFunc sATResetFuncs[] = {
Collider_ResetJntSphAT, Collider_ResetJntSphAT,
@ -2153,8 +2160,6 @@ void CollisionCheck_ATTrisVsACCyl(PlayState* play, CollisionCheckContext* colChk
ColliderTris* atTris = (ColliderTris*)atCol; ColliderTris* atTris = (ColliderTris*)atCol;
ColliderTrisElement* atTrisElem; ColliderTrisElement* atTrisElem;
ColliderCylinder* acCyl = (ColliderCylinder*)acCol; ColliderCylinder* acCyl = (ColliderCylinder*)acCol;
Vec3f atPos;
Vec3f acPos;
if (acCyl->dim.radius > 0 && acCyl->dim.height > 0 && atTris->count > 0 && atTris->elements != NULL) { if (acCyl->dim.radius > 0 && acCyl->dim.height > 0 && atTris->count > 0 && atTris->elements != NULL) {
if (CollisionCheck_SkipElementBump(&acCyl->elem) == true) { if (CollisionCheck_SkipElementBump(&acCyl->elem) == true) {
@ -2169,6 +2174,9 @@ void CollisionCheck_ATTrisVsACCyl(PlayState* play, CollisionCheckContext* colChk
} }
if (Math3D_CylTriVsIntersect(&acCyl->dim, &atTrisElem->dim, &hitPos) == true) { if (Math3D_CylTriVsIntersect(&acCyl->dim, &atTrisElem->dim, &hitPos) == true) {
Vec3f atPos;
Vec3f acPos;
atPos.x = (atTrisElem->dim.vtx[0].x + atTrisElem->dim.vtx[1].x + atTrisElem->dim.vtx[2].x) * (1.0f / 3); atPos.x = (atTrisElem->dim.vtx[0].x + atTrisElem->dim.vtx[1].x + atTrisElem->dim.vtx[2].x) * (1.0f / 3);
atPos.y = (atTrisElem->dim.vtx[0].y + atTrisElem->dim.vtx[1].y + atTrisElem->dim.vtx[2].y) * (1.0f / 3); atPos.y = (atTrisElem->dim.vtx[0].y + atTrisElem->dim.vtx[1].y + atTrisElem->dim.vtx[2].y) * (1.0f / 3);
atPos.z = (atTrisElem->dim.vtx[0].z + atTrisElem->dim.vtx[1].z + atTrisElem->dim.vtx[2].z) * (1.0f / 3); atPos.z = (atTrisElem->dim.vtx[0].z + atTrisElem->dim.vtx[1].z + atTrisElem->dim.vtx[2].z) * (1.0f / 3);
@ -2512,11 +2520,12 @@ void CollisionCheck_ATQuadVsACQuad(PlayState* play, CollisionCheckContext* colCh
void CollisionCheck_SetJntSphHitFX(PlayState* play, CollisionCheckContext* colChkCtx, Collider* col) { void CollisionCheck_SetJntSphHitFX(PlayState* play, CollisionCheckContext* colChkCtx, Collider* col) {
ColliderJntSph* jntSph = (ColliderJntSph*)col; ColliderJntSph* jntSph = (ColliderJntSph*)col;
ColliderJntSphElement* jntSphElem; ColliderJntSphElement* jntSphElem;
Vec3f hitPos;
for (jntSphElem = jntSph->elements; jntSphElem < jntSph->elements + jntSph->count; jntSphElem++) { for (jntSphElem = jntSph->elements; jntSphElem < jntSph->elements + jntSph->count; jntSphElem++) {
if ((jntSphElem->base.bumperFlags & BUMP_DRAW_HITMARK) && (jntSphElem->base.acHitElem != NULL) && if ((jntSphElem->base.bumperFlags & BUMP_DRAW_HITMARK) && (jntSphElem->base.acHitElem != NULL) &&
!(jntSphElem->base.acHitElem->toucherFlags & TOUCH_DREW_HITMARK)) { !(jntSphElem->base.acHitElem->toucherFlags & TOUCH_DREW_HITMARK)) {
Vec3f hitPos;
Math_Vec3s_ToVec3f(&hitPos, &jntSphElem->base.bumper.hitPos); Math_Vec3s_ToVec3f(&hitPos, &jntSphElem->base.bumper.hitPos);
CollisionCheck_HitEffects(play, jntSphElem->base.acHit, jntSphElem->base.acHitElem, &jntSph->base, CollisionCheck_HitEffects(play, jntSphElem->base.acHit, jntSphElem->base.acHitElem, &jntSph->base,
&jntSphElem->base, &hitPos); &jntSphElem->base, &hitPos);
@ -2528,10 +2537,11 @@ void CollisionCheck_SetJntSphHitFX(PlayState* play, CollisionCheckContext* colCh
void CollisionCheck_SetCylHitFX(PlayState* play, CollisionCheckContext* colChkCtx, Collider* col) { void CollisionCheck_SetCylHitFX(PlayState* play, CollisionCheckContext* colChkCtx, Collider* col) {
ColliderCylinder* cyl = (ColliderCylinder*)col; ColliderCylinder* cyl = (ColliderCylinder*)col;
Vec3f hitPos;
if ((cyl->elem.bumperFlags & BUMP_DRAW_HITMARK) && (cyl->elem.acHitElem != NULL) && if ((cyl->elem.bumperFlags & BUMP_DRAW_HITMARK) && (cyl->elem.acHitElem != NULL) &&
!(cyl->elem.acHitElem->toucherFlags & TOUCH_DREW_HITMARK)) { !(cyl->elem.acHitElem->toucherFlags & TOUCH_DREW_HITMARK)) {
Vec3f hitPos;
Math_Vec3s_ToVec3f(&hitPos, &cyl->elem.bumper.hitPos); Math_Vec3s_ToVec3f(&hitPos, &cyl->elem.bumper.hitPos);
CollisionCheck_HitEffects(play, cyl->elem.acHit, cyl->elem.acHitElem, &cyl->base, &cyl->elem, &hitPos); CollisionCheck_HitEffects(play, cyl->elem.acHit, cyl->elem.acHitElem, &cyl->base, &cyl->elem, &hitPos);
cyl->elem.acHitElem->toucherFlags |= TOUCH_DREW_HITMARK; cyl->elem.acHitElem->toucherFlags |= TOUCH_DREW_HITMARK;
@ -2541,11 +2551,12 @@ void CollisionCheck_SetCylHitFX(PlayState* play, CollisionCheckContext* colChkCt
void CollisionCheck_SetTrisHitFX(PlayState* play, CollisionCheckContext* colChkCtx, Collider* col) { void CollisionCheck_SetTrisHitFX(PlayState* play, CollisionCheckContext* colChkCtx, Collider* col) {
ColliderTris* tris = (ColliderTris*)col; ColliderTris* tris = (ColliderTris*)col;
ColliderTrisElement* trisElem; ColliderTrisElement* trisElem;
Vec3f hitPos;
for (trisElem = tris->elements; trisElem < tris->elements + tris->count; trisElem++) { for (trisElem = tris->elements; trisElem < tris->elements + tris->count; trisElem++) {
if ((trisElem->base.bumperFlags & BUMP_DRAW_HITMARK) && (trisElem->base.acHitElem != NULL) && if ((trisElem->base.bumperFlags & BUMP_DRAW_HITMARK) && (trisElem->base.acHitElem != NULL) &&
!(trisElem->base.acHitElem->toucherFlags & TOUCH_DREW_HITMARK)) { !(trisElem->base.acHitElem->toucherFlags & TOUCH_DREW_HITMARK)) {
Vec3f hitPos;
Math_Vec3s_ToVec3f(&hitPos, &trisElem->base.bumper.hitPos); Math_Vec3s_ToVec3f(&hitPos, &trisElem->base.bumper.hitPos);
CollisionCheck_HitEffects(play, trisElem->base.acHit, trisElem->base.acHitElem, &tris->base, CollisionCheck_HitEffects(play, trisElem->base.acHit, trisElem->base.acHitElem, &tris->base,
&trisElem->base, &hitPos); &trisElem->base, &hitPos);
@ -2807,8 +2818,7 @@ void CollisionCheck_OC_JntSphVsJntSph(PlayState* play, CollisionCheckContext* co
continue; continue;
} }
if (Math3D_SphVsSphOverlap(&leftJntSphElem->dim.worldSphere, &rightJntSphElem->dim.worldSphere, if (Math3D_SphVsSphOverlap(&leftJntSphElem->dim.worldSphere, &rightJntSphElem->dim.worldSphere,
&overlapSize) == &overlapSize) == true) {
true) {
Vec3f leftPos; Vec3f leftPos;
Vec3f rightPos; Vec3f rightPos;
@ -3689,6 +3699,9 @@ u8 CollisionCheck_GetSwordDamage(s32 dmgFlags) {
damage = 8; damage = 8;
} }
#if OOT_DEBUG
KREG(7) = damage; KREG(7) = damage;
#endif
return damage; return damage;
} }

View file

@ -17,8 +17,9 @@ void Interface_Init(PlayState* play) {
View_Init(&interfaceCtx->view, play->state.gfxCtx); View_Init(&interfaceCtx->view, play->state.gfxCtx);
interfaceCtx->unk_1FA = interfaceCtx->unk_261 = interfaceCtx->unk_1FC = 0;
interfaceCtx->unk_1EC = interfaceCtx->unk_1EE = interfaceCtx->unk_1F0 = 0; interfaceCtx->unk_1EC = interfaceCtx->unk_1EE = interfaceCtx->unk_1F0 = 0;
interfaceCtx->unk_1FA = interfaceCtx->unk_261 = interfaceCtx->unk_1FC = 0;
interfaceCtx->unk_22E = 0; interfaceCtx->unk_22E = 0;
interfaceCtx->lensMagicConsumptionTimer = 16; interfaceCtx->lensMagicConsumptionTimer = 16;
interfaceCtx->unk_1F4 = 0.0f; interfaceCtx->unk_1F4 = 0.0f;

View file

@ -153,6 +153,7 @@ void DebugCamera_DrawScreenText(GfxPrint* printer) {
} }
} }
#if OOT_DEBUG
/** /**
* Updates the state of the Reg Editor according to user input. * Updates the state of the Reg Editor according to user input.
* Also contains a controller rumble test that can be interfaced with via related REGs. * Also contains a controller rumble test that can be interfaced with via related REGs.
@ -269,6 +270,7 @@ void Regs_DrawEditor(GfxPrint* printer) {
} }
} }
} }
#endif
/** /**
* Draws the Reg Editor and Debug Camera text on screen * Draws the Reg Editor and Debug Camera text on screen
@ -283,7 +285,7 @@ void Debug_DrawText(GraphicsContext* gfxCtx) {
GfxPrint_Init(&printer); GfxPrint_Init(&printer);
opaStart = POLY_OPA_DISP; opaStart = POLY_OPA_DISP;
gfx = Graph_GfxPlusOne(POLY_OPA_DISP); gfx = Gfx_Open(POLY_OPA_DISP);
gSPDisplayList(OVERLAY_DISP++, gfx); gSPDisplayList(OVERLAY_DISP++, gfx);
GfxPrint_Open(&printer, gfx); GfxPrint_Open(&printer, gfx);
@ -291,15 +293,17 @@ void Debug_DrawText(GraphicsContext* gfxCtx) {
DebugCamera_DrawScreenText(&printer); DebugCamera_DrawScreenText(&printer);
} }
#if OOT_DEBUG
if (gRegEditor->regPage != 0) { if (gRegEditor->regPage != 0) {
Regs_DrawEditor(&printer); Regs_DrawEditor(&printer);
} }
#endif
sDebugCamTextEntryCount = 0; sDebugCamTextEntryCount = 0;
gfx = GfxPrint_Close(&printer); gfx = GfxPrint_Close(&printer);
gSPEndDisplayList(gfx++); gSPEndDisplayList(gfx++);
Graph_BranchDlist(opaStart, gfx); Gfx_Close(opaStart, gfx);
POLY_OPA_DISP = gfx; POLY_OPA_DISP = gfx;
if (1) {} if (1) {}

View file

@ -130,6 +130,7 @@ s16 sQuakeIndex;
void Cutscene_SetupScripted(PlayState* play, CutsceneContext* csCtx); void Cutscene_SetupScripted(PlayState* play, CutsceneContext* csCtx);
#if OOT_DEBUG
void Cutscene_DrawDebugInfo(PlayState* play, Gfx** dlist, CutsceneContext* csCtx) { void Cutscene_DrawDebugInfo(PlayState* play, Gfx** dlist, CutsceneContext* csCtx) {
GfxPrint printer; GfxPrint printer;
s32 pad[2]; s32 pad[2];
@ -149,6 +150,7 @@ void Cutscene_DrawDebugInfo(PlayState* play, Gfx** dlist, CutsceneContext* csCtx
*dlist = GfxPrint_Close(&printer); *dlist = GfxPrint_Close(&printer);
GfxPrint_Destroy(&printer); GfxPrint_Destroy(&printer);
} }
#endif
void Cutscene_InitContext(PlayState* play, CutsceneContext* csCtx) { void Cutscene_InitContext(PlayState* play, CutsceneContext* csCtx) {
csCtx->state = CS_STATE_IDLE; csCtx->state = CS_STATE_IDLE;
@ -173,6 +175,8 @@ void Cutscene_UpdateManual(PlayState* play, CutsceneContext* csCtx) {
} }
void Cutscene_UpdateScripted(PlayState* play, CutsceneContext* csCtx) { void Cutscene_UpdateScripted(PlayState* play, CutsceneContext* csCtx) {
#if OOT_DEBUG
{
Input* input = &play->state.input[0]; Input* input = &play->state.input[0];
if (CHECK_BTN_ALL(input->press.button, BTN_DLEFT) && (csCtx->state == CS_STATE_IDLE) && IS_CUTSCENE_LAYER) { if (CHECK_BTN_ALL(input->press.button, BTN_DLEFT) && (csCtx->state == CS_STATE_IDLE) && IS_CUTSCENE_LAYER) {
@ -187,6 +191,8 @@ void Cutscene_UpdateScripted(PlayState* play, CutsceneContext* csCtx) {
gSaveContext.save.cutsceneIndex = 0xFFFD; gSaveContext.save.cutsceneIndex = 0xFFFD;
gSaveContext.cutsceneTrigger = 1; gSaveContext.cutsceneTrigger = 1;
} }
}
#endif
if ((gSaveContext.cutsceneTrigger != 0) && (play->transitionTrigger == TRANS_TRIGGER_START)) { if ((gSaveContext.cutsceneTrigger != 0) && (play->transitionTrigger == TRANS_TRIGGER_START)) {
gSaveContext.cutsceneTrigger = 0; gSaveContext.cutsceneTrigger = 0;
@ -562,7 +568,7 @@ void CutsceneCmd_Destination(PlayState* play, CutsceneContext* csCtx, CsCmdDesti
} }
if ((csCtx->curFrame == cmd->startFrame) || titleDemoSkipped || if ((csCtx->curFrame == cmd->startFrame) || titleDemoSkipped ||
((csCtx->curFrame > 20) && CHECK_BTN_ALL(play->state.input[0].press.button, BTN_START) && (OOT_DEBUG && (csCtx->curFrame > 20) && CHECK_BTN_ALL(play->state.input[0].press.button, BTN_START) &&
(gSaveContext.fileNum != 0xFEDC))) { (gSaveContext.fileNum != 0xFEDC))) {
csCtx->state = CS_STATE_RUN_UNSTOPPABLE; csCtx->state = CS_STATE_RUN_UNSTOPPABLE;
Audio_SetCutsceneFlag(0); Audio_SetCutsceneFlag(0);
@ -717,7 +723,9 @@ void CutsceneCmd_Destination(PlayState* play, CutsceneContext* csCtx, CsCmdDesti
break; break;
case CS_DEST_TEMPLE_OF_TIME_AFTER_LIGHT_MEDALLION: case CS_DEST_TEMPLE_OF_TIME_AFTER_LIGHT_MEDALLION:
SET_EVENTCHKINF(EVENTCHKINF_4F); #if OOT_DEBUG
SET_EVENTCHKINF(EVENTCHKINF_WATCHED_SHEIK_AFTER_MASTER_SWORD_CS);
#endif
play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_4; play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_4;
play->transitionTrigger = TRANS_TRIGGER_START; play->transitionTrigger = TRANS_TRIGGER_START;
play->transitionType = TRANS_TYPE_FADE_BLACK; play->transitionType = TRANS_TYPE_FADE_BLACK;
@ -886,7 +894,9 @@ void CutsceneCmd_Destination(PlayState* play, CutsceneContext* csCtx, CsCmdDesti
break; break;
case CS_DEST_TEMPLE_OF_TIME_AFTER_LIGHT_MEDALLION_ALT: case CS_DEST_TEMPLE_OF_TIME_AFTER_LIGHT_MEDALLION_ALT:
SET_EVENTCHKINF(EVENTCHKINF_4F); #if OOT_DEBUG
SET_EVENTCHKINF(EVENTCHKINF_WATCHED_SHEIK_AFTER_MASTER_SWORD_CS);
#endif
play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_4; play->nextEntranceIndex = ENTR_TEMPLE_OF_TIME_4;
play->transitionTrigger = TRANS_TRIGGER_START; play->transitionTrigger = TRANS_TRIGGER_START;
play->transitionType = TRANS_TYPE_FADE_BLACK_FAST; play->transitionType = TRANS_TYPE_FADE_BLACK_FAST;
@ -941,8 +951,10 @@ void CutsceneCmd_Destination(PlayState* play, CutsceneContext* csCtx, CsCmdDesti
break; break;
case CS_DEST_GERUDO_VALLEY_CREDITS: case CS_DEST_GERUDO_VALLEY_CREDITS:
#if OOT_DEBUG
gSaveContext.gameMode = GAMEMODE_END_CREDITS; gSaveContext.gameMode = GAMEMODE_END_CREDITS;
Audio_SetSfxBanksMute(0x6F); Audio_SetSfxBanksMute(0x6F);
#endif
play->linkAgeOnLoad = LINK_AGE_CHILD; play->linkAgeOnLoad = LINK_AGE_CHILD;
play->nextEntranceIndex = ENTR_GERUDO_VALLEY_0; play->nextEntranceIndex = ENTR_GERUDO_VALLEY_0;
gSaveContext.save.cutsceneIndex = 0xFFF2; gSaveContext.save.cutsceneIndex = 0xFFF2;
@ -1779,10 +1791,12 @@ void Cutscene_ProcessScript(PlayState* play, CutsceneContext* csCtx, u8* script)
return; return;
} }
#if OOT_DEBUG
if (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_DRIGHT)) { if (CHECK_BTN_ALL(play->state.input[0].press.button, BTN_DRIGHT)) {
csCtx->state = CS_STATE_STOP; csCtx->state = CS_STATE_STOP;
return; return;
} }
#endif
for (i = 0; i < totalEntries; i++) { for (i = 0; i < totalEntries; i++) {
MemCpy(&cmdType, script, sizeof(cmdType)); MemCpy(&cmdType, script, sizeof(cmdType));
@ -2189,31 +2203,26 @@ void Cutscene_ProcessScript(PlayState* play, CutsceneContext* csCtx, u8* script)
} }
void CutsceneHandler_RunScript(PlayState* play, CutsceneContext* csCtx) { void CutsceneHandler_RunScript(PlayState* play, CutsceneContext* csCtx) {
if (gSaveContext.save.cutsceneIndex >= 0xFFF0) {
if (OOT_DEBUG && BREG(0) != 0) {
Gfx* displayList; Gfx* displayList;
Gfx* prevDisplayList; Gfx* prevDisplayList;
if (0) {} // Necessary to match
if (gSaveContext.save.cutsceneIndex >= 0xFFF0) {
if (0) {} // Also necessary to match
if (BREG(0) != 0) {
OPEN_DISPS(play->state.gfxCtx, "../z_demo.c", 4101); OPEN_DISPS(play->state.gfxCtx, "../z_demo.c", 4101);
prevDisplayList = POLY_OPA_DISP; prevDisplayList = POLY_OPA_DISP;
displayList = Graph_GfxPlusOne(POLY_OPA_DISP); displayList = Gfx_Open(POLY_OPA_DISP);
gSPDisplayList(OVERLAY_DISP++, displayList); gSPDisplayList(OVERLAY_DISP++, displayList);
Cutscene_DrawDebugInfo(play, &displayList, csCtx); Cutscene_DrawDebugInfo(play, &displayList, csCtx);
gSPEndDisplayList(displayList++); gSPEndDisplayList(displayList++);
Graph_BranchDlist(prevDisplayList, displayList); Gfx_Close(prevDisplayList, displayList);
POLY_OPA_DISP = displayList; POLY_OPA_DISP = displayList;
CLOSE_DISPS(play->state.gfxCtx, "../z_demo.c", 4108); CLOSE_DISPS(play->state.gfxCtx, "../z_demo.c", 4108);
} }
csCtx->curFrame++; csCtx->curFrame++;
if (R_USE_DEBUG_CUTSCENE) { if (OOT_DEBUG && R_USE_DEBUG_CUTSCENE) {
Cutscene_ProcessScript(play, csCtx, gDebugCutsceneScript); Cutscene_ProcessScript(play, csCtx, gDebugCutsceneScript);
} else { } else {
Cutscene_ProcessScript(play, csCtx, play->csCtx.script); Cutscene_ProcessScript(play, csCtx, play->csCtx.script);

View file

@ -768,6 +768,8 @@ void GetItem_DrawSmallRupee(PlayState* play, s16 drawId) {
Matrix_Scale(0.7f, 0.7f, 0.7f, MTXMODE_APPLY); Matrix_Scale(0.7f, 0.7f, 0.7f, MTXMODE_APPLY);
if (1) {}
Gfx_SetupDL_25Opa(play->state.gfxCtx); Gfx_SetupDL_25Opa(play->state.gfxCtx);
gSPMatrix(POLY_OPA_DISP++, MATRIX_NEW(play->state.gfxCtx, "../z_draw.c", 1140), G_MTX_MODELVIEW | G_MTX_LOAD); gSPMatrix(POLY_OPA_DISP++, MATRIX_NEW(play->state.gfxCtx, "../z_draw.c", 1140), G_MTX_MODELVIEW | G_MTX_LOAD);
gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[1]); gSPDisplayList(POLY_OPA_DISP++, sDrawItemTable[drawId].dlists[1]);

View file

@ -4,16 +4,10 @@
void EffectBlure_AddVertex(EffectBlure* this, Vec3f* p1, Vec3f* p2) { void EffectBlure_AddVertex(EffectBlure* this, Vec3f* p1, Vec3f* p2) {
EffectBlureElement* elem; EffectBlureElement* elem;
s32 numElements; s32 numElements;
Vec3f sp16C;
Vec3f sp160; // Necessary to match
Vec3f sp154; if (this) {}
f32 scale; if (this) {}
MtxF sp110;
MtxF spD0;
MtxF sp90;
MtxF sp50;
Vec3f sp44;
Vec3f sp38;
if (this != NULL) { if (this != NULL) {
numElements = this->numElements; numElements = this->numElements;
@ -34,6 +28,17 @@ void EffectBlure_AddVertex(EffectBlure* this, Vec3f* p1, Vec3f* p2) {
elem->p2.y = p2->y; elem->p2.y = p2->y;
elem->p2.z = p2->z; elem->p2.z = p2->z;
} else { } else {
Vec3f sp16C;
Vec3f sp160;
Vec3f sp154;
f32 scale;
MtxF sp110;
MtxF spD0;
MtxF sp90;
MtxF sp50;
Vec3f sp44;
Vec3f sp38;
sp16C.x = ((f32)(elem - 1)->p2.x + (f32)(elem - 1)->p1.x) * 0.5f; sp16C.x = ((f32)(elem - 1)->p2.x + (f32)(elem - 1)->p1.x) * 0.5f;
sp16C.y = ((f32)(elem - 1)->p2.y + (f32)(elem - 1)->p1.y) * 0.5f; sp16C.y = ((f32)(elem - 1)->p2.y + (f32)(elem - 1)->p1.y) * 0.5f;
sp16C.z = ((f32)(elem - 1)->p2.z + (f32)(elem - 1)->p1.z) * 0.5f; sp16C.z = ((f32)(elem - 1)->p2.z + (f32)(elem - 1)->p1.z) * 0.5f;
@ -255,19 +260,16 @@ void EffectBlure_UpdateFlags(EffectBlureElement* elem) {
Vec3f sp58; Vec3f sp58;
Vec3f sp4C; Vec3f sp4C;
Vec3f sp40; Vec3f sp40;
if (((elem - 1)->state == 0) || ((elem + 1)->state == 0)) {
elem->flags &= ~3;
elem->flags |= 2;
} else {
EffectBlureElement* prev = elem - 1; EffectBlureElement* prev = elem - 1;
EffectBlureElement* next = elem + 1; EffectBlureElement* next = elem + 1;
f32 sp34; f32 sp34;
f32 sp30; f32 sp30;
f32 sp2C; f32 sp2C;
if (1) {} // Necessary to match if (((elem - 1)->state == 0) || ((elem + 1)->state == 0)) {
elem->flags &= ~3;
elem->flags |= 2;
} else {
Math_Vec3s_DiffToVec3f(&sp64, &elem->p1, &prev->p1); Math_Vec3s_DiffToVec3f(&sp64, &elem->p1, &prev->p1);
Math_Vec3s_DiffToVec3f(&sp58, &elem->p2, &prev->p2); Math_Vec3s_DiffToVec3f(&sp58, &elem->p2, &prev->p2);
Math_Vec3s_DiffToVec3f(&sp4C, &next->p1, &elem->p1); Math_Vec3s_DiffToVec3f(&sp4C, &next->p1, &elem->p1);
@ -1013,11 +1015,11 @@ void EffectBlure_Draw(void* thisx, GraphicsContext* gfxCtx) {
} }
} }
flag = 0;
j = 0; j = 0;
gSPVertex(POLY_XLU_DISP++, vtx, 32, 0); gSPVertex(POLY_XLU_DISP++, vtx, 32, 0);
flag = 0;
for (i = 0; i < this->numElements; i++) { for (i = 0; i < this->numElements; i++) {
elem = &this->elements[i]; elem = &this->elements[i];

Some files were not shown because too many files have changed in this diff Show more