diff --git a/.gitignore b/.gitignore index ce16eaafb..aa4a3a5c4 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ tools/ido_recomp/* binary ctx.c graphs/ *.c.m2c +tools/**/*dSYM/ tools/decomp-permuter/ tools/mips_to_c/ @@ -42,5 +43,9 @@ tools/mips_to_c/ !*_custom* .extracted-assets.json +# Docs +!docs/**/*.png +!.vscode/extensions.json + # Per-user configuration .python-version diff --git a/Jenkinsfile b/Jenkinsfile index df06c6a09..cf5d8f3b6 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -52,9 +52,9 @@ pipeline { } steps { sh 'mkdir reports' - sh 'python3 ./tools/progress.py csv >> reports/progress_mm.us.rev1.csv' - sh 'python3 ./tools/progress.py csv -m >> reports/progress_matching_mm.us.rev1.csv' - sh 'python3 ./tools/progress.py shield-json > reports/progress_shield_mm.us.rev1.json' + sh 'python3 ./tools/progress.py csv >> reports/progress-mm-nonmatching.csv' + sh 'python3 ./tools/progress.py csv -m >> reports/progress-mm-matching.csv' + sh 'python3 ./tools/progress.py shield-json > reports/progress-mm-shield.json' stash includes: 'reports/*', name: 'reports' } } @@ -67,9 +67,9 @@ pipeline { } steps { unstash 'reports' - sh 'cat reports/progress_mm.us.rev1.csv >> /var/www/html/reports/progress_mm.us.rev1.csv' - sh 'cat reports/progress_matching_mm.us.rev1.csv >> /var/www/html/reports/progress_matching_mm.us.rev1.csv' - sh 'cat reports/progress_shield_mm.us.rev1.json > /var/www/html/reports/progress_shield_mm.us.rev1.json' + sh 'cat reports/progress-mm-nonmatching.csv >> /var/www/zelda64.dev/assets/csv/progress-mm-nonmatching.csv' + sh 'cat reports/progress-mm-matching.csv >> /var/www/zelda64.dev/assets/csv/progress-mm-matching.csv' + sh 'cat reports/progress-mm-shield.json > /var/www/zelda64.dev/assets/csv/progress-mm-shield.json' } } } diff --git a/Makefile b/Makefile index a65a8713d..7d08aadce 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,8 @@ NON_MATCHING ?= 0 ORIG_COMPILER ?= 0 # Keep .mdebug section in build KEEP_MDEBUG ?= 0 +# Disassembles all asm from the ROM instead of skipping files which are entirely in C +FULL_DISASM ?= 0 ifeq ($(NON_MATCHING),1) CFLAGS := -DNON_MATCHING @@ -17,6 +19,10 @@ ifeq ($(NON_MATCHING),1) COMPARE := 0 endif +ifneq ($(FULL_DISASM), 0) + DISASM_FLAGS += --full +endif + PROJECT_DIR := $(dir $(realpath $(firstword $(MAKEFILE_LIST)))) MAKE = make @@ -36,12 +42,7 @@ else endif endif -# Threads to compress and extract assets with, TODO improve later -ifeq ($(DETECTED_OS),linux) - N_THREADS ?= $(shell nproc) -else - N_THREADS ?= 1 -endif +N_THREADS ?= $(shell nproc) #### Tools #### ifeq ($(shell type mips-linux-gnu-ld >/dev/null 2>/dev/null; echo $$?), 0) @@ -71,6 +72,7 @@ OBJCOPY := $(MIPS_BINUTILS_PREFIX)objcopy OBJDUMP := $(MIPS_BINUTILS_PREFIX)objdump IINC := -Iinclude -Isrc -Iassets -Ibuild -I. + ifeq ($(KEEP_MDEBUG),0) RM_MDEBUG = $(OBJCOPY) --remove-section .mdebug $@ else @@ -102,6 +104,12 @@ else CC_CHECK += -m32 endif +# rom compression flags +COMPFLAGS := --threads $(N_THREADS) +ifneq ($(NON_MATCHING),1) + COMPFLAGS += --matching +endif + #### Files #### # ROM image @@ -116,25 +124,27 @@ $(shell mkdir -p asm data) SRC_DIRS := $(shell find src -type d) ASM_DIRS := $(shell find asm -type d -not -path "asm/non_matchings*") $(shell find data -type d) -ASSET_BIN_DIRS := $(shell find assets/* -type d -not -path "assets/xml*") -BASEROM_DIRS := $(shell find baserom -type d 2>/dev/null) -ASSET_C_FILES := $(shell find assets/ -type f -name "*.c") -ASSET_FILES_BIN := $(foreach dir,$(ASSET_BIN_DIRS),$(wildcard $(dir)/*.bin)) -ASSET_FILES_OUT := $(foreach f,$(ASSET_FILES_BIN:.bin=.bin.inc.c),build/$f) ## Assets binaries (PNGs, JPGs, etc) +ASSET_BIN_DIRS := $(shell find assets/* -type d -not -path "assets/xml*") + +ASSET_FILES_XML := $(foreach dir,$(ASSET_BIN_DIRS),$(wildcard $(dir)/*.xml)) +ASSET_FILES_BIN := $(foreach dir,$(ASSET_BIN_DIRS),$(wildcard $(dir)/*.bin)) +ASSET_FILES_OUT := $(foreach f,$(ASSET_FILES_XML:.xml=.c),$f) \ + $(foreach f,$(ASSET_FILES_BIN:.bin=.bin.inc.c),build/$f) + TEXTURE_FILES_PNG := $(foreach dir,$(ASSET_BIN_DIRS),$(wildcard $(dir)/*.png)) TEXTURE_FILES_JPG := $(foreach dir,$(ASSET_BIN_DIRS),$(wildcard $(dir)/*.jpg)) TEXTURE_FILES_OUT := $(foreach f,$(TEXTURE_FILES_PNG:.png=.inc.c),build/$f) \ $(foreach f,$(TEXTURE_FILES_JPG:.jpg=.jpg.inc.c),build/$f) \ -C_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.c)) +C_FILES := $(foreach dir,$(SRC_DIRS) $(ASSET_BIN_DIRS),$(wildcard $(dir)/*.c)) S_FILES := $(shell grep -F "build/asm" spec | sed 's/.*build\/// ; s/\.o\".*/.s/') \ $(shell grep -F "build/data" spec | sed 's/.*build\/// ; s/\.o\".*/.s/') +BASEROM_FILES := $(shell grep -F "build/baserom" spec | sed 's/.*build\/// ; s/\.o\".*//') O_FILES := $(foreach f,$(S_FILES:.s=.o),build/$f) \ - $(foreach f,$(wildcard baserom/*),build/$f.o) \ $(foreach f,$(C_FILES:.c=.o),build/$f) \ - $(foreach f,$(ASSET_C_FILES:.c=.o),build/$f) + $(foreach f,$(BASEROM_FILES),build/$f.o) # Automatic dependency files # (Only asm_processor dependencies are handled for now) @@ -158,6 +168,8 @@ build/src/libultra/flash/%.o: MIPS_VERSION := -mips1 build/src/code/audio/%.o: OPTFLAGS := -O2 +build/assets/%.o: OPTFLAGS := + # file flags build/src/boot_O2_g3/fault.o: CFLAGS += -trapuv build/src/boot_O2_g3/fault_drawer.o: CFLAGS += -trapuv @@ -209,9 +221,9 @@ $(ROM): $(ELF) $(ELF2ROM) -cic 6105 $< $@ $(ROMC): uncompressed - python3 tools/z64compress_wrapper.py --mb 32 --matching --threads $(N_THREADS) $(ROM) $@ $(ELF) build/$(SPEC) + python3 tools/z64compress_wrapper.py $(COMPFLAGS) $(ROM) $@ $(ELF) build/$(SPEC) -$(ELF): $(TEXTURE_FILES_OUT) $(OVERLAY_RELOC_FILES) $(O_FILES) build/ldscript.txt build/undefined_syms.txt +$(ELF): $(TEXTURE_FILES_OUT) $(ASSET_FILES_OUT) $(O_FILES) build/ldscript.txt build/undefined_syms.txt $(LD) -T build/undefined_syms.txt -T build/ldscript.txt --no-check-sections --accept-unknown-input-arch --emit-relocs -Map build/mm.map -o $@ @@ -235,12 +247,12 @@ setup: $(MAKE) -C tools python3 tools/fixbaserom.py python3 tools/extract_baserom.py - python3 extract_assets.py -t $(N_THREADS) + python3 extract_assets.py -j $(N_THREADS) ## Assembly generation disasm: $(RM) -rf asm data - python3 tools/disasm/disasm.py -j $(N_THREADS) + python3 tools/disasm/disasm.py -j $(N_THREADS) $(DISASM_FLAGS) diff-init: uncompressed $(RM) -rf expected/ @@ -254,10 +266,6 @@ init: $(MAKE) all $(MAKE) diff-init -build/assets/%.o: assets/%.c - $(CC) -I build/ -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $< - $(RM_MDEBUG) - #### Various Recipes #### build/undefined_syms.txt: undefined_syms.txt @@ -267,14 +275,19 @@ build/ldscript.txt: $(SPEC) $(CPP) $(CPPFLAGS) $< > build/spec $(MKLDSCRIPT) build/spec $@ -build/baserom/%.o: baserom/% - $(OBJCOPY) -I binary -O elf32-big $< $@ - build/asm/%.o: asm/%.s $(AS) $(ASFLAGS) $< -o $@ +build/assets/%.o: assets/%.c + $(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $< + $(OBJCOPY) -O binary $@ $@.bin + $(RM_MDEBUG) + +build/baserom/%.o: baserom/% + $(OBJCOPY) -I binary -O elf32-big $< $@ + build/data/%.o: data/%.s - iconv --from UTF-8 --to EUC-JP $< | $(AS) $(ASFLAGS) -o $@ + $(AS) $(ASFLAGS) $< -o $@ build/src/overlays/%.o: src/overlays/%.c $(CC) -c $(CFLAGS) $(MIPS_VERSION) $(OPTFLAGS) -o $@ $< @@ -307,8 +320,9 @@ build/src/libultra/libc/llcvt.o: src/libultra/libc/llcvt.c $(RM_MDEBUG) # Build C files from assets + build/%.inc.c: %.png - $(ZAPD) btex -eh -tt $(lastword ,$(subst ., ,$(basename $<))) -i $< -o $@ + $(ZAPD) btex -eh -tt $(subst .,,$(suffix $*)) -i $< -o $@ build/assets/%.bin.inc.c: assets/%.bin $(ZAPD) bblb -eh -i $< -o $@ diff --git a/README.md b/README.md index 99ae2355a..845a10cc6 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@ [jenkins]: https://jenkins.deco.mp/job/MM/job/master [jenkins-badge]: https://img.shields.io/jenkins/build?jobUrl=https%3A%2F%2Fjenkins.deco.mp%2Fjob%2FMM%2Fjob%2Fmaster -[progress]: https://zelda64.dev/progress.html -[progress-badge]: https://img.shields.io/endpoint?url=https://zelda64.dev/reports/progress_shield_mm.us.rev1.json +[progress]: https://zelda64.dev/games/mm +[progress-badge]: https://img.shields.io/endpoint?url=https://zelda64.dev/assets/csv/progress-mm-shield.json [contributors]: https://github.com/zeldaret/mm/graphs/contributors [contributors-badge]: https://img.shields.io/github/contributors/zeldaret/mm @@ -23,26 +23,35 @@ in an experimental and research phase and cannot currently be used traditionally source code base for general changes. ``` -**This repo does not include any assets or code necessary for compiling the ROM. A prior copy of the game is required to extract the required assets.** +This is a WIP **decompilation** of ***The Legend of Zelda: Majora's Mask***. The purpose of the project is to recreate a source code base for the game from scratch, using information found inside the game along with static and/or dynamic analysis. **It is not producing a PC port.** For more information you can get in touch with the team on our [Discord server](https://discord.zelda64.dev). -This is a decompilation of Legend of Zelda: Majora's Mask (US) 1.0 +The only build currently supported is N64 US, but other versions are planned to be supported. -It builds the following ROM: +It currently builds the following ROM: * mm.us.rev1.rom.z64 `md5: 2a0a8acb61538235bc1094d297fb6556` +**This repo does not include any assets or assembly code necessary for compiling the ROM. A prior copy of the game is required to extract the required assets.** + Please refer to the following for more information: - [Website](https://zelda64.dev/) - [Discord](https://discord.zelda64.dev/) - [How to Contribute](CONTRIBUTING.md) + ## Installation ### Windows For Windows 10, install WSL and a distribution by following this [Windows Subsystem for Linux Installation Guide](https://docs.microsoft.com/en-us/windows/wsl/install-win10). -We recommend using Debian or Ubuntu 18.04 Linux distributions. +We recommend using Debian or Ubuntu 20.04 Linux distributions. + + +### MacOS + +Preparation is covered in a [separate document](docsBUILDING_MACOS.md). + ### Linux (Native or under WSL / VM) @@ -110,30 +119,23 @@ This means that something is wrong with the ROM's contents. Either the baserom f Running `make init` will also make the `./expected` directory and copy all of the files there, which will be useful when running the diff script. The diff script is useful in decompiling functions and can be ran with this command: `./tools/asm-differ/diff.py -wmo3 ` -**Note**: to speed up the build, you can either: -* Pass `-jN` to `make setup` and `make`, where N is the number of threads to use in the build, e.g. `make -j4`. The generally-accepted wisdom is to use the number of virtual cores your computer has. -* Pass `-j` to `make setup` and `make`, to use as many threads as possible, but beware that this can use too much memory on lower-end systems. -Both of these have the disadvantage that the ordering of the terminal output is scrambled, so for debugging it is best to stick to one thread (i.e. not pass `-j` or `-jN`). +**Note**: to speed up the build, you can pass `-jN` to `make setup` and `make`, where N is the number of threads to use in the build, e.g. `make -j4`. The generally-accepted wisdom is to use the number of virtual cores your computer has, which is the output of `nproc` (which should be installed as part of `coreutils`). +The disadvantage that the ordering of the terminal output is scrambled, so for debugging it is best to stick to one thread (i.e. not pass `-jN`). +(`-j` also exists, which uses unlimited jobs, but is generally slower.) -**Note**: if you rename symbols, it is recommended that you use the `tools/rename_sym.sh` to ensure that you cover all instances, including the tables which are used to generate the `asm/` directory. - -Usage: `tools/rename_sym.sh old_name new_name`. Example: - -```bash -tools/rename_sym.sh func_808A3428 EnTorch2_UpdateIdle -``` ## Contributing All contributions are welcome. This is a group effort, and even small contributions can make a difference. Some tasks also don't require much knowledge to get started. -Anyone who wishes to contribute to the OOT or MM projects **must not have accessed leaked source code at any point in time** for Nintendo 64 SDK, iQue player SDK, libultra, Ocarina of Time, Majora's Mask, Animal Crossing/Animal Forest, or any other game that shares the same game engine or significant portions of code to a Zelda 64 game or any other console similar to the Nintendo 64. +Please note that is is our strict policy that *Anyone who wishes to contribute to the OOT or MM projects **must not have accessed leaked source code at any point in time** for Nintendo 64 SDK, iQue player SDK, libultra, Ocarina of Time, Majora's Mask, Animal Crossing/Animal Forest, or any other game that shares the same game engine or significant portions of code to a Zelda 64 game or any other console similar to the Nintendo 64.* Most discussions happen on our [Discord Server](https://discord.zelda64.dev), where you are welcome to ask if you need help getting started, or if you have any questions regarding this project and other decompilation projects. For more information on getting started, see our [Contributing Guide](CONTRIBUTING.md) and our [Code Review Guidelines](REVIEWING.md) to see what code quality guidelines we follow. + ## FAQ ### Q: Why does MM use transient assembly? diff --git a/assets/xml/code/eff_shield_particle.xml b/assets/xml/code/eff_shield_particle.xml new file mode 100644 index 000000000..3ff553506 --- /dev/null +++ b/assets/xml/code/eff_shield_particle.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/static/icon_item_gameover_static.xml b/assets/xml/interface/icon_item_gameover_static.xml similarity index 100% rename from assets/xml/static/icon_item_gameover_static.xml rename to assets/xml/interface/icon_item_gameover_static.xml diff --git a/assets/xml/static/daytelop_static.xml b/assets/xml/misc/daytelop_static.xml similarity index 100% rename from assets/xml/static/daytelop_static.xml rename to assets/xml/misc/daytelop_static.xml diff --git a/assets/xml/static/esp_daytelop_static.xml b/assets/xml/misc/esp_daytelop_static.xml similarity index 100% rename from assets/xml/static/esp_daytelop_static.xml rename to assets/xml/misc/esp_daytelop_static.xml diff --git a/assets/xml/static/fra_daytelop_static.xml b/assets/xml/misc/fra_daytelop_static.xml similarity index 100% rename from assets/xml/static/fra_daytelop_static.xml rename to assets/xml/misc/fra_daytelop_static.xml diff --git a/assets/xml/static/ger_daytelop_static.xml b/assets/xml/misc/ger_daytelop_static.xml similarity index 100% rename from assets/xml/static/ger_daytelop_static.xml rename to assets/xml/misc/ger_daytelop_static.xml diff --git a/assets/xml/static/nintendo_rogo_static.xml b/assets/xml/misc/nintendo_rogo_static.xml similarity index 100% rename from assets/xml/static/nintendo_rogo_static.xml rename to assets/xml/misc/nintendo_rogo_static.xml diff --git a/assets/xml/objects/gameplay_dangeon_keep.xml b/assets/xml/objects/gameplay_dangeon_keep.xml new file mode 100644 index 000000000..19fabad2b --- /dev/null +++ b/assets/xml/objects/gameplay_dangeon_keep.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/gameplay_field_keep.xml b/assets/xml/objects/gameplay_field_keep.xml new file mode 100644 index 000000000..537d596a6 --- /dev/null +++ b/assets/xml/objects/gameplay_field_keep.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/gameplay_keep.xml b/assets/xml/objects/gameplay_keep.xml new file mode 100644 index 000000000..d8ab73a83 --- /dev/null +++ b/assets/xml/objects/gameplay_keep.xml @@ -0,0 +1,1421 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ah.xml b/assets/xml/objects/object_ah.xml new file mode 100644 index 000000000..296347dac --- /dev/null +++ b/assets/xml/objects/object_ah.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ahg.xml b/assets/xml/objects/object_ahg.xml new file mode 100644 index 000000000..c636f0baa --- /dev/null +++ b/assets/xml/objects/object_ahg.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_al.xml b/assets/xml/objects/object_al.xml new file mode 100644 index 000000000..7a2ff1a52 --- /dev/null +++ b/assets/xml/objects/object_al.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_am.xml b/assets/xml/objects/object_am.xml new file mode 100644 index 000000000..c135b7b0b --- /dev/null +++ b/assets/xml/objects/object_am.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_an1.xml b/assets/xml/objects/object_an1.xml new file mode 100644 index 000000000..c2ae65d8b --- /dev/null +++ b/assets/xml/objects/object_an1.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_an2.xml b/assets/xml/objects/object_an2.xml new file mode 100644 index 000000000..3adcc27f7 --- /dev/null +++ b/assets/xml/objects/object_an2.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_an3.xml b/assets/xml/objects/object_an3.xml new file mode 100644 index 000000000..2d94b81b7 --- /dev/null +++ b/assets/xml/objects/object_an3.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_an4.xml b/assets/xml/objects/object_an4.xml new file mode 100644 index 000000000..57088a072 --- /dev/null +++ b/assets/xml/objects/object_an4.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_and.xml b/assets/xml/objects/object_and.xml new file mode 100644 index 000000000..269e2a73f --- /dev/null +++ b/assets/xml/objects/object_and.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ani.xml b/assets/xml/objects/object_ani.xml new file mode 100644 index 000000000..85fd13cec --- /dev/null +++ b/assets/xml/objects/object_ani.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_aob.xml b/assets/xml/objects/object_aob.xml new file mode 100644 index 000000000..dcdb75748 --- /dev/null +++ b/assets/xml/objects/object_aob.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_astr_obj.xml b/assets/xml/objects/object_astr_obj.xml new file mode 100644 index 000000000..7a87bd61b --- /dev/null +++ b/assets/xml/objects/object_astr_obj.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_az.xml b/assets/xml/objects/object_az.xml new file mode 100644 index 000000000..c192f6914 --- /dev/null +++ b/assets/xml/objects/object_az.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_b_heart.xml b/assets/xml/objects/object_b_heart.xml new file mode 100644 index 000000000..789f05b37 --- /dev/null +++ b/assets/xml/objects/object_b_heart.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_bai.xml b/assets/xml/objects/object_bai.xml new file mode 100644 index 000000000..ad8d8445b --- /dev/null +++ b/assets/xml/objects/object_bai.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bal.xml b/assets/xml/objects/object_bal.xml new file mode 100644 index 000000000..e564a4798 --- /dev/null +++ b/assets/xml/objects/object_bal.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bat.xml b/assets/xml/objects/object_bat.xml new file mode 100644 index 000000000..35a5c158d --- /dev/null +++ b/assets/xml/objects/object_bat.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bb.xml b/assets/xml/objects/object_bb.xml new file mode 100644 index 000000000..ba3e4cb94 --- /dev/null +++ b/assets/xml/objects/object_bb.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bba.xml b/assets/xml/objects/object_bba.xml new file mode 100644 index 000000000..b172e9f77 --- /dev/null +++ b/assets/xml/objects/object_bba.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bdoor.xml b/assets/xml/objects/object_bdoor.xml new file mode 100644 index 000000000..d74f4aa57 --- /dev/null +++ b/assets/xml/objects/object_bdoor.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bee.xml b/assets/xml/objects/object_bee.xml new file mode 100644 index 000000000..b2c90324b --- /dev/null +++ b/assets/xml/objects/object_bee.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bg.xml b/assets/xml/objects/object_bg.xml new file mode 100644 index 000000000..d623f9455 --- /dev/null +++ b/assets/xml/objects/object_bg.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bh.xml b/assets/xml/objects/object_bh.xml new file mode 100644 index 000000000..d54e99e23 --- /dev/null +++ b/assets/xml/objects/object_bh.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_big_fwall.xml b/assets/xml/objects/object_big_fwall.xml new file mode 100644 index 000000000..f3f51a488 --- /dev/null +++ b/assets/xml/objects/object_big_fwall.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_bigicicle.xml b/assets/xml/objects/object_bigicicle.xml new file mode 100644 index 000000000..3e1a7fd7e --- /dev/null +++ b/assets/xml/objects/object_bigicicle.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bigokuta.xml b/assets/xml/objects/object_bigokuta.xml new file mode 100644 index 000000000..b6783c15d --- /dev/null +++ b/assets/xml/objects/object_bigokuta.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bigpo.xml b/assets/xml/objects/object_bigpo.xml new file mode 100644 index 000000000..c41d5ff79 --- /dev/null +++ b/assets/xml/objects/object_bigpo.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bigslime.xml b/assets/xml/objects/object_bigslime.xml new file mode 100644 index 000000000..18b702506 --- /dev/null +++ b/assets/xml/objects/object_bigslime.xml @@ -0,0 +1,130 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bji.xml b/assets/xml/objects/object_bji.xml new file mode 100644 index 000000000..e8c7fe949 --- /dev/null +++ b/assets/xml/objects/object_bji.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bjt.xml b/assets/xml/objects/object_bjt.xml new file mode 100644 index 000000000..9f0c0edc2 --- /dev/null +++ b/assets/xml/objects/object_bjt.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bob.xml b/assets/xml/objects/object_bob.xml new file mode 100644 index 000000000..968a838d2 --- /dev/null +++ b/assets/xml/objects/object_bob.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_boj.xml b/assets/xml/objects/object_boj.xml new file mode 100644 index 000000000..d948ff546 --- /dev/null +++ b/assets/xml/objects/object_boj.xml @@ -0,0 +1,92 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bombf.xml b/assets/xml/objects/object_bombf.xml new file mode 100644 index 000000000..a0e5cdef3 --- /dev/null +++ b/assets/xml/objects/object_bombf.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_bombiwa.xml b/assets/xml/objects/object_bombiwa.xml new file mode 100644 index 000000000..6dbcaf2b5 --- /dev/null +++ b/assets/xml/objects/object_bombiwa.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_boss01.xml b/assets/xml/objects/object_boss01.xml new file mode 100644 index 000000000..a9865a096 --- /dev/null +++ b/assets/xml/objects/object_boss01.xml @@ -0,0 +1,189 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_boss02.xml b/assets/xml/objects/object_boss02.xml new file mode 100644 index 000000000..f944de242 --- /dev/null +++ b/assets/xml/objects/object_boss02.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_boss03.xml b/assets/xml/objects/object_boss03.xml new file mode 100644 index 000000000..14d7d3498 --- /dev/null +++ b/assets/xml/objects/object_boss03.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_boss04.xml b/assets/xml/objects/object_boss04.xml new file mode 100644 index 000000000..d24ad986a --- /dev/null +++ b/assets/xml/objects/object_boss04.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_boss05.xml b/assets/xml/objects/object_boss05.xml new file mode 100644 index 000000000..ec994d824 --- /dev/null +++ b/assets/xml/objects/object_boss05.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_boss07.xml b/assets/xml/objects/object_boss07.xml new file mode 100644 index 000000000..aa0ef8c88 --- /dev/null +++ b/assets/xml/objects/object_boss07.xml @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_boss_hakugin.xml b/assets/xml/objects/object_boss_hakugin.xml new file mode 100644 index 000000000..05302db78 --- /dev/null +++ b/assets/xml/objects/object_boss_hakugin.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_botihasira.xml b/assets/xml/objects/object_botihasira.xml new file mode 100644 index 000000000..93c59f42f --- /dev/null +++ b/assets/xml/objects/object_botihasira.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_box.xml b/assets/xml/objects/object_box.xml new file mode 100644 index 000000000..39d21765f --- /dev/null +++ b/assets/xml/objects/object_box.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_boyo.xml b/assets/xml/objects/object_boyo.xml new file mode 100644 index 000000000..0084c4825 --- /dev/null +++ b/assets/xml/objects/object_boyo.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_bsb.xml b/assets/xml/objects/object_bsb.xml new file mode 100644 index 000000000..ddaadc33d --- /dev/null +++ b/assets/xml/objects/object_bsb.xml @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bsmask.xml b/assets/xml/objects/object_bsmask.xml new file mode 100644 index 000000000..e776cde1a --- /dev/null +++ b/assets/xml/objects/object_bsmask.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_bubble.xml b/assets/xml/objects/object_bubble.xml new file mode 100644 index 000000000..4397a017f --- /dev/null +++ b/assets/xml/objects/object_bubble.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_cha.xml b/assets/xml/objects/object_cha.xml new file mode 100644 index 000000000..12835da1f --- /dev/null +++ b/assets/xml/objects/object_cha.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_cne.xml b/assets/xml/objects/object_cne.xml new file mode 100644 index 000000000..72447ceec --- /dev/null +++ b/assets/xml/objects/object_cne.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_comb.xml b/assets/xml/objects/object_comb.xml new file mode 100644 index 000000000..df9359acc --- /dev/null +++ b/assets/xml/objects/object_comb.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_cow.xml b/assets/xml/objects/object_cow.xml new file mode 100644 index 000000000..b44057344 --- /dev/null +++ b/assets/xml/objects/object_cow.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_crace_object.xml b/assets/xml/objects/object_crace_object.xml new file mode 100644 index 000000000..06c007989 --- /dev/null +++ b/assets/xml/objects/object_crace_object.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_crow.xml b/assets/xml/objects/object_crow.xml new file mode 100644 index 000000000..b3b004cd7 --- /dev/null +++ b/assets/xml/objects/object_crow.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_cs.xml b/assets/xml/objects/object_cs.xml new file mode 100644 index 000000000..65cff1d46 --- /dev/null +++ b/assets/xml/objects/object_cs.xml @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ctower_rot.xml b/assets/xml/objects/object_ctower_rot.xml new file mode 100644 index 000000000..515b4fa65 --- /dev/null +++ b/assets/xml/objects/object_ctower_rot.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_d_hsblock.xml b/assets/xml/objects/object_d_hsblock.xml new file mode 100644 index 000000000..e9f90c011 --- /dev/null +++ b/assets/xml/objects/object_d_hsblock.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_d_lift.xml b/assets/xml/objects/object_d_lift.xml new file mode 100644 index 000000000..bcd707d68 --- /dev/null +++ b/assets/xml/objects/object_d_lift.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_dai.xml b/assets/xml/objects/object_dai.xml new file mode 100644 index 000000000..c39ef9a6d --- /dev/null +++ b/assets/xml/objects/object_dai.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_daiku.xml b/assets/xml/objects/object_daiku.xml new file mode 100644 index 000000000..0c42532ec --- /dev/null +++ b/assets/xml/objects/object_daiku.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_danpei_object.xml b/assets/xml/objects/object_danpei_object.xml new file mode 100644 index 000000000..3f373a8ce --- /dev/null +++ b/assets/xml/objects/object_danpei_object.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dblue_object.xml b/assets/xml/objects/object_dblue_object.xml new file mode 100644 index 000000000..d49b368e1 --- /dev/null +++ b/assets/xml/objects/object_dblue_object.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_death.xml b/assets/xml/objects/object_death.xml new file mode 100644 index 000000000..2aba9582d --- /dev/null +++ b/assets/xml/objects/object_death.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dekubaba.xml b/assets/xml/objects/object_dekubaba.xml new file mode 100644 index 000000000..bd59555c4 --- /dev/null +++ b/assets/xml/objects/object_dekubaba.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dekucity_ana_obj.xml b/assets/xml/objects/object_dekucity_ana_obj.xml new file mode 100644 index 000000000..620c34a04 --- /dev/null +++ b/assets/xml/objects/object_dekucity_ana_obj.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_dekucity_obj.xml b/assets/xml/objects/object_dekucity_obj.xml new file mode 100644 index 000000000..1d680965e --- /dev/null +++ b/assets/xml/objects/object_dekucity_obj.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dekunuts.xml b/assets/xml/objects/object_dekunuts.xml new file mode 100644 index 000000000..442dc756d --- /dev/null +++ b/assets/xml/objects/object_dekunuts.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_delf.xml b/assets/xml/objects/object_delf.xml new file mode 100644 index 000000000..39996c0f0 --- /dev/null +++ b/assets/xml/objects/object_delf.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dhouse.xml b/assets/xml/objects/object_dhouse.xml new file mode 100644 index 000000000..dd95b8b98 --- /dev/null +++ b/assets/xml/objects/object_dhouse.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dinofos.xml b/assets/xml/objects/object_dinofos.xml new file mode 100644 index 000000000..83eade0da --- /dev/null +++ b/assets/xml/objects/object_dinofos.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dkjail_obj.xml b/assets/xml/objects/object_dkjail_obj.xml new file mode 100644 index 000000000..219181c6d --- /dev/null +++ b/assets/xml/objects/object_dkjail_obj.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_dmask.xml b/assets/xml/objects/object_dmask.xml new file mode 100644 index 000000000..f2411c147 --- /dev/null +++ b/assets/xml/objects/object_dmask.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dnk.xml b/assets/xml/objects/object_dnk.xml new file mode 100644 index 000000000..209742fe1 --- /dev/null +++ b/assets/xml/objects/object_dnk.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dno.xml b/assets/xml/objects/object_dno.xml new file mode 100644 index 000000000..16fa904c5 --- /dev/null +++ b/assets/xml/objects/object_dno.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dnp.xml b/assets/xml/objects/object_dnp.xml new file mode 100644 index 000000000..0f5655e9b --- /dev/null +++ b/assets/xml/objects/object_dnp.xml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dnq.xml b/assets/xml/objects/object_dnq.xml new file mode 100644 index 000000000..d286082bf --- /dev/null +++ b/assets/xml/objects/object_dnq.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dns.xml b/assets/xml/objects/object_dns.xml new file mode 100644 index 000000000..64939670e --- /dev/null +++ b/assets/xml/objects/object_dns.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dnt.xml b/assets/xml/objects/object_dnt.xml new file mode 100644 index 000000000..d2ff328d3 --- /dev/null +++ b/assets/xml/objects/object_dnt.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dodongo.xml b/assets/xml/objects/object_dodongo.xml new file mode 100644 index 000000000..cf0fa3725 --- /dev/null +++ b/assets/xml/objects/object_dodongo.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dog.xml b/assets/xml/objects/object_dog.xml new file mode 100644 index 000000000..7e9cd3e99 --- /dev/null +++ b/assets/xml/objects/object_dog.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dor01.xml b/assets/xml/objects/object_dor01.xml new file mode 100644 index 000000000..39c950680 --- /dev/null +++ b/assets/xml/objects/object_dor01.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_dor02.xml b/assets/xml/objects/object_dor02.xml new file mode 100644 index 000000000..0b64a9b1b --- /dev/null +++ b/assets/xml/objects/object_dor02.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_dor03.xml b/assets/xml/objects/object_dor03.xml new file mode 100644 index 000000000..c374837ea --- /dev/null +++ b/assets/xml/objects/object_dor03.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_dor04.xml b/assets/xml/objects/object_dor04.xml new file mode 100644 index 000000000..2d1ac5611 --- /dev/null +++ b/assets/xml/objects/object_dor04.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_dora.xml b/assets/xml/objects/object_dora.xml new file mode 100644 index 000000000..6a0972666 --- /dev/null +++ b/assets/xml/objects/object_dora.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_driftice.xml b/assets/xml/objects/object_driftice.xml new file mode 100644 index 000000000..0ddb6e204 --- /dev/null +++ b/assets/xml/objects/object_driftice.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_drs.xml b/assets/xml/objects/object_drs.xml new file mode 100644 index 000000000..35202d17b --- /dev/null +++ b/assets/xml/objects/object_drs.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ds2.xml b/assets/xml/objects/object_ds2.xml new file mode 100644 index 000000000..0745fad58 --- /dev/null +++ b/assets/xml/objects/object_ds2.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ds2n.xml b/assets/xml/objects/object_ds2n.xml new file mode 100644 index 000000000..63ccca136 --- /dev/null +++ b/assets/xml/objects/object_ds2n.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dt.xml b/assets/xml/objects/object_dt.xml new file mode 100644 index 000000000..a4df244ad --- /dev/null +++ b/assets/xml/objects/object_dt.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_dy_obj.xml b/assets/xml/objects/object_dy_obj.xml new file mode 100644 index 000000000..dc2ab5ed4 --- /dev/null +++ b/assets/xml/objects/object_dy_obj.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_efc_star_field.xml b/assets/xml/objects/object_efc_star_field.xml new file mode 100644 index 000000000..72b7ef636 --- /dev/null +++ b/assets/xml/objects/object_efc_star_field.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_efc_tw.xml b/assets/xml/objects/object_efc_tw.xml new file mode 100644 index 000000000..f251f9607 --- /dev/null +++ b/assets/xml/objects/object_efc_tw.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_eg.xml b/assets/xml/objects/object_eg.xml new file mode 100644 index 000000000..1458afaec --- /dev/null +++ b/assets/xml/objects/object_eg.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ending_obj.xml b/assets/xml/objects/object_ending_obj.xml new file mode 100644 index 000000000..ad13ce7b8 --- /dev/null +++ b/assets/xml/objects/object_ending_obj.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_f40_obj.xml b/assets/xml/objects/object_f40_obj.xml new file mode 100644 index 000000000..59bff9d05 --- /dev/null +++ b/assets/xml/objects/object_f40_obj.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_f40_switch.xml b/assets/xml/objects/object_f40_switch.xml new file mode 100644 index 000000000..a5c823baa --- /dev/null +++ b/assets/xml/objects/object_f40_switch.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_f52_obj.xml b/assets/xml/objects/object_f52_obj.xml new file mode 100644 index 000000000..7f35d8b1b --- /dev/null +++ b/assets/xml/objects/object_f52_obj.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_f53_obj.xml b/assets/xml/objects/object_f53_obj.xml new file mode 100644 index 000000000..8fef96ac8 --- /dev/null +++ b/assets/xml/objects/object_f53_obj.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_fall.xml b/assets/xml/objects/object_fall.xml new file mode 100644 index 000000000..5a90c5a24 --- /dev/null +++ b/assets/xml/objects/object_fall.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_fall2.xml b/assets/xml/objects/object_fall2.xml new file mode 100644 index 000000000..e616de260 --- /dev/null +++ b/assets/xml/objects/object_fall2.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_famos.xml b/assets/xml/objects/object_famos.xml new file mode 100644 index 000000000..7cec70be5 --- /dev/null +++ b/assets/xml/objects/object_famos.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_fb.xml b/assets/xml/objects/object_fb.xml new file mode 100644 index 000000000..101ddbc5a --- /dev/null +++ b/assets/xml/objects/object_fb.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_firefly.xml b/assets/xml/objects/object_firefly.xml new file mode 100644 index 000000000..f6d8f1bc7 --- /dev/null +++ b/assets/xml/objects/object_firefly.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_fish.xml b/assets/xml/objects/object_fish.xml new file mode 100644 index 000000000..c0cbd54c7 --- /dev/null +++ b/assets/xml/objects/object_fish.xml @@ -0,0 +1,162 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_flowerpot.xml b/assets/xml/objects/object_flowerpot.xml new file mode 100644 index 000000000..b6adc70d4 --- /dev/null +++ b/assets/xml/objects/object_flowerpot.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_fr.xml b/assets/xml/objects/object_fr.xml new file mode 100644 index 000000000..b1d284de9 --- /dev/null +++ b/assets/xml/objects/object_fr.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_fsn.xml b/assets/xml/objects/object_fsn.xml new file mode 100644 index 000000000..f2d4b3648 --- /dev/null +++ b/assets/xml/objects/object_fsn.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_fu.xml b/assets/xml/objects/object_fu.xml new file mode 100644 index 000000000..83d2f9eff --- /dev/null +++ b/assets/xml/objects/object_fu.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_fu_kaiten.xml b/assets/xml/objects/object_fu_kaiten.xml new file mode 100644 index 000000000..bce80f68c --- /dev/null +++ b/assets/xml/objects/object_fu_kaiten.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_fu_mato.xml b/assets/xml/objects/object_fu_mato.xml new file mode 100644 index 000000000..b28899f3c --- /dev/null +++ b/assets/xml/objects/object_fu_mato.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_funen.xml b/assets/xml/objects/object_funen.xml new file mode 100644 index 000000000..5f8c18c3d --- /dev/null +++ b/assets/xml/objects/object_funen.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_fusen.xml b/assets/xml/objects/object_fusen.xml new file mode 100644 index 000000000..0ff9e9f6c --- /dev/null +++ b/assets/xml/objects/object_fusen.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_fwall.xml b/assets/xml/objects/object_fwall.xml new file mode 100644 index 000000000..1f7fb575b --- /dev/null +++ b/assets/xml/objects/object_fwall.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_fz.xml b/assets/xml/objects/object_fz.xml new file mode 100644 index 000000000..0c0b2ce2b --- /dev/null +++ b/assets/xml/objects/object_fz.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ge1.xml b/assets/xml/objects/object_ge1.xml new file mode 100644 index 000000000..e401fd088 --- /dev/null +++ b/assets/xml/objects/object_ge1.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_geldb.xml b/assets/xml/objects/object_geldb.xml new file mode 100644 index 000000000..357b83284 --- /dev/null +++ b/assets/xml/objects/object_geldb.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gg.xml b/assets/xml/objects/object_gg.xml new file mode 100644 index 000000000..e1ac1c779 --- /dev/null +++ b/assets/xml/objects/object_gg.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ghaka.xml b/assets/xml/objects/object_ghaka.xml new file mode 100644 index 000000000..6ca9a32b0 --- /dev/null +++ b/assets/xml/objects/object_ghaka.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_arrow.xml b/assets/xml/objects/object_gi_arrow.xml new file mode 100644 index 000000000..ab3bcbde9 --- /dev/null +++ b/assets/xml/objects/object_gi_arrow.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_gi_arrowcase.xml b/assets/xml/objects/object_gi_arrowcase.xml new file mode 100644 index 000000000..ae10b4faa --- /dev/null +++ b/assets/xml/objects/object_gi_arrowcase.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_bean.xml b/assets/xml/objects/object_gi_bean.xml new file mode 100644 index 000000000..e19b48d14 --- /dev/null +++ b/assets/xml/objects/object_gi_bean.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_gi_bigbomb.xml b/assets/xml/objects/object_gi_bigbomb.xml new file mode 100644 index 000000000..27d2a0741 --- /dev/null +++ b/assets/xml/objects/object_gi_bigbomb.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_bomb_1.xml b/assets/xml/objects/object_gi_bomb_1.xml new file mode 100644 index 000000000..98af21873 --- /dev/null +++ b/assets/xml/objects/object_gi_bomb_1.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_gi_bomb_2.xml b/assets/xml/objects/object_gi_bomb_2.xml new file mode 100644 index 000000000..ecd07c048 --- /dev/null +++ b/assets/xml/objects/object_gi_bomb_2.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_gi_bombpouch.xml b/assets/xml/objects/object_gi_bombpouch.xml new file mode 100644 index 000000000..06eff7ced --- /dev/null +++ b/assets/xml/objects/object_gi_bombpouch.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_bosskey.xml b/assets/xml/objects/object_gi_bosskey.xml new file mode 100644 index 000000000..ae5ac2e75 --- /dev/null +++ b/assets/xml/objects/object_gi_bosskey.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_gi_bottle.xml b/assets/xml/objects/object_gi_bottle.xml new file mode 100644 index 000000000..95a7b8bce --- /dev/null +++ b/assets/xml/objects/object_gi_bottle.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_gi_bottle_04.xml b/assets/xml/objects/object_gi_bottle_04.xml new file mode 100644 index 000000000..f215d4059 --- /dev/null +++ b/assets/xml/objects/object_gi_bottle_04.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_bottle_15.xml b/assets/xml/objects/object_gi_bottle_15.xml new file mode 100644 index 000000000..afea0f6ca --- /dev/null +++ b/assets/xml/objects/object_gi_bottle_15.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_bottle_16.xml b/assets/xml/objects/object_gi_bottle_16.xml new file mode 100644 index 000000000..7ee7f3640 --- /dev/null +++ b/assets/xml/objects/object_gi_bottle_16.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_bottle_21.xml b/assets/xml/objects/object_gi_bottle_21.xml new file mode 100644 index 000000000..779b474cd --- /dev/null +++ b/assets/xml/objects/object_gi_bottle_21.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_bottle_22.xml b/assets/xml/objects/object_gi_bottle_22.xml new file mode 100644 index 000000000..d61397014 --- /dev/null +++ b/assets/xml/objects/object_gi_bottle_22.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_bottle_red.xml b/assets/xml/objects/object_gi_bottle_red.xml new file mode 100644 index 000000000..c2f189dce --- /dev/null +++ b/assets/xml/objects/object_gi_bottle_red.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_bow.xml b/assets/xml/objects/object_gi_bow.xml new file mode 100644 index 000000000..b7d62e12d --- /dev/null +++ b/assets/xml/objects/object_gi_bow.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_camera.xml b/assets/xml/objects/object_gi_camera.xml new file mode 100644 index 000000000..81641ca30 --- /dev/null +++ b/assets/xml/objects/object_gi_camera.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_compass.xml b/assets/xml/objects/object_gi_compass.xml new file mode 100644 index 000000000..49f7cf87e --- /dev/null +++ b/assets/xml/objects/object_gi_compass.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_gi_fieldmap.xml b/assets/xml/objects/object_gi_fieldmap.xml new file mode 100644 index 000000000..bdb77ad0b --- /dev/null +++ b/assets/xml/objects/object_gi_fieldmap.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_fish.xml b/assets/xml/objects/object_gi_fish.xml new file mode 100644 index 000000000..339f2d144 --- /dev/null +++ b/assets/xml/objects/object_gi_fish.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_gi_ghost.xml b/assets/xml/objects/object_gi_ghost.xml new file mode 100644 index 000000000..813ba7d4e --- /dev/null +++ b/assets/xml/objects/object_gi_ghost.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_glasses.xml b/assets/xml/objects/object_gi_glasses.xml new file mode 100644 index 000000000..571f0ea6d --- /dev/null +++ b/assets/xml/objects/object_gi_glasses.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_gi_gold_dust.xml b/assets/xml/objects/object_gi_gold_dust.xml new file mode 100644 index 000000000..ed787b2b2 --- /dev/null +++ b/assets/xml/objects/object_gi_gold_dust.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_golonmask.xml b/assets/xml/objects/object_gi_golonmask.xml new file mode 100644 index 000000000..c845fd0bd --- /dev/null +++ b/assets/xml/objects/object_gi_golonmask.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_heart.xml b/assets/xml/objects/object_gi_heart.xml new file mode 100644 index 000000000..0917876aa --- /dev/null +++ b/assets/xml/objects/object_gi_heart.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_gi_hearts.xml b/assets/xml/objects/object_gi_hearts.xml new file mode 100644 index 000000000..442ba21c7 --- /dev/null +++ b/assets/xml/objects/object_gi_hearts.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_gi_hookshot.xml b/assets/xml/objects/object_gi_hookshot.xml new file mode 100644 index 000000000..37a0b4642 --- /dev/null +++ b/assets/xml/objects/object_gi_hookshot.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_insect.xml b/assets/xml/objects/object_gi_insect.xml new file mode 100644 index 000000000..a7c3107ea --- /dev/null +++ b/assets/xml/objects/object_gi_insect.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_gi_key.xml b/assets/xml/objects/object_gi_key.xml new file mode 100644 index 000000000..bf4cdb727 --- /dev/null +++ b/assets/xml/objects/object_gi_key.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_gi_ki_tan_mask.xml b/assets/xml/objects/object_gi_ki_tan_mask.xml new file mode 100644 index 000000000..313576631 --- /dev/null +++ b/assets/xml/objects/object_gi_ki_tan_mask.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_gi_liquid.xml b/assets/xml/objects/object_gi_liquid.xml new file mode 100644 index 000000000..bec768cfe --- /dev/null +++ b/assets/xml/objects/object_gi_liquid.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_loach.xml b/assets/xml/objects/object_gi_loach.xml new file mode 100644 index 000000000..c9c81f0b9 --- /dev/null +++ b/assets/xml/objects/object_gi_loach.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_longsword.xml b/assets/xml/objects/object_gi_longsword.xml new file mode 100644 index 000000000..6be60d411 --- /dev/null +++ b/assets/xml/objects/object_gi_longsword.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_gi_m_arrow.xml b/assets/xml/objects/object_gi_m_arrow.xml new file mode 100644 index 000000000..6351783b5 --- /dev/null +++ b/assets/xml/objects/object_gi_m_arrow.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_magicmushroom.xml b/assets/xml/objects/object_gi_magicmushroom.xml new file mode 100644 index 000000000..ae6cbeb49 --- /dev/null +++ b/assets/xml/objects/object_gi_magicmushroom.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_magicpot.xml b/assets/xml/objects/object_gi_magicpot.xml new file mode 100644 index 000000000..2abd48eef --- /dev/null +++ b/assets/xml/objects/object_gi_magicpot.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_gi_map.xml b/assets/xml/objects/object_gi_map.xml new file mode 100644 index 000000000..250bb4613 --- /dev/null +++ b/assets/xml/objects/object_gi_map.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_gi_mask03.xml b/assets/xml/objects/object_gi_mask03.xml new file mode 100644 index 000000000..561ddef83 --- /dev/null +++ b/assets/xml/objects/object_gi_mask03.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask05.xml b/assets/xml/objects/object_gi_mask05.xml new file mode 100644 index 000000000..307a3b2f4 --- /dev/null +++ b/assets/xml/objects/object_gi_mask05.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask06.xml b/assets/xml/objects/object_gi_mask06.xml new file mode 100644 index 000000000..256d9a91e --- /dev/null +++ b/assets/xml/objects/object_gi_mask06.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask09.xml b/assets/xml/objects/object_gi_mask09.xml new file mode 100644 index 000000000..d6db047d5 --- /dev/null +++ b/assets/xml/objects/object_gi_mask09.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask10.xml b/assets/xml/objects/object_gi_mask10.xml new file mode 100644 index 000000000..adb3ee1d2 --- /dev/null +++ b/assets/xml/objects/object_gi_mask10.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask11.xml b/assets/xml/objects/object_gi_mask11.xml new file mode 100644 index 000000000..46de5c2cd --- /dev/null +++ b/assets/xml/objects/object_gi_mask11.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask12.xml b/assets/xml/objects/object_gi_mask12.xml new file mode 100644 index 000000000..dced8d8eb --- /dev/null +++ b/assets/xml/objects/object_gi_mask12.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask13.xml b/assets/xml/objects/object_gi_mask13.xml new file mode 100644 index 000000000..b6d2c7733 --- /dev/null +++ b/assets/xml/objects/object_gi_mask13.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask14.xml b/assets/xml/objects/object_gi_mask14.xml new file mode 100644 index 000000000..a3c96bb9d --- /dev/null +++ b/assets/xml/objects/object_gi_mask14.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask15.xml b/assets/xml/objects/object_gi_mask15.xml new file mode 100644 index 000000000..bc612c075 --- /dev/null +++ b/assets/xml/objects/object_gi_mask15.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask16.xml b/assets/xml/objects/object_gi_mask16.xml new file mode 100644 index 000000000..57124d4d4 --- /dev/null +++ b/assets/xml/objects/object_gi_mask16.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask17.xml b/assets/xml/objects/object_gi_mask17.xml new file mode 100644 index 000000000..a509ca27e --- /dev/null +++ b/assets/xml/objects/object_gi_mask17.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask18.xml b/assets/xml/objects/object_gi_mask18.xml new file mode 100644 index 000000000..8e1c8ca54 --- /dev/null +++ b/assets/xml/objects/object_gi_mask18.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask20.xml b/assets/xml/objects/object_gi_mask20.xml new file mode 100644 index 000000000..8b87c44fa --- /dev/null +++ b/assets/xml/objects/object_gi_mask20.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask21.xml b/assets/xml/objects/object_gi_mask21.xml new file mode 100644 index 000000000..175d22b85 --- /dev/null +++ b/assets/xml/objects/object_gi_mask21.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask22.xml b/assets/xml/objects/object_gi_mask22.xml new file mode 100644 index 000000000..7b3a49e53 --- /dev/null +++ b/assets/xml/objects/object_gi_mask22.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_mask23.xml b/assets/xml/objects/object_gi_mask23.xml new file mode 100644 index 000000000..458b7c825 --- /dev/null +++ b/assets/xml/objects/object_gi_mask23.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_melody.xml b/assets/xml/objects/object_gi_melody.xml new file mode 100644 index 000000000..d7617e7a6 --- /dev/null +++ b/assets/xml/objects/object_gi_melody.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_milk.xml b/assets/xml/objects/object_gi_milk.xml new file mode 100644 index 000000000..137dae777 --- /dev/null +++ b/assets/xml/objects/object_gi_milk.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_gi_mssa.xml b/assets/xml/objects/object_gi_mssa.xml new file mode 100644 index 000000000..6b61b00f5 --- /dev/null +++ b/assets/xml/objects/object_gi_mssa.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_nuts.xml b/assets/xml/objects/object_gi_nuts.xml new file mode 100644 index 000000000..073e7db8f --- /dev/null +++ b/assets/xml/objects/object_gi_nuts.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_gi_nutsmask.xml b/assets/xml/objects/object_gi_nutsmask.xml new file mode 100644 index 000000000..e34a593f2 --- /dev/null +++ b/assets/xml/objects/object_gi_nutsmask.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_ocarina.xml b/assets/xml/objects/object_gi_ocarina.xml new file mode 100644 index 000000000..7b968a491 --- /dev/null +++ b/assets/xml/objects/object_gi_ocarina.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_gi_purse.xml b/assets/xml/objects/object_gi_purse.xml new file mode 100644 index 000000000..49cf9fd37 --- /dev/null +++ b/assets/xml/objects/object_gi_purse.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_rabit_mask.xml b/assets/xml/objects/object_gi_rabit_mask.xml new file mode 100644 index 000000000..172c080f1 --- /dev/null +++ b/assets/xml/objects/object_gi_rabit_mask.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_gi_reserve00.xml b/assets/xml/objects/object_gi_reserve00.xml new file mode 100644 index 000000000..1527a2630 --- /dev/null +++ b/assets/xml/objects/object_gi_reserve00.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_reserve01.xml b/assets/xml/objects/object_gi_reserve01.xml new file mode 100644 index 000000000..c31c76698 --- /dev/null +++ b/assets/xml/objects/object_gi_reserve01.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_reserve_b_00.xml b/assets/xml/objects/object_gi_reserve_b_00.xml new file mode 100644 index 000000000..1c1e54390 --- /dev/null +++ b/assets/xml/objects/object_gi_reserve_b_00.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_reserve_b_01.xml b/assets/xml/objects/object_gi_reserve_b_01.xml new file mode 100644 index 000000000..574763ee9 --- /dev/null +++ b/assets/xml/objects/object_gi_reserve_b_01.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_reserve_c_00.xml b/assets/xml/objects/object_gi_reserve_c_00.xml new file mode 100644 index 000000000..86c6b15fb --- /dev/null +++ b/assets/xml/objects/object_gi_reserve_c_00.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_reserve_c_01.xml b/assets/xml/objects/object_gi_reserve_c_01.xml new file mode 100644 index 000000000..da1530970 --- /dev/null +++ b/assets/xml/objects/object_gi_reserve_c_01.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_rupy.xml b/assets/xml/objects/object_gi_rupy.xml new file mode 100644 index 000000000..69cd8bf5c --- /dev/null +++ b/assets/xml/objects/object_gi_rupy.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_schedule.xml b/assets/xml/objects/object_gi_schedule.xml new file mode 100644 index 000000000..e5025a993 --- /dev/null +++ b/assets/xml/objects/object_gi_schedule.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_seahorse.xml b/assets/xml/objects/object_gi_seahorse.xml new file mode 100644 index 000000000..f35e2edc9 --- /dev/null +++ b/assets/xml/objects/object_gi_seahorse.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_shield_2.xml b/assets/xml/objects/object_gi_shield_2.xml new file mode 100644 index 000000000..eb9fec8d2 --- /dev/null +++ b/assets/xml/objects/object_gi_shield_2.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_shield_3.xml b/assets/xml/objects/object_gi_shield_3.xml new file mode 100644 index 000000000..8e011bb92 --- /dev/null +++ b/assets/xml/objects/object_gi_shield_3.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_gi_soldout.xml b/assets/xml/objects/object_gi_soldout.xml new file mode 100644 index 000000000..8a733af02 --- /dev/null +++ b/assets/xml/objects/object_gi_soldout.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_gi_soul.xml b/assets/xml/objects/object_gi_soul.xml new file mode 100644 index 000000000..945670888 --- /dev/null +++ b/assets/xml/objects/object_gi_soul.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_stick.xml b/assets/xml/objects/object_gi_stick.xml new file mode 100644 index 000000000..c038af357 --- /dev/null +++ b/assets/xml/objects/object_gi_stick.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_gi_stonemask.xml b/assets/xml/objects/object_gi_stonemask.xml new file mode 100644 index 000000000..9d3b62b8c --- /dev/null +++ b/assets/xml/objects/object_gi_stonemask.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_sutaru.xml b/assets/xml/objects/object_gi_sutaru.xml new file mode 100644 index 000000000..3b991123e --- /dev/null +++ b/assets/xml/objects/object_gi_sutaru.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_gi_sword_1.xml b/assets/xml/objects/object_gi_sword_1.xml new file mode 100644 index 000000000..a03de82d5 --- /dev/null +++ b/assets/xml/objects/object_gi_sword_1.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_sword_2.xml b/assets/xml/objects/object_gi_sword_2.xml new file mode 100644 index 000000000..045936ef2 --- /dev/null +++ b/assets/xml/objects/object_gi_sword_2.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_sword_3.xml b/assets/xml/objects/object_gi_sword_3.xml new file mode 100644 index 000000000..79a207991 --- /dev/null +++ b/assets/xml/objects/object_gi_sword_3.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_sword_4.xml b/assets/xml/objects/object_gi_sword_4.xml new file mode 100644 index 000000000..b5c826dc3 --- /dev/null +++ b/assets/xml/objects/object_gi_sword_4.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_gi_truth_mask.xml b/assets/xml/objects/object_gi_truth_mask.xml new file mode 100644 index 000000000..52fdaaf65 --- /dev/null +++ b/assets/xml/objects/object_gi_truth_mask.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_gi_zoramask.xml b/assets/xml/objects/object_gi_zoramask.xml new file mode 100644 index 000000000..c5ba218b4 --- /dev/null +++ b/assets/xml/objects/object_gi_zoramask.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_giant.xml b/assets/xml/objects/object_giant.xml new file mode 100644 index 000000000..edaeee039 --- /dev/null +++ b/assets/xml/objects/object_giant.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gk.xml b/assets/xml/objects/object_gk.xml new file mode 100644 index 000000000..420f544f1 --- /dev/null +++ b/assets/xml/objects/object_gk.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gla.xml b/assets/xml/objects/object_gla.xml new file mode 100644 index 000000000..ee793c256 --- /dev/null +++ b/assets/xml/objects/object_gla.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gm.xml b/assets/xml/objects/object_gm.xml new file mode 100644 index 000000000..50c852ade --- /dev/null +++ b/assets/xml/objects/object_gm.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_gmo.xml b/assets/xml/objects/object_gmo.xml new file mode 100644 index 000000000..4884d7919 --- /dev/null +++ b/assets/xml/objects/object_gmo.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_goroiwa.xml b/assets/xml/objects/object_goroiwa.xml new file mode 100644 index 000000000..e6ddfe7c1 --- /dev/null +++ b/assets/xml/objects/object_goroiwa.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_goronswitch.xml b/assets/xml/objects/object_goronswitch.xml new file mode 100644 index 000000000..a6a0f996f --- /dev/null +++ b/assets/xml/objects/object_goronswitch.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_grasshopper.xml b/assets/xml/objects/object_grasshopper.xml new file mode 100644 index 000000000..5b8ee82af --- /dev/null +++ b/assets/xml/objects/object_grasshopper.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_gs.xml b/assets/xml/objects/object_gs.xml new file mode 100644 index 000000000..1e9b159df --- /dev/null +++ b/assets/xml/objects/object_gs.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_ha.xml b/assets/xml/objects/object_ha.xml new file mode 100644 index 000000000..f3d3f1029 --- /dev/null +++ b/assets/xml/objects/object_ha.xml @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_haka_obj.xml b/assets/xml/objects/object_haka_obj.xml new file mode 100644 index 000000000..57f34f0d1 --- /dev/null +++ b/assets/xml/objects/object_haka_obj.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_hakaisi.xml b/assets/xml/objects/object_hakaisi.xml new file mode 100644 index 000000000..82e80242e --- /dev/null +++ b/assets/xml/objects/object_hakaisi.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_hakugin_demo.xml b/assets/xml/objects/object_hakugin_demo.xml new file mode 100644 index 000000000..24c7a2ba2 --- /dev/null +++ b/assets/xml/objects/object_hakugin_demo.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_hakugin_obj.xml b/assets/xml/objects/object_hakugin_obj.xml new file mode 100644 index 000000000..412d0bdd3 --- /dev/null +++ b/assets/xml/objects/object_hakugin_obj.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_hana.xml b/assets/xml/objects/object_hana.xml new file mode 100644 index 000000000..3812a4ff5 --- /dev/null +++ b/assets/xml/objects/object_hana.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_hanareyama_obj.xml b/assets/xml/objects/object_hanareyama_obj.xml new file mode 100644 index 000000000..ba213a585 --- /dev/null +++ b/assets/xml/objects/object_hanareyama_obj.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_harfgibud.xml b/assets/xml/objects/object_harfgibud.xml new file mode 100644 index 000000000..9a9bf4745 --- /dev/null +++ b/assets/xml/objects/object_harfgibud.xml @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_hariko.xml b/assets/xml/objects/object_hariko.xml new file mode 100644 index 000000000..e0f139b88 --- /dev/null +++ b/assets/xml/objects/object_hariko.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_hata.xml b/assets/xml/objects/object_hata.xml new file mode 100644 index 000000000..3131a6628 --- /dev/null +++ b/assets/xml/objects/object_hata.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_hgdoor.xml b/assets/xml/objects/object_hgdoor.xml new file mode 100644 index 000000000..e897103bf --- /dev/null +++ b/assets/xml/objects/object_hgdoor.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_hintnuts.xml b/assets/xml/objects/object_hintnuts.xml new file mode 100644 index 000000000..655c8ae3c --- /dev/null +++ b/assets/xml/objects/object_hintnuts.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_horse_game_check.xml b/assets/xml/objects/object_horse_game_check.xml new file mode 100644 index 000000000..1ea72ac57 --- /dev/null +++ b/assets/xml/objects/object_horse_game_check.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_horse_link_child.xml b/assets/xml/objects/object_horse_link_child.xml new file mode 100644 index 000000000..f844224fa --- /dev/null +++ b/assets/xml/objects/object_horse_link_child.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_hs.xml b/assets/xml/objects/object_hs.xml new file mode 100644 index 000000000..315128815 --- /dev/null +++ b/assets/xml/objects/object_hs.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_hsstump.xml b/assets/xml/objects/object_hsstump.xml new file mode 100644 index 000000000..f94f0ed4e --- /dev/null +++ b/assets/xml/objects/object_hsstump.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_hunsui.xml b/assets/xml/objects/object_hunsui.xml new file mode 100644 index 000000000..878bf704d --- /dev/null +++ b/assets/xml/objects/object_hunsui.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ice_block.xml b/assets/xml/objects/object_ice_block.xml new file mode 100644 index 000000000..1e14ea5b5 --- /dev/null +++ b/assets/xml/objects/object_ice_block.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_icefloe.xml b/assets/xml/objects/object_icefloe.xml new file mode 100644 index 000000000..cb9b321a3 --- /dev/null +++ b/assets/xml/objects/object_icefloe.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_icicle.xml b/assets/xml/objects/object_icicle.xml new file mode 100644 index 000000000..4f7bab8a2 --- /dev/null +++ b/assets/xml/objects/object_icicle.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_ik.xml b/assets/xml/objects/object_ik.xml new file mode 100644 index 000000000..34dcac8f2 --- /dev/null +++ b/assets/xml/objects/object_ik.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ikana_obj.xml b/assets/xml/objects/object_ikana_obj.xml new file mode 100644 index 000000000..66398991b --- /dev/null +++ b/assets/xml/objects/object_ikana_obj.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ikn_demo.xml b/assets/xml/objects/object_ikn_demo.xml new file mode 100644 index 000000000..69d225933 --- /dev/null +++ b/assets/xml/objects/object_ikn_demo.xml @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ikninside_obj.xml b/assets/xml/objects/object_ikninside_obj.xml new file mode 100644 index 000000000..98ae6d34f --- /dev/null +++ b/assets/xml/objects/object_ikninside_obj.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_iknv_obj.xml b/assets/xml/objects/object_iknv_obj.xml new file mode 100644 index 000000000..1e10d813c --- /dev/null +++ b/assets/xml/objects/object_iknv_obj.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_in.xml b/assets/xml/objects/object_in.xml new file mode 100644 index 000000000..07969fe80 --- /dev/null +++ b/assets/xml/objects/object_in.xml @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_in2.xml b/assets/xml/objects/object_in2.xml new file mode 100644 index 000000000..34a942882 --- /dev/null +++ b/assets/xml/objects/object_in2.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_inibs_object.xml b/assets/xml/objects/object_inibs_object.xml new file mode 100644 index 000000000..e1d454ae7 --- /dev/null +++ b/assets/xml/objects/object_inibs_object.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ishi.xml b/assets/xml/objects/object_ishi.xml new file mode 100644 index 000000000..6e48cf5f4 --- /dev/null +++ b/assets/xml/objects/object_ishi.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_jg.xml b/assets/xml/objects/object_jg.xml new file mode 100644 index 000000000..10253e155 --- /dev/null +++ b/assets/xml/objects/object_jg.xml @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_js.xml b/assets/xml/objects/object_js.xml new file mode 100644 index 000000000..be9246ab6 --- /dev/null +++ b/assets/xml/objects/object_js.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_jso.xml b/assets/xml/objects/object_jso.xml new file mode 100644 index 000000000..777c6e53c --- /dev/null +++ b/assets/xml/objects/object_jso.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ka.xml b/assets/xml/objects/object_ka.xml new file mode 100644 index 000000000..2944a00b2 --- /dev/null +++ b/assets/xml/objects/object_ka.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kaizoku_obj.xml b/assets/xml/objects/object_kaizoku_obj.xml new file mode 100644 index 000000000..a38d16827 --- /dev/null +++ b/assets/xml/objects/object_kaizoku_obj.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kamejima.xml b/assets/xml/objects/object_kamejima.xml new file mode 100644 index 000000000..8bdb54d06 --- /dev/null +++ b/assets/xml/objects/object_kamejima.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kanban.xml b/assets/xml/objects/object_kanban.xml new file mode 100644 index 000000000..b821aa288 --- /dev/null +++ b/assets/xml/objects/object_kanban.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kbt.xml b/assets/xml/objects/object_kbt.xml new file mode 100644 index 000000000..b3ab0baaf --- /dev/null +++ b/assets/xml/objects/object_kbt.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_keikoku_demo.xml b/assets/xml/objects/object_keikoku_demo.xml new file mode 100644 index 000000000..994b682f3 --- /dev/null +++ b/assets/xml/objects/object_keikoku_demo.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_keikoku_obj.xml b/assets/xml/objects/object_keikoku_obj.xml new file mode 100644 index 000000000..ff5a6899c --- /dev/null +++ b/assets/xml/objects/object_keikoku_obj.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kepn_koya.xml b/assets/xml/objects/object_kepn_koya.xml new file mode 100644 index 000000000..893892d25 --- /dev/null +++ b/assets/xml/objects/object_kepn_koya.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kgy.xml b/assets/xml/objects/object_kgy.xml new file mode 100644 index 000000000..856c5883d --- /dev/null +++ b/assets/xml/objects/object_kgy.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kibako.xml b/assets/xml/objects/object_kibako.xml new file mode 100644 index 000000000..43276080a --- /dev/null +++ b/assets/xml/objects/object_kibako.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_kibako2.xml b/assets/xml/objects/object_kibako2.xml new file mode 100644 index 000000000..4b6ce5ac7 --- /dev/null +++ b/assets/xml/objects/object_kibako2.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kin2_obj.xml b/assets/xml/objects/object_kin2_obj.xml new file mode 100644 index 000000000..93e55786c --- /dev/null +++ b/assets/xml/objects/object_kin2_obj.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kinsta1_obj.xml b/assets/xml/objects/object_kinsta1_obj.xml new file mode 100644 index 000000000..48d40c527 --- /dev/null +++ b/assets/xml/objects/object_kinsta1_obj.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_kinsta2_obj.xml b/assets/xml/objects/object_kinsta2_obj.xml new file mode 100644 index 000000000..f27778b1a --- /dev/null +++ b/assets/xml/objects/object_kinsta2_obj.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_kitan.xml b/assets/xml/objects/object_kitan.xml new file mode 100644 index 000000000..3884470f9 --- /dev/null +++ b/assets/xml/objects/object_kitan.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_knight.xml b/assets/xml/objects/object_knight.xml new file mode 100644 index 000000000..bbd2d7b93 --- /dev/null +++ b/assets/xml/objects/object_knight.xml @@ -0,0 +1,208 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kujiya.xml b/assets/xml/objects/object_kujiya.xml new file mode 100644 index 000000000..3b17d43c0 --- /dev/null +++ b/assets/xml/objects/object_kujiya.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kumo30.xml b/assets/xml/objects/object_kumo30.xml new file mode 100644 index 000000000..24e8d3974 --- /dev/null +++ b/assets/xml/objects/object_kumo30.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kusa.xml b/assets/xml/objects/object_kusa.xml new file mode 100644 index 000000000..0d36569a5 --- /dev/null +++ b/assets/xml/objects/object_kusa.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_kz.xml b/assets/xml/objects/object_kz.xml new file mode 100644 index 000000000..24c16e1fc --- /dev/null +++ b/assets/xml/objects/object_kz.xml @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_kzsaku.xml b/assets/xml/objects/object_kzsaku.xml new file mode 100644 index 000000000..4cfce2de2 --- /dev/null +++ b/assets/xml/objects/object_kzsaku.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_ladder.xml b/assets/xml/objects/object_ladder.xml new file mode 100644 index 000000000..6e42412ec --- /dev/null +++ b/assets/xml/objects/object_ladder.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_last_obj.xml b/assets/xml/objects/object_last_obj.xml new file mode 100644 index 000000000..03dbddcf2 --- /dev/null +++ b/assets/xml/objects/object_last_obj.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_lastday.xml b/assets/xml/objects/object_lastday.xml new file mode 100644 index 000000000..9988ec1f8 --- /dev/null +++ b/assets/xml/objects/object_lastday.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_lbfshot.xml b/assets/xml/objects/object_lbfshot.xml new file mode 100644 index 000000000..325ddf49e --- /dev/null +++ b/assets/xml/objects/object_lbfshot.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_lightblock.xml b/assets/xml/objects/object_lightblock.xml new file mode 100644 index 000000000..207b03020 --- /dev/null +++ b/assets/xml/objects/object_lightblock.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_lightswitch.xml b/assets/xml/objects/object_lightswitch.xml new file mode 100644 index 000000000..3d5c3aee2 --- /dev/null +++ b/assets/xml/objects/object_lightswitch.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_link_boy.xml b/assets/xml/objects/object_link_boy.xml new file mode 100644 index 000000000..8bfd17e98 --- /dev/null +++ b/assets/xml/objects/object_link_boy.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_link_child.xml b/assets/xml/objects/object_link_child.xml new file mode 100644 index 000000000..86c596909 --- /dev/null +++ b/assets/xml/objects/object_link_child.xml @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_link_goron.xml b/assets/xml/objects/object_link_goron.xml new file mode 100644 index 000000000..05336d6db --- /dev/null +++ b/assets/xml/objects/object_link_goron.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_link_nuts.xml b/assets/xml/objects/object_link_nuts.xml new file mode 100644 index 000000000..169dc848a --- /dev/null +++ b/assets/xml/objects/object_link_nuts.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_link_zora.xml b/assets/xml/objects/object_link_zora.xml new file mode 100644 index 000000000..e3bbaba95 --- /dev/null +++ b/assets/xml/objects/object_link_zora.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_lodmoon.xml b/assets/xml/objects/object_lodmoon.xml new file mode 100644 index 000000000..46d9f8e72 --- /dev/null +++ b/assets/xml/objects/object_lodmoon.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_lotus.xml b/assets/xml/objects/object_lotus.xml new file mode 100644 index 000000000..a9835b81b --- /dev/null +++ b/assets/xml/objects/object_lotus.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_ma1.xml b/assets/xml/objects/object_ma1.xml new file mode 100644 index 000000000..98444a884 --- /dev/null +++ b/assets/xml/objects/object_ma1.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ma2.xml b/assets/xml/objects/object_ma2.xml new file mode 100644 index 000000000..523dfe212 --- /dev/null +++ b/assets/xml/objects/object_ma2.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mag.xml b/assets/xml/objects/object_mag.xml new file mode 100644 index 000000000..1feae8057 --- /dev/null +++ b/assets/xml/objects/object_mag.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mamenoki.xml b/assets/xml/objects/object_mamenoki.xml new file mode 100644 index 000000000..9ce4644c3 --- /dev/null +++ b/assets/xml/objects/object_mamenoki.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_market_obj.xml b/assets/xml/objects/object_market_obj.xml new file mode 100644 index 000000000..81ab838f1 --- /dev/null +++ b/assets/xml/objects/object_market_obj.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_maruta.xml b/assets/xml/objects/object_maruta.xml new file mode 100644 index 000000000..e61e1162b --- /dev/null +++ b/assets/xml/objects/object_maruta.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_bakuretu.xml b/assets/xml/objects/object_mask_bakuretu.xml new file mode 100644 index 000000000..2eed78171 --- /dev/null +++ b/assets/xml/objects/object_mask_bakuretu.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_bigelf.xml b/assets/xml/objects/object_mask_bigelf.xml new file mode 100644 index 000000000..762d11808 --- /dev/null +++ b/assets/xml/objects/object_mask_bigelf.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_boy.xml b/assets/xml/objects/object_mask_boy.xml new file mode 100644 index 000000000..e0f93797e --- /dev/null +++ b/assets/xml/objects/object_mask_boy.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_bree.xml b/assets/xml/objects/object_mask_bree.xml new file mode 100644 index 000000000..9fda443c8 --- /dev/null +++ b/assets/xml/objects/object_mask_bree.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_bu_san.xml b/assets/xml/objects/object_mask_bu_san.xml new file mode 100644 index 000000000..621e748ed --- /dev/null +++ b/assets/xml/objects/object_mask_bu_san.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_dancer.xml b/assets/xml/objects/object_mask_dancer.xml new file mode 100644 index 000000000..a2a37c958 --- /dev/null +++ b/assets/xml/objects/object_mask_dancer.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_gero.xml b/assets/xml/objects/object_mask_gero.xml new file mode 100644 index 000000000..b6acf6c17 --- /dev/null +++ b/assets/xml/objects/object_mask_gero.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_gibudo.xml b/assets/xml/objects/object_mask_gibudo.xml new file mode 100644 index 000000000..76bf2b3de --- /dev/null +++ b/assets/xml/objects/object_mask_gibudo.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_mask_goron.xml b/assets/xml/objects/object_mask_goron.xml new file mode 100644 index 000000000..56a67218e --- /dev/null +++ b/assets/xml/objects/object_mask_goron.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_json.xml b/assets/xml/objects/object_mask_json.xml new file mode 100644 index 000000000..1a5c10eb1 --- /dev/null +++ b/assets/xml/objects/object_mask_json.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_kerfay.xml b/assets/xml/objects/object_mask_kerfay.xml new file mode 100644 index 000000000..282aa8029 --- /dev/null +++ b/assets/xml/objects/object_mask_kerfay.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_ki_tan.xml b/assets/xml/objects/object_mask_ki_tan.xml new file mode 100644 index 000000000..f0322cc83 --- /dev/null +++ b/assets/xml/objects/object_mask_ki_tan.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_mask_kyojin.xml b/assets/xml/objects/object_mask_kyojin.xml new file mode 100644 index 000000000..cd07a57fd --- /dev/null +++ b/assets/xml/objects/object_mask_kyojin.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_mask_meoto.xml b/assets/xml/objects/object_mask_meoto.xml new file mode 100644 index 000000000..069e521e0 --- /dev/null +++ b/assets/xml/objects/object_mask_meoto.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_mask_nuts.xml b/assets/xml/objects/object_mask_nuts.xml new file mode 100644 index 000000000..6a0eaf26d --- /dev/null +++ b/assets/xml/objects/object_mask_nuts.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_mask_posthat.xml b/assets/xml/objects/object_mask_posthat.xml new file mode 100644 index 000000000..bccbfb301 --- /dev/null +++ b/assets/xml/objects/object_mask_posthat.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_mask_rabit.xml b/assets/xml/objects/object_mask_rabit.xml new file mode 100644 index 000000000..a4a1f5c0c --- /dev/null +++ b/assets/xml/objects/object_mask_rabit.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_mask_romerny.xml b/assets/xml/objects/object_mask_romerny.xml new file mode 100644 index 000000000..603feef0d --- /dev/null +++ b/assets/xml/objects/object_mask_romerny.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_skj.xml b/assets/xml/objects/object_mask_skj.xml new file mode 100644 index 000000000..457cd94f2 --- /dev/null +++ b/assets/xml/objects/object_mask_skj.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_stone.xml b/assets/xml/objects/object_mask_stone.xml new file mode 100644 index 000000000..24f67d1df --- /dev/null +++ b/assets/xml/objects/object_mask_stone.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_mask_truth.xml b/assets/xml/objects/object_mask_truth.xml new file mode 100644 index 000000000..3fed737a2 --- /dev/null +++ b/assets/xml/objects/object_mask_truth.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_mask_yofukasi.xml b/assets/xml/objects/object_mask_yofukasi.xml new file mode 100644 index 000000000..990543e1b --- /dev/null +++ b/assets/xml/objects/object_mask_yofukasi.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_mask_zacho.xml b/assets/xml/objects/object_mask_zacho.xml new file mode 100644 index 000000000..ae63753de --- /dev/null +++ b/assets/xml/objects/object_mask_zacho.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mask_zora.xml b/assets/xml/objects/object_mask_zora.xml new file mode 100644 index 000000000..c2e07cde2 --- /dev/null +++ b/assets/xml/objects/object_mask_zora.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_mastergolon.xml b/assets/xml/objects/object_mastergolon.xml new file mode 100644 index 000000000..ae481332c --- /dev/null +++ b/assets/xml/objects/object_mastergolon.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_masterzoora.xml b/assets/xml/objects/object_masterzoora.xml new file mode 100644 index 000000000..c4f8735d7 --- /dev/null +++ b/assets/xml/objects/object_masterzoora.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_mbar_obj.xml b/assets/xml/objects/object_mbar_obj.xml new file mode 100644 index 000000000..d69d7ce3b --- /dev/null +++ b/assets/xml/objects/object_mbar_obj.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_meganeana_obj.xml b/assets/xml/objects/object_meganeana_obj.xml new file mode 100644 index 000000000..457c937bd --- /dev/null +++ b/assets/xml/objects/object_meganeana_obj.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_milkbar.xml b/assets/xml/objects/object_milkbar.xml new file mode 100644 index 000000000..38bec140b --- /dev/null +++ b/assets/xml/objects/object_milkbar.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mir_ray.xml b/assets/xml/objects/object_mir_ray.xml new file mode 100644 index 000000000..962982322 --- /dev/null +++ b/assets/xml/objects/object_mir_ray.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mk.xml b/assets/xml/objects/object_mk.xml new file mode 100644 index 000000000..c927f33de --- /dev/null +++ b/assets/xml/objects/object_mk.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mkk.xml b/assets/xml/objects/object_mkk.xml new file mode 100644 index 000000000..17f36f323 --- /dev/null +++ b/assets/xml/objects/object_mkk.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mm.xml b/assets/xml/objects/object_mm.xml new file mode 100644 index 000000000..3ce9c1925 --- /dev/null +++ b/assets/xml/objects/object_mm.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mnk.xml b/assets/xml/objects/object_mnk.xml new file mode 100644 index 000000000..8f813ba00 --- /dev/null +++ b/assets/xml/objects/object_mnk.xml @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_moonend.xml b/assets/xml/objects/object_moonend.xml new file mode 100644 index 000000000..e677f9c3f --- /dev/null +++ b/assets/xml/objects/object_moonend.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_moonston.xml b/assets/xml/objects/object_moonston.xml new file mode 100644 index 000000000..cc06a9632 --- /dev/null +++ b/assets/xml/objects/object_moonston.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_ms.xml b/assets/xml/objects/object_ms.xml new file mode 100644 index 000000000..9d7df53ad --- /dev/null +++ b/assets/xml/objects/object_ms.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_msmo.xml b/assets/xml/objects/object_msmo.xml new file mode 100644 index 000000000..cb08f53ef --- /dev/null +++ b/assets/xml/objects/object_msmo.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_mtoride.xml b/assets/xml/objects/object_mtoride.xml new file mode 100644 index 000000000..ab0792839 --- /dev/null +++ b/assets/xml/objects/object_mtoride.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_mu.xml b/assets/xml/objects/object_mu.xml new file mode 100644 index 000000000..a1c11fed2 --- /dev/null +++ b/assets/xml/objects/object_mu.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_nb.xml b/assets/xml/objects/object_nb.xml new file mode 100644 index 000000000..e0f557f98 --- /dev/null +++ b/assets/xml/objects/object_nb.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_niw.xml b/assets/xml/objects/object_niw.xml new file mode 100644 index 000000000..f97b5d726 --- /dev/null +++ b/assets/xml/objects/object_niw.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_nnh.xml b/assets/xml/objects/object_nnh.xml new file mode 100644 index 000000000..1bb833cf0 --- /dev/null +++ b/assets/xml/objects/object_nnh.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_numa_obj.xml b/assets/xml/objects/object_numa_obj.xml new file mode 100644 index 000000000..cc36fa1b8 --- /dev/null +++ b/assets/xml/objects/object_numa_obj.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_nwc.xml b/assets/xml/objects/object_nwc.xml new file mode 100644 index 000000000..77b395b58 --- /dev/null +++ b/assets/xml/objects/object_nwc.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ny.xml b/assets/xml/objects/object_ny.xml new file mode 100644 index 000000000..186dd91c3 --- /dev/null +++ b/assets/xml/objects/object_ny.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_oF1d_map.xml b/assets/xml/objects/object_oF1d_map.xml new file mode 100644 index 000000000..9557dc73e --- /dev/null +++ b/assets/xml/objects/object_oF1d_map.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ob.xml b/assets/xml/objects/object_ob.xml new file mode 100644 index 000000000..7a75a59f2 --- /dev/null +++ b/assets/xml/objects/object_ob.xml @@ -0,0 +1,84 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_obj_chan.xml b/assets/xml/objects/object_obj_chan.xml new file mode 100644 index 000000000..8469110e4 --- /dev/null +++ b/assets/xml/objects/object_obj_chan.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_obj_danpeilift.xml b/assets/xml/objects/object_obj_danpeilift.xml new file mode 100644 index 000000000..2d3c26567 --- /dev/null +++ b/assets/xml/objects/object_obj_danpeilift.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_obj_dinner.xml b/assets/xml/objects/object_obj_dinner.xml new file mode 100644 index 000000000..6ca440035 --- /dev/null +++ b/assets/xml/objects/object_obj_dinner.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_obj_milk_bin.xml b/assets/xml/objects/object_obj_milk_bin.xml new file mode 100644 index 000000000..4a0ca700b --- /dev/null +++ b/assets/xml/objects/object_obj_milk_bin.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_obj_tokeidai.xml b/assets/xml/objects/object_obj_tokeidai.xml new file mode 100644 index 000000000..9141b67ff --- /dev/null +++ b/assets/xml/objects/object_obj_tokeidai.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_obj_usiyane.xml b/assets/xml/objects/object_obj_usiyane.xml new file mode 100644 index 000000000..339b25df9 --- /dev/null +++ b/assets/xml/objects/object_obj_usiyane.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_obj_yasi.xml b/assets/xml/objects/object_obj_yasi.xml new file mode 100644 index 000000000..b7d2c1fd1 --- /dev/null +++ b/assets/xml/objects/object_obj_yasi.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_okuta.xml b/assets/xml/objects/object_okuta.xml new file mode 100644 index 000000000..0eebb587e --- /dev/null +++ b/assets/xml/objects/object_okuta.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_omoya_obj.xml b/assets/xml/objects/object_omoya_obj.xml new file mode 100644 index 000000000..85389f314 --- /dev/null +++ b/assets/xml/objects/object_omoya_obj.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_open_obj.xml b/assets/xml/objects/object_open_obj.xml new file mode 100644 index 000000000..ea1664a88 --- /dev/null +++ b/assets/xml/objects/object_open_obj.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_os_anime.xml b/assets/xml/objects/object_os_anime.xml new file mode 100644 index 000000000..7957dd58d --- /dev/null +++ b/assets/xml/objects/object_os_anime.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_osn.xml b/assets/xml/objects/object_osn.xml new file mode 100644 index 000000000..0994d057f --- /dev/null +++ b/assets/xml/objects/object_osn.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ot.xml b/assets/xml/objects/object_ot.xml new file mode 100644 index 000000000..1fb04a34a --- /dev/null +++ b/assets/xml/objects/object_ot.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_owl.xml b/assets/xml/objects/object_owl.xml new file mode 100644 index 000000000..b35f38b0f --- /dev/null +++ b/assets/xml/objects/object_owl.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_oyu.xml b/assets/xml/objects/object_oyu.xml new file mode 100644 index 000000000..aa762ce59 --- /dev/null +++ b/assets/xml/objects/object_oyu.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_pamera.xml b/assets/xml/objects/object_pamera.xml new file mode 100644 index 000000000..901a7523b --- /dev/null +++ b/assets/xml/objects/object_pamera.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ph.xml b/assets/xml/objects/object_ph.xml new file mode 100644 index 000000000..df0cff73d --- /dev/null +++ b/assets/xml/objects/object_ph.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_po.xml b/assets/xml/objects/object_po.xml new file mode 100644 index 000000000..5d66d380c --- /dev/null +++ b/assets/xml/objects/object_po.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_po_composer.xml b/assets/xml/objects/object_po_composer.xml new file mode 100644 index 000000000..288dd41c3 --- /dev/null +++ b/assets/xml/objects/object_po_composer.xml @@ -0,0 +1,58 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_po_fusen.xml b/assets/xml/objects/object_po_fusen.xml new file mode 100644 index 000000000..6dd6d1f9b --- /dev/null +++ b/assets/xml/objects/object_po_fusen.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_po_sisters.xml b/assets/xml/objects/object_po_sisters.xml new file mode 100644 index 000000000..6004d6cbf --- /dev/null +++ b/assets/xml/objects/object_po_sisters.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_posthouse_obj.xml b/assets/xml/objects/object_posthouse_obj.xml new file mode 100644 index 000000000..8a324672b --- /dev/null +++ b/assets/xml/objects/object_posthouse_obj.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_pp.xml b/assets/xml/objects/object_pp.xml new file mode 100644 index 000000000..63bf541cd --- /dev/null +++ b/assets/xml/objects/object_pp.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_pr.xml b/assets/xml/objects/object_pr.xml new file mode 100644 index 000000000..27a03fdcf --- /dev/null +++ b/assets/xml/objects/object_pr.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ps.xml b/assets/xml/objects/object_ps.xml new file mode 100644 index 000000000..9febc5660 --- /dev/null +++ b/assets/xml/objects/object_ps.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_pst.xml b/assets/xml/objects/object_pst.xml new file mode 100644 index 000000000..9d62acba7 --- /dev/null +++ b/assets/xml/objects/object_pst.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_racetsubo.xml b/assets/xml/objects/object_racetsubo.xml new file mode 100644 index 000000000..6558fcbe5 --- /dev/null +++ b/assets/xml/objects/object_racetsubo.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_raf.xml b/assets/xml/objects/object_raf.xml new file mode 100644 index 000000000..df3d619d1 --- /dev/null +++ b/assets/xml/objects/object_raf.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_raillift.xml b/assets/xml/objects/object_raillift.xml new file mode 100644 index 000000000..241a7346b --- /dev/null +++ b/assets/xml/objects/object_raillift.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_random_obj.xml b/assets/xml/objects/object_random_obj.xml new file mode 100644 index 000000000..9b9986ca1 --- /dev/null +++ b/assets/xml/objects/object_random_obj.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_rat.xml b/assets/xml/objects/object_rat.xml new file mode 100644 index 000000000..5c979b098 --- /dev/null +++ b/assets/xml/objects/object_rat.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_rb.xml b/assets/xml/objects/object_rb.xml new file mode 100644 index 000000000..3898e8417 --- /dev/null +++ b/assets/xml/objects/object_rb.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_rd.xml b/assets/xml/objects/object_rd.xml new file mode 100644 index 000000000..d9087282a --- /dev/null +++ b/assets/xml/objects/object_rd.xml @@ -0,0 +1,114 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_redead_obj.xml b/assets/xml/objects/object_redead_obj.xml new file mode 100644 index 000000000..fd286d6e7 --- /dev/null +++ b/assets/xml/objects/object_redead_obj.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_rotlift.xml b/assets/xml/objects/object_rotlift.xml new file mode 100644 index 000000000..403f7d3dd --- /dev/null +++ b/assets/xml/objects/object_rotlift.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_rr.xml b/assets/xml/objects/object_rr.xml new file mode 100644 index 000000000..dbdba55c5 --- /dev/null +++ b/assets/xml/objects/object_rr.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_rs.xml b/assets/xml/objects/object_rs.xml new file mode 100644 index 000000000..5019d9631 --- /dev/null +++ b/assets/xml/objects/object_rs.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ru2.xml b/assets/xml/objects/object_ru2.xml new file mode 100644 index 000000000..016a610e8 --- /dev/null +++ b/assets/xml/objects/object_ru2.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_rz.xml b/assets/xml/objects/object_rz.xml new file mode 100644 index 000000000..323393f87 --- /dev/null +++ b/assets/xml/objects/object_rz.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_sb.xml b/assets/xml/objects/object_sb.xml new file mode 100644 index 000000000..9fcd76a8f --- /dev/null +++ b/assets/xml/objects/object_sb.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_sdn.xml b/assets/xml/objects/object_sdn.xml new file mode 100644 index 000000000..9cc607047 --- /dev/null +++ b/assets/xml/objects/object_sdn.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_secom_obj.xml b/assets/xml/objects/object_secom_obj.xml new file mode 100644 index 000000000..7b21783a3 --- /dev/null +++ b/assets/xml/objects/object_secom_obj.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_sek.xml b/assets/xml/objects/object_sek.xml new file mode 100644 index 000000000..e37af4380 --- /dev/null +++ b/assets/xml/objects/object_sek.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_sekihig.xml b/assets/xml/objects/object_sekihig.xml new file mode 100644 index 000000000..dab91d71b --- /dev/null +++ b/assets/xml/objects/object_sekihig.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_sekihil.xml b/assets/xml/objects/object_sekihil.xml new file mode 100644 index 000000000..e3c7bcc42 --- /dev/null +++ b/assets/xml/objects/object_sekihil.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_sekihin.xml b/assets/xml/objects/object_sekihin.xml new file mode 100644 index 000000000..f2982169b --- /dev/null +++ b/assets/xml/objects/object_sekihin.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_sekihiz.xml b/assets/xml/objects/object_sekihiz.xml new file mode 100644 index 000000000..0f8ef7c43 --- /dev/null +++ b/assets/xml/objects/object_sekihiz.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_shn.xml b/assets/xml/objects/object_shn.xml new file mode 100644 index 000000000..78cc77ca7 --- /dev/null +++ b/assets/xml/objects/object_shn.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_sichitai_obj.xml b/assets/xml/objects/object_sichitai_obj.xml new file mode 100644 index 000000000..f093778ab --- /dev/null +++ b/assets/xml/objects/object_sichitai_obj.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_sinkai_kabe.xml b/assets/xml/objects/object_sinkai_kabe.xml new file mode 100644 index 000000000..96f8531ad --- /dev/null +++ b/assets/xml/objects/object_sinkai_kabe.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/xml/objects/object_skb.xml b/assets/xml/objects/object_skb.xml new file mode 100644 index 000000000..cafba559e --- /dev/null +++ b/assets/xml/objects/object_skb.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_slime.xml b/assets/xml/objects/object_slime.xml new file mode 100644 index 000000000..f17633eff --- /dev/null +++ b/assets/xml/objects/object_slime.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_smtower.xml b/assets/xml/objects/object_smtower.xml new file mode 100644 index 000000000..90ee5a13d --- /dev/null +++ b/assets/xml/objects/object_smtower.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_snowman.xml b/assets/xml/objects/object_snowman.xml new file mode 100644 index 000000000..f92110b3e --- /dev/null +++ b/assets/xml/objects/object_snowman.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_snowwd.xml b/assets/xml/objects/object_snowwd.xml new file mode 100644 index 000000000..c61d07beb --- /dev/null +++ b/assets/xml/objects/object_snowwd.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_spdweb.xml b/assets/xml/objects/object_spdweb.xml new file mode 100644 index 000000000..6f54a482d --- /dev/null +++ b/assets/xml/objects/object_spdweb.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_spidertent.xml b/assets/xml/objects/object_spidertent.xml new file mode 100644 index 000000000..d90bede67 --- /dev/null +++ b/assets/xml/objects/object_spidertent.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_spinyroll.xml b/assets/xml/objects/object_spinyroll.xml new file mode 100644 index 000000000..d27386945 --- /dev/null +++ b/assets/xml/objects/object_spinyroll.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_spot11_obj.xml b/assets/xml/objects/object_spot11_obj.xml new file mode 100644 index 000000000..c049bb337 --- /dev/null +++ b/assets/xml/objects/object_spot11_obj.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_ssh.xml b/assets/xml/objects/object_ssh.xml new file mode 100644 index 000000000..a95597ae4 --- /dev/null +++ b/assets/xml/objects/object_ssh.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_st.xml b/assets/xml/objects/object_st.xml new file mode 100644 index 000000000..a7ce1418d --- /dev/null +++ b/assets/xml/objects/object_st.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_sth.xml b/assets/xml/objects/object_sth.xml new file mode 100644 index 000000000..7b6947b07 --- /dev/null +++ b/assets/xml/objects/object_sth.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_stk.xml b/assets/xml/objects/object_stk.xml new file mode 100644 index 000000000..44a311dfb --- /dev/null +++ b/assets/xml/objects/object_stk.xml @@ -0,0 +1,110 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_stk2.xml b/assets/xml/objects/object_stk2.xml new file mode 100644 index 000000000..fe62266a8 --- /dev/null +++ b/assets/xml/objects/object_stk2.xml @@ -0,0 +1,86 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_stk3.xml b/assets/xml/objects/object_stk3.xml new file mode 100644 index 000000000..dbd5da652 --- /dev/null +++ b/assets/xml/objects/object_stk3.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_stream.xml b/assets/xml/objects/object_stream.xml new file mode 100644 index 000000000..2e49af916 --- /dev/null +++ b/assets/xml/objects/object_stream.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_syokudai.xml b/assets/xml/objects/object_syokudai.xml new file mode 100644 index 000000000..83e4c34f3 --- /dev/null +++ b/assets/xml/objects/object_syokudai.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_syoten.xml b/assets/xml/objects/object_syoten.xml new file mode 100644 index 000000000..9802f7701 --- /dev/null +++ b/assets/xml/objects/object_syoten.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tab.xml b/assets/xml/objects/object_tab.xml new file mode 100644 index 000000000..52c3156a3 --- /dev/null +++ b/assets/xml/objects/object_tab.xml @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_taisou.xml b/assets/xml/objects/object_taisou.xml new file mode 100644 index 000000000..696285927 --- /dev/null +++ b/assets/xml/objects/object_taisou.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_takaraya_objects.xml b/assets/xml/objects/object_takaraya_objects.xml new file mode 100644 index 000000000..4ce448c86 --- /dev/null +++ b/assets/xml/objects/object_takaraya_objects.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_tanron1.xml b/assets/xml/objects/object_tanron1.xml new file mode 100644 index 000000000..99a39e534 --- /dev/null +++ b/assets/xml/objects/object_tanron1.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_tanron2.xml b/assets/xml/objects/object_tanron2.xml new file mode 100644 index 000000000..950621c19 --- /dev/null +++ b/assets/xml/objects/object_tanron2.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tanron3.xml b/assets/xml/objects/object_tanron3.xml new file mode 100644 index 000000000..05ef078d7 --- /dev/null +++ b/assets/xml/objects/object_tanron3.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tanron4.xml b/assets/xml/objects/object_tanron4.xml new file mode 100644 index 000000000..7e48cdf0e --- /dev/null +++ b/assets/xml/objects/object_tanron4.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tanron5.xml b/assets/xml/objects/object_tanron5.xml new file mode 100644 index 000000000..e64a11d5d --- /dev/null +++ b/assets/xml/objects/object_tanron5.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_taru.xml b/assets/xml/objects/object_taru.xml new file mode 100644 index 000000000..763fe1b2e --- /dev/null +++ b/assets/xml/objects/object_taru.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_test3.xml b/assets/xml/objects/object_test3.xml new file mode 100644 index 000000000..fc6e026a9 --- /dev/null +++ b/assets/xml/objects/object_test3.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_thiefbird.xml b/assets/xml/objects/object_thiefbird.xml new file mode 100644 index 000000000..31f0213c5 --- /dev/null +++ b/assets/xml/objects/object_thiefbird.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tite.xml b/assets/xml/objects/object_tite.xml new file mode 100644 index 000000000..2d57d1b47 --- /dev/null +++ b/assets/xml/objects/object_tite.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tk.xml b/assets/xml/objects/object_tk.xml new file mode 100644 index 000000000..506f9b00a --- /dev/null +++ b/assets/xml/objects/object_tk.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tl.xml b/assets/xml/objects/object_tl.xml new file mode 100644 index 000000000..656d70743 --- /dev/null +++ b/assets/xml/objects/object_tl.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tokei_step.xml b/assets/xml/objects/object_tokei_step.xml new file mode 100644 index 000000000..ecdf14ac3 --- /dev/null +++ b/assets/xml/objects/object_tokei_step.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_tokei_tobira.xml b/assets/xml/objects/object_tokei_tobira.xml new file mode 100644 index 000000000..cfa617551 --- /dev/null +++ b/assets/xml/objects/object_tokei_tobira.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tokei_turret.xml b/assets/xml/objects/object_tokei_turret.xml new file mode 100644 index 000000000..edca7c5c2 --- /dev/null +++ b/assets/xml/objects/object_tokei_turret.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_toryo.xml b/assets/xml/objects/object_toryo.xml new file mode 100644 index 000000000..101db5839 --- /dev/null +++ b/assets/xml/objects/object_toryo.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_trap.xml b/assets/xml/objects/object_trap.xml new file mode 100644 index 000000000..3afdf61d4 --- /dev/null +++ b/assets/xml/objects/object_trap.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_tree.xml b/assets/xml/objects/object_tree.xml new file mode 100644 index 000000000..9d5fb66dd --- /dev/null +++ b/assets/xml/objects/object_tree.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_tro.xml b/assets/xml/objects/object_tro.xml new file mode 100644 index 000000000..773182c58 --- /dev/null +++ b/assets/xml/objects/object_tro.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_trt.xml b/assets/xml/objects/object_trt.xml new file mode 100644 index 000000000..ecde36e18 --- /dev/null +++ b/assets/xml/objects/object_trt.xml @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tru.xml b/assets/xml/objects/object_tru.xml new file mode 100644 index 000000000..0ca1acff4 --- /dev/null +++ b/assets/xml/objects/object_tru.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tsn.xml b/assets/xml/objects/object_tsn.xml new file mode 100644 index 000000000..63c03c84c --- /dev/null +++ b/assets/xml/objects/object_tsn.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_tsubo.xml b/assets/xml/objects/object_tsubo.xml new file mode 100644 index 000000000..46aacd873 --- /dev/null +++ b/assets/xml/objects/object_tsubo.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_twig.xml b/assets/xml/objects/object_twig.xml new file mode 100644 index 000000000..7b9c6c191 --- /dev/null +++ b/assets/xml/objects/object_twig.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_uch.xml b/assets/xml/objects/object_uch.xml new file mode 100644 index 000000000..de16b0d7b --- /dev/null +++ b/assets/xml/objects/object_uch.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_um.xml b/assets/xml/objects/object_um.xml new file mode 100644 index 000000000..693c704d3 --- /dev/null +++ b/assets/xml/objects/object_um.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_umajump.xml b/assets/xml/objects/object_umajump.xml new file mode 100644 index 000000000..6d86b4298 --- /dev/null +++ b/assets/xml/objects/object_umajump.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/assets/xml/objects/object_utubo.xml b/assets/xml/objects/object_utubo.xml new file mode 100644 index 000000000..97a7095c9 --- /dev/null +++ b/assets/xml/objects/object_utubo.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_visiblock.xml b/assets/xml/objects/object_visiblock.xml new file mode 100644 index 000000000..d714338fc --- /dev/null +++ b/assets/xml/objects/object_visiblock.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_vm.xml b/assets/xml/objects/object_vm.xml new file mode 100644 index 000000000..b07534c65 --- /dev/null +++ b/assets/xml/objects/object_vm.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_wallmaster.xml b/assets/xml/objects/object_wallmaster.xml new file mode 100644 index 000000000..249af61ee --- /dev/null +++ b/assets/xml/objects/object_wallmaster.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_warp1.xml b/assets/xml/objects/object_warp1.xml new file mode 100644 index 000000000..50d4c527a --- /dev/null +++ b/assets/xml/objects/object_warp1.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_warp_uzu.xml b/assets/xml/objects/object_warp_uzu.xml new file mode 100644 index 000000000..4924c86ca --- /dev/null +++ b/assets/xml/objects/object_warp_uzu.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_water_effect.xml b/assets/xml/objects/object_water_effect.xml new file mode 100644 index 000000000..e3cd9ec27 --- /dev/null +++ b/assets/xml/objects/object_water_effect.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_wdhand.xml b/assets/xml/objects/object_wdhand.xml new file mode 100644 index 000000000..22e12cfa0 --- /dev/null +++ b/assets/xml/objects/object_wdhand.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_wdor01.xml b/assets/xml/objects/object_wdor01.xml new file mode 100644 index 000000000..ffc3327bb --- /dev/null +++ b/assets/xml/objects/object_wdor01.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_wdor02.xml b/assets/xml/objects/object_wdor02.xml new file mode 100644 index 000000000..9cb35ddb8 --- /dev/null +++ b/assets/xml/objects/object_wdor02.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_wdor03.xml b/assets/xml/objects/object_wdor03.xml new file mode 100644 index 000000000..c23f87037 --- /dev/null +++ b/assets/xml/objects/object_wdor03.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_wdor04.xml b/assets/xml/objects/object_wdor04.xml new file mode 100644 index 000000000..040df1598 --- /dev/null +++ b/assets/xml/objects/object_wdor04.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_wdor05.xml b/assets/xml/objects/object_wdor05.xml new file mode 100644 index 000000000..f8fda2322 --- /dev/null +++ b/assets/xml/objects/object_wdor05.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/assets/xml/objects/object_wf.xml b/assets/xml/objects/object_wf.xml new file mode 100644 index 000000000..98dd21ed5 --- /dev/null +++ b/assets/xml/objects/object_wf.xml @@ -0,0 +1,108 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_wiz.xml b/assets/xml/objects/object_wiz.xml new file mode 100644 index 000000000..7f41954cf --- /dev/null +++ b/assets/xml/objects/object_wiz.xml @@ -0,0 +1,102 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_wood02.xml b/assets/xml/objects/object_wood02.xml new file mode 100644 index 000000000..6ef693f34 --- /dev/null +++ b/assets/xml/objects/object_wood02.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_yabusame_point.xml b/assets/xml/objects/object_yabusame_point.xml new file mode 100644 index 000000000..856d94cfe --- /dev/null +++ b/assets/xml/objects/object_yabusame_point.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/objects/object_yado_obj.xml b/assets/xml/objects/object_yado_obj.xml new file mode 100644 index 000000000..d5d0467d4 --- /dev/null +++ b/assets/xml/objects/object_yado_obj.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/assets/xml/objects/object_yb.xml b/assets/xml/objects/object_yb.xml new file mode 100644 index 000000000..8cf61e347 --- /dev/null +++ b/assets/xml/objects/object_yb.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_yukimura_obj.xml b/assets/xml/objects/object_yukimura_obj.xml new file mode 100644 index 000000000..2099f807a --- /dev/null +++ b/assets/xml/objects/object_yukimura_obj.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_yukiyama.xml b/assets/xml/objects/object_yukiyama.xml new file mode 100644 index 000000000..5e7215f82 --- /dev/null +++ b/assets/xml/objects/object_yukiyama.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zg.xml b/assets/xml/objects/object_zg.xml new file mode 100644 index 000000000..e5cb1dd5d --- /dev/null +++ b/assets/xml/objects/object_zg.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/assets/xml/objects/object_zl1.xml b/assets/xml/objects/object_zl1.xml new file mode 100644 index 000000000..759b35867 --- /dev/null +++ b/assets/xml/objects/object_zl1.xml @@ -0,0 +1,90 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zl4.xml b/assets/xml/objects/object_zl4.xml new file mode 100644 index 000000000..f13487f98 --- /dev/null +++ b/assets/xml/objects/object_zl4.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zm.xml b/assets/xml/objects/object_zm.xml new file mode 100644 index 000000000..c5511f6b2 --- /dev/null +++ b/assets/xml/objects/object_zm.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zo.xml b/assets/xml/objects/object_zo.xml new file mode 100644 index 000000000..446202443 --- /dev/null +++ b/assets/xml/objects/object_zo.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zob.xml b/assets/xml/objects/object_zob.xml new file mode 100644 index 000000000..22400d46e --- /dev/null +++ b/assets/xml/objects/object_zob.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zod.xml b/assets/xml/objects/object_zod.xml new file mode 100644 index 000000000..f1152e2ac --- /dev/null +++ b/assets/xml/objects/object_zod.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zog.xml b/assets/xml/objects/object_zog.xml new file mode 100644 index 000000000..55f169ad1 --- /dev/null +++ b/assets/xml/objects/object_zog.xml @@ -0,0 +1,112 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zoraband.xml b/assets/xml/objects/object_zoraband.xml new file mode 100644 index 000000000..53a3d5a7b --- /dev/null +++ b/assets/xml/objects/object_zoraband.xml @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/assets/xml/objects/object_zoraegg.xml b/assets/xml/objects/object_zoraegg.xml new file mode 100644 index 000000000..c527fe618 --- /dev/null +++ b/assets/xml/objects/object_zoraegg.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zos.xml b/assets/xml/objects/object_zos.xml new file mode 100644 index 000000000..7a25eb338 --- /dev/null +++ b/assets/xml/objects/object_zos.xml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/objects/object_zov.xml b/assets/xml/objects/object_zov.xml new file mode 100644 index 000000000..17d6382a9 --- /dev/null +++ b/assets/xml/objects/object_zov.xml @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/overlays/ovl_En_Bigslime.xml b/assets/xml/overlays/ovl_En_Bigslime.xml new file mode 100644 index 000000000..9526daea6 --- /dev/null +++ b/assets/xml/overlays/ovl_En_Bigslime.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/xml/overlays/ovl_En_Bomjima.xml b/assets/xml/overlays/ovl_En_Bomjima.xml new file mode 100644 index 000000000..5aada4887 --- /dev/null +++ b/assets/xml/overlays/ovl_En_Bomjima.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/overlays/ovl_En_Bomjimb.xml b/assets/xml/overlays/ovl_En_Bomjimb.xml new file mode 100644 index 000000000..af42c7956 --- /dev/null +++ b/assets/xml/overlays/ovl_En_Bomjimb.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/xml/overlays/ovl_En_Mm2.xml b/assets/xml/overlays/ovl_En_Mm2.xml new file mode 100644 index 000000000..5d0be627f --- /dev/null +++ b/assets/xml/overlays/ovl_En_Mm2.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/assets/xml/overlays/ovl_En_Tru.xml b/assets/xml/overlays/ovl_En_Tru.xml new file mode 100644 index 000000000..e242db4c3 --- /dev/null +++ b/assets/xml/overlays/ovl_En_Tru.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/BUILDING_MACOS.md b/docs/BUILDING_MACOS.md new file mode 100644 index 000000000..17b683442 --- /dev/null +++ b/docs/BUILDING_MACOS.md @@ -0,0 +1,83 @@ +# Building on macOS + +**N.B. C++17 is required to build the asset processing program that we use (ZAPD), so check your OS version can support this before proceeding** + + +## Dependencies + +For macOS, use Homebrew to install the following dependencies: + +* coreutils +* make +* python3 +* libpng +* bash +* clang-format 11 + +You can install them with the following commands: + +```bash +brew update +brew install coreutils make python3 libpng bash clang-format@11 +``` + +(The repository expects Homebrew-installed programs to be either linked correctly in `$PATH` etc. or in their default locations.) + + +## Building mips-linux-binutils + +The following instructions are written for MacOS users but should apply to any Unix-like system, with maybe some modifications at the end regarding the bash_profile. + +Create destination dir for binutils +```bash +sudo mkdir -p /opt/cross +``` + +Create and enter local working dir +```bash +mkdir ~/binutils-tmp +cd ~/binutils-tmp +``` + +Get and extract binutils source +```bash +wget https://ftp.gnu.org/gnu/binutils/binutils-2.35.tar.bz2 +tar xjf binutils-2.35.tar.bz2 +``` +(You may find this command does not work: if so, just access the URL in a browser and save it to `~/binutils-tmp`.) + +Create and enter a build directory +```bash +mkdir build-binutils +cd build-binutils +``` + +Configure the build +```bash +../binutils-2.35/configure --target=mips-linux-gnu --prefix=/opt/cross --disable-gprof --disable-gdb --disable-werror +``` + +Make and install binutils +```bash +make -j +sudo make install +``` + +Edit your `~/.bash_profile`/`~/.zsh_profile` (or whichever shell you use) to add the new binutils binaries to the system PATH +```bash +echo "export PATH=$PATH:/opt/cross/bin" >> ~/.bash_profile +``` + +Reload ~/.bash_profile (or just launch a new terminal tab) +```bash +source ~/.bash_profile +``` + +If this worked, you can now delete the temporary directory `~/binutils-tmp`. + + +## Final note + +Apple's version of `make` is very out-of-date, so you should use the brew-installed `gmake` in place of `make` in this repo from now on. + +You should now be able to continue from [step 2](README.md#2-clone-the-repository) of the Linux instructions. diff --git a/docs/images/En_Firefly.png b/docs/images/En_Firefly.png new file mode 100644 index 000000000..ed3258592 Binary files /dev/null and b/docs/images/En_Firefly.png differ diff --git a/docs/images/diff.png b/docs/images/diff.png new file mode 100644 index 000000000..c93a5ac9f Binary files /dev/null and b/docs/images/diff.png differ diff --git a/docs/tools.md b/docs/tools.md new file mode 100644 index 000000000..6fec9caf8 --- /dev/null +++ b/docs/tools.md @@ -0,0 +1,291 @@ +# Table of Contnets + +- [Table of Contnets](#table-of-contnets) + - [Introduction](#introduction) + - [In the repository](#in-the-repository) + - [`diff.py`](#diffpy) + - [`tools/m2ctx.py`](#toolsm2ctxpy) + - [`tools/overlayhelpers/actor_symbols.py`](#toolsoverlayhelpersactor_symbolspy) + - [`first_diff.py`](#first_diffpy) + - [`sym_info.py`](#sym_infopy) + - [`extract_assets.py`](#extract_assetspy) + - [`tools/assist.py`](#toolsassistpy) + - [`tools/get_actor_sizes.py`](#toolsget_actor_sizespy) + - [`tools/progress.py`](#toolsprogresspy) + - [`tools/regconvert.py`](#toolsregconvertpy) + - [`tools/rename_global_asm.py`](#toolsrename_global_asmpy) + - [`tools/rename_sym.sh`](#toolsrename_symsh) + - [`tools/actorfixer.py`](#toolsactorfixerpy) + - [`tools/timeconv.py`](#toolstimeconvpy) + - [`tools/sfx_convert.py`](#toolssfx_convertpy) + - [`tools/vt_fmt.py`](#toolsvt_fmtpy) + - [`tools/graphovl.py`](#toolsgraphovlpy) + - [`tools/warnings_count/check_new_warnings.sh`](#toolswarnings_countcheck_new_warningssh) + - [`tools/warnings_count/update_current_warnings.sh`](#toolswarnings_countupdate_current_warningssh) + - [`fixle.sh`](#fixlesh) + - [`format.sh`](#formatsh) + - [External tools](#external-tools) + - [mips_to_c](#mips_to_c) + - [Permuter](#permuter) + - [vbindiff](#vbindiff) + - [Texture64](#texture64) + - [Z64Utils](#z64utils) + - [Retired tools](#retired-tools) + - [`tools/overlayhelpers/ichaindis.py`](#toolsoverlayhelpersichaindispy) + - [`tools/overlayhelpers/colliderinit.py`](#toolsoverlayhelperscolliderinitpy) + - [`tools/overlayhelpers/colchkinfoinit.py`](#toolsoverlayhelperscolchkinfoinitpy) + - [`tools/overlayhelpers/damage_table.py`](#toolsoverlayhelpersdamage_tablepy) + - [`tools/vtxdis`](#toolsvtxdis) + - [Reservation Tracking](#reservation-tracking) + +## Introduction + +There are a variety of tools that are used to assist in the decompilation process. This guide is an introduction to some of the tools that are used. Most of these tools are located in the `mm/tools` directory, others are either in the project root, or are separate programs entirely. Almost all of these programs have more information available via running them with `-h`. + +## In the repository + +### `diff.py` + +Your best friend for most of the decompilation work. Compares the original assembly extracted from the ROM instruction-for-instruction with what the code you have written compiles to. + +To use `diff.py`, you need a copy of a matching build folder to diff against. In MM, this can be made with `make diff-init`, which will rebuild both ROMs, check for OK, and copy the build folder and the roms. + +`diff.py` takes the function symbol name as the main argument: + +```bash +./diff.py ObjTree_Init +``` + +`diff.py` reads the respective `mm.map` files to find the function. If the function has been renamed, it will not be able to find it. You should not edit map files yourself, but instead rerun `make diff-init` (it is possible to copy the build folder manually, but it's better not to, since `make diff-init` guarantees an OK `expected` folder). + +The recommended flags used are `-mwo`, `-mwo3`, or `-mwob`: + +- `-m` ("make") builds the file used for diffing automatically when `diff.py` is run. +- `-w` ("watch") will watch the C file containing the function (and only the C file!) and automatically recompile when it changes. +- `-o` ("object file") uses only the `.o` file. This is faster than without, and means you can see symbol names, but obscures the data behind relative addresses: if you have differences in the .text section that are invisible with `-o`, or you suspect the data is shifted in some way, try without +- `-3` creates a three-way diff: TARGET/CURRENT/PREVIOUS, which is particularly useful for seeing changes. +- `-b` creates a three-way diff: TARGET/CURRENT/BASE, where BASE is the version from when the program was started. +- `-s` ("stop") stops diffing at the next `jr $ra`, commonly the end of the function. Beware that some functions with conditionals may have multiple `jr $ra`s, so this feature can chop the bottom off the diff. + +There are numerous other options that are not used as often (changing the diffing algorithm, viewing the source code in the diff, ...), and the various flags have dependencies among themselves, so check its documentation with `-h` to get fuller information. + +Colour explanations (sadly GitHub markdown does not allow for fancy colouring here): + +- white/grey is matching instructions +- red is missing instructions +- green is extra instructions +- blue means something in the instruction is wrong, be it numerical differences in the immediates, or the whole thing. Not all blue is meaningful: using `-o` to get symbols, the addresses of imported data will be blue since the relative address looks different from the absolute one. +- yellow means the instruction itself is correct, but the registers used are not (*regalloc*, register allocation) +- Each register gets its own colour when the regalloc is wrong, which makes it much easier to follow their usage. +- a branch is indicated by coloured `~>`s on the right of the instruction, and their targets by the same colour `~>` on the left of the instruction (remember delay slots!). The colours matching is a good indication that the branches are correct, although not infallible, since there are only so many colours it will use. +- occasionally instructions will be coloured a dark grey. You should consider this the same as blue. + +Example Diff: + +![Diff](images/diff.png) + +### `tools/m2ctx.py` + +Pass it the path to a C file to generate the context for that C file, to help [mips_to_c](#mips_to_c). Writes to a file called `ctx.c` in the root directory of the repo. + +### `tools/overlayhelpers/actor_symbols.py` + +Takes a VRAM or VROM address to get overlay file and offset for an Actor. + +### `first_diff.py` + +Gives you the addresses of first difference in the ROM, the difference, and a count of how many bytes differ, or if the whole ROM is shifted. + +### `sym_info.py` + +Can be given a symbol (function or variable name, for example), and will find its ROM, VRAM, and file using the map file. E.g. + +```bash +$ ./sym_info.py ObjTree_Init +Symbol ObjTree_Init (RAM: 0x80B9A0B0, ROM: 0xFFF210, build/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.o) +``` + +### `extract_assets.py` + +A tool that will use ZAPD to extract assets from the baserom. + +### `tools/assist.py` + +Searches for similar functions to the one you are passing, and it tells you which one are decompiled. You can pass the name of an overlay and it will search for similar functions for every function in said overlay. + +(Still a little broken) + +### `tools/get_actor_sizes.py` + +Generates a list of actors with various statistics about their function sizes. Run with `-h` for information on flags. + +(nonmatching does not work currently: we need to adapt it to MM's assembly files) + +### `tools/progress.py` + +Gives the progress output that the website uses. Run for that warm glow. + +### `tools/regconvert.py` + +Convert `mips2c`'s `gGameInfo->data[n]` output (or a raw offset) into the appropriate variable in the REG pages. Can also be run on a file to mass-convert them: run with `-h` for details. + +### `tools/rename_global_asm.py` + +Will rename the single-function assembly files in `asm/non_matchings` when the function they contain has been renamed. Should mean you have to run `make disasm` far less frequently. + +### `tools/rename_sym.sh` + +Will rename a symbol throughout the codebase. **Be very careful with this script**: it has no sanity checks, so you can do a lot of damage if you're not careful. Best to commit before using it. + +### `tools/actorfixer.py` + +Provided it is kept up-to-date with function renames, you can run this to automatically update your branch with the new names. `.` will cause it to replace in the whole repo, or you can pass it a specific file path to run it on only that file. + +### `tools/timeconv.py` + +Changes a raw `u16` value into a macro for clock time in-game: + +```bash +$ ./tools/timeconv.py 0x4800 +6,45 -> 0x4800 +CLOCK_TIME(6, 45) +``` + +Either dec or hex input will work. It will warn if the macro output will not match: + +```bash +$ ./tools/timeconv.py 44102 +16,09 -> 0xAC44 +CLOCK_TIME(16, 9) +Warning: Result does not match as-is +``` + +### `tools/sfx_convert.py` + +Replaces sfx ids by their corresponding defines from `sfx.h`. Run on a single file to replace all of them. + +### `tools/vt_fmt.py` + +Replaces VT symbols by their corresponding macros. Not many files in MM need this; ask if you need help with it. + +### `tools/graphovl.py` + +Creates a graph of action functions (black and green arrows) and function calls (blue arrows) for a given overlay file. For best results, run this from the root directory + +Example: `./tools/graphovl/graphovl.py En_Firefly` + +This will save a `.png` of the overlay in the `/graphs` directory. + +See Example below. + +![Graph](images/En_Firefly.png) + +### `tools/warnings_count/check_new_warnings.sh` + +Runs a make from clean and checks if new warnings have been produced: we use Jenkins to check this as well, but you should run this before opening a PR. + +You can specify how many threads you would like this to run with by adding the `-jN` flag. Where N is the number of threads. By default this will run using 1 thread (i.e. `-j1`). + +Run `check_new_warnings.sh -h` for more information. + +### `tools/warnings_count/update_current_warnings.sh` + +If you have to add new warnings, **and have permission from the leads**, run this to update the file used for warnings comparison. + +### `fixle.sh` + +Fixes line endings in the repo to Linux style (LF), which is required for the build process to work. (You may be better off creating a new clone directly in Linux/WSL, though) + +### `format.sh` + +Formats all C files in the repo using `clang-format-11` (instructions on how to install this version are pinned in Discord if you can't get it from your package manager in the usual way). This will touch all files in the repo, so the next `make` will take longer. + +## External tools + +### mips_to_c + +mips_to_c (or mips2c) is a tool that takes MIPS assembly and will attempt to convert it to C. + +There are different ways you can run mips2c: + +- Clone the repo and run it loclly on your own machine. Follow set up instructions at +- An online version is available at . + +mips_to_c's accuracy can be improved when some context to what the existing C source code is like. See more on how to generate this in [m2ctx](#m2ctx.py) + +### Permuter + +Use when you're low on ideas for matching a function. This goes through a series of heuristic random replacements known to help improve matching, although often at the expense of clarity. + +To set up the permuter, clone the repository in a directory of your choice. Follow the usage section of the README and ensure you have all the prerequisites installed. + +```bash +./import.py +``` + +on the files to import the code on which to run the permuter to `nonmatchings/func`, and then + +```bash +./permuter.py +``` + +will run the permuter + +Flags: + +- `-jN` for multithreading +- `-J` for using permuter@home (ask in Discord for someone to vouch for you to use this). (Can be combined with `-jN`.) +- `--better-only` only report improvements on base score (and not ties) +- `--best-only` only report improvements on current best score +- `--stack-diffs` take into account differences in placement on the stack (ignored by default) + +More information on these can be found in the permuter's own documentation. There are macros that can be added to the C to get the permuter to run particular types of transformation; these are also detailed in its manual. + +### vbindiff + +Your fallback for anything that you need to correct that is not visible in `diff.py`. Typically you use it to open the nonmatching uncompressed ROM and the uncompressed baserom and look at the differences highlighted in red. `first_diff.py` will usually tell you where to look. Controls are detailed in the program itself. + +### Texture64 + +Probably the best of the Nintendo 64 texture viewing programs. It is quite simple, but very good for the one thing that it does. + +### Z64Utils + +Basically essential for convenient analysis of object files. Can analyse and display DisplayLists, some textures, skeletons, animations, and a few other resources. Download from . + +## Retired tools + +The following tools are hopefully rendered obsolete by the data extraction that has already been done. + +### `tools/overlayhelpers/ichaindis.py` + +Used for extracting the InitChain information automatically from the ROM. + +### `tools/overlayhelpers/colliderinit.py` + +Used for decompliling the Collider struct of an actor. To use colliderinit, you will need to know the address (VRAM or VROM) of the struct, and the type of collider. There are different types of colliderinits: `ColliderJntSph, ColliderTrisInit, ColliderQuadInit, ColliderSphereInit`. + +### `tools/overlayhelpers/colchkinfoinit.py` + +Similar to `colliderinit.py` but for `CollisionCheckInfoInit`s. + +### `tools/overlayhelpers/damage_table.py` + +Extracts a damagetable from its address. Can also reconvert existing damagetables should the format change. + +### `tools/vtxdis` + +Extracts vertex data from a file. Essentially irrelevant since MM requires extracting this data with ZAPD anyway. + +### Reservation Tracking + +We use a [Google Sheet](https://docs.google.com/spreadsheets/d/1X83YCPRa532v-Zo0WgUsJ2kB1X9RxBta5_p9aWA8uro/edit#gid=0) to keep track of all the files' decompilation statuses and their function statistics. On this board one can reserve a file to work on. The columns are + +- **Actor Id**: The enum that uniquely identifies the actor for spawning etc., useful for looking in KZ/VerboseOcarina/Spectrum. For `boot`/`code`, the VRAM of the file's .text start is given instead. +- **Overlay/File name**: Name of the Overlay or File in the codebase. +- **Function size statistics**: Intended as a crude estimate of how hard a file will be. Beginners should look for small largest function size and total size; the columns give a rough estimate of the distribution of function sizes without getting unnecessarily statistically descriptive. As you become more experienced, you should work on larger files to leave the smaller ones for other beginners. +- **Description**: What the file is. It's helpful if you can fill this in if you know! They should be synchronised with the short top-of-file descriptions. +- **Status**: (Free)/Reserved/PR/Merged. To be kept up-to-date by the reserver. +- **Reserved**: To reserve a file, put your Discord name in the "Reserved" column. It is common courtesy to not work on a file that is being worked on by another contributor, so ensure the "Reserved" column is blank before working on a file. If it is not, you can ask the reserver(s) if they want to release it or collaborate on it, but don't expect them to agree. More information on what is expected when you reserve a file is available in the [CONTRIBUTING.md](../CONTRIBUTING.md). +- **Interested**: If you would like to work on a file, but don't want to reserve it, or would be interested in collaboration, etc. You should talk to any Interested people if you want to work on the file. +- **Notes**: Any other useful information: partial progress by someone unable to finish the file, other files it works with, etc. diff --git a/docs/tutorial/advanced_control_flow.md b/docs/tutorial/advanced_control_flow.md new file mode 100644 index 000000000..953e3e44d --- /dev/null +++ b/docs/tutorial/advanced_control_flow.md @@ -0,0 +1,747 @@ +# Advanced control flow + +Nice as `EnRecepgirl` was, she was somewhat lacking in complexity. In this document, we'll look at something rather more complicated than any of the functions she had. + +Again our example will be taken from a small NPC: this time, `EnMs` (Bean Seller). Most of its functions are even simpler than `EnRecepgirl`'s, and fairly quickly we can get to + +
+ + Large code block, click to show. + + +```C +#include "z_en_ms.h" + +#define FLAGS 0x00000009 + +#define THIS ((EnMs*)thisx) + +void EnMs_Init(Actor* thisx, GlobalContext* globalCtx); +void EnMs_Destroy(Actor* thisx, GlobalContext* globalCtx); +void EnMs_Update(Actor* thisx, GlobalContext* globalCtx); +void EnMs_Draw(Actor* thisx, GlobalContext* globalCtx); + +void func_80952734(EnMs* this, GlobalContext* globalCtx); +void func_809527F8(EnMs* this, GlobalContext* globalCtx); +void func_809529AC(EnMs* this, GlobalContext* globalCtx); +void func_80952A1C(EnMs *this, GlobalContext *globalCtx); + +const ActorInit En_Ms_InitVars = { + ACTOR_EN_MS, + ACTORCAT_NPC, + FLAGS, + OBJECT_MS, + sizeof(EnMs), + (ActorFunc)EnMs_Init, + (ActorFunc)EnMs_Destroy, + (ActorFunc)EnMs_Update, + (ActorFunc)EnMs_Draw, +}; + +static ColliderCylinderInitType1 D_80952BA0 = { + { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, COLSHAPE_CYLINDER, }, + { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { 22, 37, 0, { 0, 0, 0 } }, +}; + +static InitChainEntry D_80952BCC[] = { + ICHAIN_U8(targetMode, 2, ICHAIN_CONTINUE), + ICHAIN_F32(targetArrowOffset, 500, ICHAIN_STOP), +}; + + +extern ColliderCylinderInitType1 D_80952BA0; +extern InitChainEntry D_80952BCC[]; + +extern AnimationHeader D_060005EC; +extern FlexSkeletonHeader D_06003DC0; + +void EnMs_Init(Actor* thisx, GlobalContext* globalCtx) { + EnMs* this = THIS; + + Actor_ProcessInitChain(thisx, D_80952BCC); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06003DC0, &D_060005EC, this->jointTable, this->morphTable, 9); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinderType1(globalCtx, &this->collider, &this->actor, &D_80952BA0); + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 35.0f); + Actor_SetScale(&this->actor, 0.015f); + this->actor.colChkInfo.mass = 0xFF; + this->actionFunc = func_80952734; + this->actor.speedXZ = 0.0f; + this->actor.velocity.y = 0.0f; + this->actor.gravity = -1.0f; +} + +void EnMs_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnMs* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void func_80952734(EnMs* this, GlobalContext* globalCtx) { + s16 temp_v1 = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + + if (gSaveContext.inventory.items[10] == ITEM_NONE) { + this->actor.textId = 0x92E; + } else { + this->actor.textId = 0x932; + } + + if (func_800B84D0(&this->actor, globalCtx) != 0) { + this->actionFunc = func_809527F8; + return; + } + + if (this->actor.xzDistToPlayer < 90.0f) { + if (ABS_ALT(temp_v1) < 0x2000) { + func_800B8614(&this->actor, globalCtx, 90.0f); + } + } +} + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/func_809527F8.s") + +void func_809529AC(EnMs *this, GlobalContext *globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.textId = 0; + func_800B8500(&this->actor, globalCtx, this->actor.xzDistToPlayer, this->actor.playerHeightRel, 0); + this->actionFunc = func_80952A1C; + } else { + func_800B8A1C(&this->actor, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + } +} + +void func_80952A1C(EnMs *this, GlobalContext *globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + func_80151938(globalCtx, 0x936U); + this->actionFunc = func_809527F8; + } else { + func_800B8500(&this->actor, globalCtx, this->actor.xzDistToPlayer, this->actor.playerHeightRel, -1); + } +} + +void EnMs_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnMs* this = THIS; + + Actor_SetHeight(&this->actor, 20.0f); + this->actor.targetArrowOffset = 500.0f; + Actor_SetScale(&this->actor, 0.015f); + SkelAnime_Update(&this->skelAnime); + this->actionFunc(this, globalCtx); + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void EnMs_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnMs* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, NULL, + NULL, &this->actor); +} + +``` + +
+ +(Skipping any documentation we might have done.) Indeed, this actor is so simple so far that you can see why it wasn't worth using most of it for the rest of the tutorial. `func_809527F8` is a different story, however. We know it's an action function since it's set to the `actionFunc` in `func_80952A1C`. But mips2c gives us + +```bash +$ ../mips_to_c/mips_to_c.py asm/non_matchings/overlays/ovl_En_Ms/func_809527F8.s --context ctx.c --gotos-only +``` + +```C +void func_809527F8(EnMs *this, GlobalContext *globalCtx) { + u8 temp_v0; + u8 temp_v0_2; + + temp_v0 = func_80152498(&globalCtx->msgCtx); + if (temp_v0 != 4) { + if (temp_v0 != 5) { + if ((temp_v0 == 6) && (func_80147624(globalCtx) != 0)) { + this->actionFunc = func_80952734; + return; + } + // Duplicate return node #17. Try simplifying control flow for better match + return; + } + if (func_80147624(globalCtx) != 0) { + func_801477B4(globalCtx); + func_800B8A1C((Actor *) this, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809529AC; + return; + } + // Duplicate return node #17. Try simplifying control flow for better match + return; + } + if (func_80147624(globalCtx) != 0) { + temp_v0_2 = globalCtx->msgCtx.choiceIndex; + if (temp_v0_2 != 0) { + if (temp_v0_2 != 1) { + + } + func_8019F230(); + func_80151938(globalCtx, 0x934U); + // Duplicate return node #17. Try simplifying control flow for better match + return; + } + func_801477B4(globalCtx); + if ((s32) gSaveContext.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + return; + } + if ((s32) gSaveContext.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + return; + } + func_8019F208(); + func_800B8A1C((Actor *) this, globalCtx, 0x35, 90.0f, 10.0f); + func_801159EC(-0xA); + this->actionFunc = func_809529AC; + } +} +``` + +which is long, messy, and contains some rather nasty-looking control flow, including horrors like + +```C + temp_v0 = func_80152498(&globalCtx->msgCtx); + if (temp_v0 != 4) { + if (temp_v0 != 5) { + if ((temp_v0 == 6) && (func_80147624(globalCtx) != 0)) { + this->actionFunc = func_80952734; + return; + } + // Duplicate return node #17. Try simplifying control flow for better match + return; + } +``` + +If you read the OoT tutorial, you'll know these nested negated ifs all using the same variable are a good indicator that there's a switch. The problem is working out how to write it. + + +## Goto-only mode + +For didactic purposes, we'll use a feature of mips2c called goto-only mode to examine this. *This is not the only way of doing it*, but it is good practice for a beginner to this sort of control flow. Running + +```bash +../mips_to_c/mips_to_c.py asm/non_matchings/overlays/ovl_En_Ms/func_809527F8.s --context ctx.c --gotos-only +``` + +instead will produce + +```C +void func_809527F8(EnMs *this, GlobalContext *globalCtx) { + u8 temp_v0; + u8 temp_v0_2; + + temp_v0 = func_80152498(&globalCtx->msgCtx); + if (temp_v0 == 4) { + goto block_7; + } + if (temp_v0 == 5) { + goto block_5; + } + if (temp_v0 != 6) { + goto block_17; + } + if (func_80147624(globalCtx) == 0) { + goto block_17; + } + this->actionFunc = func_80952734; + return; +block_5: + if (func_80147624(globalCtx) == 0) { + goto block_17; + } + func_801477B4(globalCtx); + func_800B8A1C((Actor *) this, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809529AC; + return; +block_7: + if (func_80147624(globalCtx) == 0) { + goto block_17; + } + temp_v0_2 = globalCtx->msgCtx.choiceIndex; + if (temp_v0_2 == 0) { + goto block_11; + } + if (temp_v0_2 == 1) { + goto block_16; + } + goto block_16; +block_11: + func_801477B4(globalCtx); + if ((s32) gSaveContext.rupees >= 0xA) { + goto block_13; + } + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + return; +block_13: + if ((s32) gSaveContext.inventory.ammo[gItemSlots[0xA]] < 0x14) { + goto block_15; + } + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + return; +block_15: + func_8019F208(); + func_800B8A1C((Actor *) this, globalCtx, 0x35, 90.0f, 10.0f); + func_801159EC(-0xA); + this->actionFunc = func_809529AC; + return; +block_16: + func_8019F230(); + func_80151938(globalCtx, 0x934U); +block_17: + return; +} +``` + +which in many ways looks worse: you can see why the use of gotos in code is strongly discouraged. However, if you throw this in `diff.py`, you'll find it's rather closer than you'd have thought. Goto-only mode has the advantages that +- code is always in the right order: mips2c has not had to reorder anything to get the ifs to work out +- it is often possible to get quite close with gotos, then start removing them, checking the matching status at each point. This is usually easier than trying to puzzle out the way it's trying to jump out of an `if ( || )` or similar. +- if you're trying to keep track of where you are in the code, the gotos mean that it is closer to the assembly in the first place. + +## Eliminating the gotos + +The simplest sort of block label to eliminate is one that is only used once, and where the corresponding goto jumps over a simple block of code with no extra internal control flow structure. There are two obvious examples of this here, the first being + +```C + if ((s32) gSaveContext.rupees >= 0xA) { + goto block_13; + } + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + return; +block_13: +``` + +Currently, this says to jump over the code block `play_sound...` if the condition in the if is satisfied. In non-goto terms, this means that the block should be run if the condition is *not* satisfied. This also illustrates a general property of goto-only mode: you have to reverse the senses of all of the ifs. Therefore the appropriate approach is to swap the if round, put the code block inside, and remove the goto and the label: + +```C + if (gSaveContext.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + return; + } +``` + +Likewise, one can do this with `block_15`. + +If you examine appropriate part of the diff, you will usually find that such eliminations make no, or very little, difference to the compiled code. + +```C +void func_809527F8(EnMs *this, GlobalContext *globalCtx) { + u8 temp_v0; + u8 temp_v0_2; + + temp_v0 = func_80152498(&globalCtx->msgCtx); + if (temp_v0 == 4) { + goto block_7; + } + if (temp_v0 == 5) { + goto block_5; + } + if (temp_v0 != 6) { + goto block_17; + } + if (func_80147624(globalCtx) == 0) { + goto block_17; + } + this->actionFunc = func_80952734; + return; +block_5: + if (func_80147624(globalCtx) == 0) { + goto block_17; + } + func_801477B4(globalCtx); + func_800B8A1C((Actor *) this, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809529AC; + return; +block_7: + if (func_80147624(globalCtx) == 0) { + goto block_17; + } + temp_v0_2 = globalCtx->msgCtx.choiceIndex; + if (temp_v0_2 == 0) { + goto block_11; + } + if (temp_v0_2 == 1) { + goto block_16; + } + goto block_16; +block_11: + func_801477B4(globalCtx); + + if (gSaveContext.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + return; + } + if (gSaveContext.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + return; + } + + func_8019F208(); + func_800B8A1C((Actor *) this, globalCtx, 0x35, 90.0f, 10.0f); + func_801159EC(-0xA); + this->actionFunc = func_809529AC; + return; +block_16: + func_8019F230(); + func_80151938(globalCtx, 0x934U); +block_17: + return; +} +``` + +We can't apply this rule any more, so we need to move on to the next: `block_17` just contains a `return`. So we can replace it by `return` everywhere it appears. + + +```C +void func_809527F8(EnMs *this, GlobalContext *globalCtx) { + u8 temp_v0; + u8 temp_v0_2; + + temp_v0 = func_80152498(&globalCtx->msgCtx); + if (temp_v0 == 4) { + goto block_7; + } + if (temp_v0 == 5) { + goto block_5; + } + if (temp_v0 != 6) { + return; + } + if (func_80147624(globalCtx) == 0) { + return; + } + this->actionFunc = func_80952734; + return; +block_5: + if (func_80147624(globalCtx) == 0) { + return; + } + func_801477B4(globalCtx); + func_800B8A1C((Actor *) this, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809529AC; + return; +block_7: + if (func_80147624(globalCtx) == 0) { + return; + } + temp_v0_2 = globalCtx->msgCtx.choiceIndex; + if (temp_v0_2 == 0) { + goto block_11; + } + if (temp_v0_2 == 1) { + goto block_16; + } + goto block_16; +block_11: + func_801477B4(globalCtx); + + if (gSaveContext.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + return; + } + if (gSaveContext.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + return; + } + + func_8019F208(); + func_800B8A1C((Actor *) this, globalCtx, 0x35, 90.0f, 10.0f); + func_801159EC(-0xA); + this->actionFunc = func_809529AC; + return; +block_16: + func_8019F230(); + func_80151938(globalCtx, 0x934U); +} +``` + +Our next rule is about non-crossing blocks. If two code blocks do not contain any jumps between them, we can treat them separately. This is *almost* true for the code after `block_7`, were it not for the returns; of course returns are a special case because they can be used to be escape from a function at any point. This doesn't get us very far in this case, unfortunately, but it *does* tell us we can look at the second half of the function separately. + +Now let's start thinking about switches. A good indicator of a switch in goto-only mode is something like + +```C + temp_v0_2 = globalCtx->msgCtx.choiceIndex; + if (temp_v0_2 == 0) { + goto block_11; + } + if (temp_v0_2 == 1) { + goto block_16; + } + goto block_16; +``` + +because +- there are multiple ifs that are simple numeric comparisons of the same argument +- the goto blocks are in the same order as the ifs +- there is one last goto at the end that triggers if none of the ifs does: this sounds an awful lot like a `default`! + +So let us rewrite the entire second half as a switch: + +```C + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_801477B4(globalCtx); + + if (gSaveContext.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + return; + } + if (gSaveContext.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + return; + } + + func_8019F208(); + func_800B8A1C((Actor *) this, globalCtx, 0x35, 90.0f, 10.0f); + func_801159EC(-0xA); + this->actionFunc = func_809529AC; + return; + break; + + case 1: + default: + func_8019F230(); + func_80151938(globalCtx, 0x934U); + break; + } +``` + +There's a couple of other obvious things here: +- the last `return` in `case 0` is unnecessary since there is no other code after the switch, so breaking is equivalent to the return` +- a common pattern everywhere, a sequence of ifs with returns as the last thing inside is the same as an if-else chain, so we can rewrite these as + +```C + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_801477B4(globalCtx); + + if (gSaveContext.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + } else if (gSaveContext.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + } else { + func_8019F208(); + func_800B8A1C((Actor *) this, globalCtx, 0x35, 90.0f, 10.0f); + func_801159EC(-0xA); + this->actionFunc = func_809529AC; + } + break; + + case 1: + default: + func_8019F230(); + func_80151938(globalCtx, 0x934U); + break; + } +``` + +Well, at least the bottom half looks respectable now. Again, there is no code after the switch, so the next thing up, namely + +```C + if (func_80147624(globalCtx) == 0) { + return; + } +``` + +can be swapped round and made to wrap the switch. This leaves us with + +```C +void func_809527F8(EnMs *this, GlobalContext *globalCtx) { + u8 temp_v0; + + temp_v0 = func_80152498(&globalCtx->msgCtx); + if (temp_v0 == 4) { + goto block_7; + } + if (temp_v0 == 5) { + goto block_5; + } + if (temp_v0 != 6) { + return; + } + if (func_80147624(globalCtx) == 0) { + return; + } + this->actionFunc = func_80952734; + return; +block_5: + if (func_80147624(globalCtx) == 0) { + return; + } + func_801477B4(globalCtx); + func_800B8A1C((Actor *) this, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809529AC; + return; +block_7: + if (func_80147624(globalCtx) != 0) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_801477B4(globalCtx); + + if (gSaveContext.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + } else if (gSaveContext.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + } else { + func_8019F208(); + func_800B8A1C((Actor *) this, globalCtx, 0x35, 90.0f, 10.0f); + func_801159EC(-0xA); + this->actionFunc = func_809529AC; + } + break; + + case 1: + default: + func_8019F230(); + func_80151938(globalCtx, 0x934U); + break; + } + } +} +``` + +Now, the top of the function also looks like a switch: +```C + temp_v0 = func_80152498(&globalCtx->msgCtx); + if (temp_v0 == 4) { + goto block_7; + } + if (temp_v0 == 5) { + goto block_5; + } + if (temp_v0 != 6) { + return; + } +``` + +Interestingly, this time the blocks are the other way round. Also, the last statement is a `!=` rather than an `==`: this should be the default this time. The code order takes priority over the check order, because the compiler likes to put those in numerical order. There will be cases 4,5,6, but in the order 6,5,4, because that's how the code ordering goes. Also, notice that every case returns at the end: this means there's nothing else in the function after this switch, so everything after `block_7` is actually part of `case 4`. + +Putting all this together, we write down a function with no gotos in it: + +```C +void func_809527F8(EnMs *this, GlobalContext *globalCtx) { + switch (func_80152498(&globalCtx->msgCtx)) { + case 6: + this->actionFunc = func_80952734; + break; + + case 5: + if (func_80147624(globalCtx) == 0) { + return; + } + func_801477B4(globalCtx); + func_800B8A1C((Actor *) this, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809529AC; + break; + + case 4: + if (func_80147624(globalCtx) != 0) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_801477B4(globalCtx); + + if (gSaveContext.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + } else if (gSaveContext.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + } else { + func_8019F208(); + func_800B8A1C((Actor *) this, globalCtx, 0x35, 90.0f, 10.0f); + func_801159EC(-0xA); + this->actionFunc = func_809529AC; + } + break; + + case 1: + default: + func_8019F230(); + func_80151938(globalCtx, 0x934U); + break; + } + } + break; + + default: + break; + } +} +``` + +Lastly, we can simplify `case 5` to replace the return in the if by the rest of the code, and we end up with + +```C +void func_809527F8(EnMs *this, GlobalContext *globalCtx) { + switch (func_80152498(&globalCtx->msgCtx)) { + case 6: + this->actionFunc = func_80952734; + break; + + case 5: + if (func_80147624(globalCtx) != 0) { + func_801477B4(globalCtx); + func_800B8A1C((Actor *) this, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809529AC; + } + break; + + case 4: + if (func_80147624(globalCtx) != 0) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_801477B4(globalCtx); + + if (gSaveContext.rupees < 0xA) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x935U); + } else if (gSaveContext.inventory.ammo[gItemSlots[0xA]] >= 0x14) { + play_sound(0x4806U); + func_80151938(globalCtx, 0x937U); + } else { + func_8019F208(); + func_800B8A1C((Actor *) this, globalCtx, 0x35, 90.0f, 10.0f); + func_801159EC(-0xA); + this->actionFunc = func_809529AC; + } + break; + + case 1: + default: + func_8019F230(); + func_80151938(globalCtx, 0x934U); + break; + } + } + break; + + default: + break; + } +} +``` + +And this matches! + +We will not document this now, although even with so few function named it seems pretty clear that it's to do with buying beans (and indeed, Magic Beans cost 10 Rupees and have Get Item ID `0x35`) You might like to try to match this function without using goto-only mode, to compare. It is also an interesting exercise to see what each elimination does to the diff: sometimes it will stray surprisingly far for a small change. diff --git a/docs/tutorial/beginning_decomp.md b/docs/tutorial/beginning_decomp.md new file mode 100644 index 000000000..01cc21cf3 --- /dev/null +++ b/docs/tutorial/beginning_decomp.md @@ -0,0 +1,675 @@ +# Beginning decompilation: the Init function and the Actor struct + +Up: [Contents](contents.md) + +Open the C file and the H file with your actor's name from the appropriate directory in `src/overlays/actors/`. These will be the main files we work with. We will be using EnRecepgirl (the rather forward Mayor's receptionist in the Mayor's residence in East Clock Town) as our example: it is a nice simple NPC with most of the common features of an NPC. + +Each actor has associated to it a data file and one assembly file per function. During the process, we will transfer the contents of all or most of these into the main C file. VSCode's search feature usually makes it quite easy to find the appropriate files without troubling the directory tree. + + +## Anatomy of the C file + +The actor file starts off looking like: + +```C +// --------------- 1 --------------- +// --------------- 2 --------------- +#include "z_en_recepgirl.h" + +#define FLAGS 0x00000009 + +#define THIS ((EnRecepgirl*)thisx) + +// --------------- 3 --------------- +void EnRecepgirl_Init(Actor* thisx, GlobalContext* globalCtx); +void EnRecepgirl_Destroy(Actor* thisx, GlobalContext* globalCtx); +void EnRecepgirl_Update(Actor* thisx, GlobalContext* globalCtx); +void EnRecepgirl_Draw(Actor* thisx, GlobalContext* globalCtx); + +// --------------- 4 --------------- +#if 0 +const ActorInit En_Recepgirl_InitVars = { + ACTOR_EN_RECEPGIRL, + ACTORCAT_NPC, + FLAGS, + OBJECT_BG, + sizeof(EnRecepgirl), + (ActorFunc)EnRecepgirl_Init, + (ActorFunc)EnRecepgirl_Destroy, + (ActorFunc)EnRecepgirl_Update, + (ActorFunc)EnRecepgirl_Draw, +}; + +// static InitChainEntry sInitChain[] = { +static InitChainEntry D_80C106C0[] = { + ICHAIN_U8(targetMode, 6, ICHAIN_CONTINUE), + ICHAIN_F32(targetArrowOffset, 1000, ICHAIN_STOP), +}; + +#endif + +// --------------- 5 --------------- +extern InitChainEntry D_80C106C0[]; + +extern UNK_TYPE D_06001384; +extern UNK_TYPE D_06009890; +extern UNK_TYPE D_0600A280; + +// --------------- 6 --------------- +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Init.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Destroy.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C100DC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10148.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C1019C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10290.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C102D4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Update.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10558.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10590.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Draw.s") + +``` + +It is currently divided into six sections as follows: + +1. Description of the actor. This is not present for all actors, (and indeed, is not present here) but gives a short description based on what we know about the actor already. It may be inaccurate, so feel free to correct it after you understand the actor better, or add it. It currently has the form + +```C +/* + * File: z_en_recepgirl.c + * Overlay: ovl_En_Recepgirl + * Description: Mayor's receptionist + */ +``` + +2. Specific `include`s and `define`s for the actor. You may need to add more header files, but otherwise this section is unlikely to change. + +3. These are prototypes for the "main four" functions that almost every actor has. You add more functions here if they need to be declared above their first use. + +5. `if`'d-out section containing the `InitVars` and a few other common pieces of data. This can be ignored until we import the data. + +4. A set of `extern`s. These refer to the data in the previous section, and, data that comes from other files, usually in the actor's corresponding object file. The latter point to addresses in the ROM where assets are stored (usually collision data, animations or display lists). Once the corresponding object files have been decompiled, these will simply be replaced by including the object file (see [Object Decompilation](object_decomp.md) for how this process works). These symbols have been automatically extracted from the MIPS code. There may turn out to be some that were not caught by the script, in which case they need to be placed in the file called `undefined_syms.txt` in the root directory of the project. Ask in Discord for how to do this: it is simple, but rare enough to not be worth covering here. + +6. List of functions. Each `#pragma GLOBAL_ASM` is letting the compiler use the corresponding assembly file while we do not have decompiled C code for that function. The majority of the decompilation work is converting these functions into C that it looks like a human wrote. + + +## Header file + +The header file looks like this at the moment: + +```C +#ifndef Z_EN_RECEPGIRL_H +#define Z_EN_RECEPGIRL_H + +#include "global.h" + +struct EnRecepgirl; + +typedef void (*EnRecepgirlActionFunc)(struct EnRecepgirl*, GlobalContext*); + +typedef struct EnRecepgirl { + /* 0x0000 */ Actor actor; + /* 0x0144 */ char unk_144[0x164]; + /* 0x02A8 */ EnRecepgirlActionFunc actionFunc; + /* 0x02AC */ char unk_2AC[0x8]; +} EnRecepgirl; // size = 0x2B4 + +extern const ActorInit En_Recepgirl_InitVars; + +#endif // Z_EN_RECEPGIRL_H +``` + +The struct currently contains a variable that is the `Actor` struct, which all actors use one way or another, plus other items. Currently we don't know what most of those items are, so we have arrays of chars as padding instead, just so the struct is the right size. As we understand the actor better, we will be able to gradually replace this padding with the actual variables that the actor uses. + +The header file is also used to declare structs and other information about the actor that is needed by other files (e.g. by other actors): one can simply `#include` the header rather than `extern`ing it. + + +## Order of decompilation + +The general rule for order of decompilation is +- Start with `Init`, because it usually contains the most information about the structure of the actor. You can also do `Destroy`, which is generally simpler than `Init`. +- Next, decompile any other functions from the actor you have found in `Init`. You generally start with the action functions, because they return nothing and all take the same arguments, + +```C +void func_80whatever(EnRecepgirl* this, GlobalContext* globalCtx); +``` + +- Decompile each action function in turn until you run out. Along the way, do any other functions in the actor for which you have discovered the argument types. (You are probably better doing depth-first on action functions than breadth-first: it's normally easier to follow along one branch of the actions than be thinking about several at once.) + +- After you've run out, do `Update`. This usually provides the rest of the function tree, apart from possibly some draw functions. + +- Finally, do the draw functions. + +The above is a rough ordering for the beginner. As you become more experienced, you can deviate from this scheme, but the general principle remains that you should work on functions that you already know something about. (This is why it's good to start on actors: they are self-contained, we already know a lot about some of the functions, and the function flow tends to be both logical and provide information about every function.) + +## Data + +![Fresh actor data](images/fresh_actor_data.png) + +Associated to each actor is a `.data` file, containing data that the actor uses. This ranges from spawn positions, to animation information, to even assets that we have to extract from the ROM. Since the structure of the data is very inconsistent between actors, automatic importing has been very limited, so the vast majority must be done manually. + +There are two ways of transfering the data into an actor: we can either +- import it all naively as words (`s32`s), which will still allow it to compile, and sort out the actual types later, or +- we can extern each piece of data as we come across it, and come back to it later when we have a better idea of what it is. + +We will concentrate on the second here; the other is covered in [the document about data](data.md). Thankfully this means we essentially don't have to do anything to the data yet. Nevertheless, it is often quite helpful to copy over at least some of the data and leave it commented out for later replacement. *Data must go in the same order as in the data file, and data is "all or nothing": you cannot only import some of it*. + + +**WARNING** The way in which the data was extracted from the ROM means that there are sometimes "fake symbols" in the data, which have to be removed to avoid confusing the compiler. Thankfully it will turn out that this is not the case here. + +(Sometimes it is useful to import the data in the middle of doing functions: you just have to choose an appropriate moment.) + +Some actors also have a `.bss` file. This is just data that is initialised to 0, and can be imported immediately once you know what type it is, by declaring it without giving it a value. (bss is a significant problem for code files, but not *usually* for actors.) + + +## Init + +The Init function sets up the various components of the actor when it is first loaded. It is hence usually very useful for finding out what is in the actor struct, and so we usually start with it. (Some people like starting with Destroy, which is usually shorter and simpler, but gives some basic information about the actor, but Init is probably best for beginners.) + +### mips2c + +The first stage of decompilation is done by a program called mips_to_c, often referred to as mips2c, which constructs a C interpretation of the assembly code based on reading it very literally. This means that considerable cleanup will be required to turn it into something that firstly compiles at all, and secondly looks like a human wrote it, let alone a Zelda developer from the late '90s. + +The web version of mips2c can be found [here](https://simonsoftware.se/other/mips_to_c.py). This was [covered in the OoT tutorial](https://github.com/zeldaret/oot/blob/master/docs/tutorial/beginning_decomp.md). We shall instead use the repository. Clone [the mips_to_c repository](https://github.com/matt-kempster/mips_to_c) into a separate directory (we will assume on the same level as the `mm/` directory). Since it's Python, we don't have to do any compilation or anything in the mips_to_c directory. + +Since the actor depends on the rest of the codebase, we can't expect to get much intelligible out of mips2c without giving it some context. We make this using a Python script in the `tools` directory called `m2ctx.py`, so run +``` +$ ./tools/m2ctx.py +``` +from the main directory of the repository. In this case, the C file is `src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.c`. This generates a file called `ctx.c` in the main directory of the repository. + +To get mips_to_c to decompile a function, the bare minimum is to run +``` +$ ../mips_to_c/mips_to_c.py +``` +(from the root directory of `mm`). We can tell mips2c to use the context file we just generated by adding `--context ctx.c`. If we have data, mips2c may be able to assist with that as well. + +In this case, we want the assembly file for `EnRecepgirl_Init`. You can copy the path to the file in VSCode or similar, or just tab-complete it once you know the directory structure well enough: it turns out to be `asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Init.s`. + +**N.B.** You want the file in `nonmatchings`! the files in the other directories in `asm/` are the *unsplit* asm, which can be used, but is less convenient (you would need to include the rodata, for example, and it will do the whole file at once. This is sometimes useful, but we'll go one function at a time today to keep things simple). + +We shall also include the data file, which is located at `data/overlays/ovl_En_Recepgirl/ovl_En_Recepgirl.data.s`. Hence the whole command will be +``` +$ ../mips_to_c/mips_to_c.py asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Init.s data/ovl_En_Recepgirl/ovl_En_Recepgirl.data.s --context ctx.c +? func_80C10148(EnRecepgirl *); // extern +extern FlexSkeletonHeader D_06011B60; +static void *D_80C106B0[4] = {(void *)0x600F8F0, (void *)0x600FCF0, (void *)0x60100F0, (void *)0x600FCF0}; +static s32 D_80C106C8 = 0; +InitChainEntry D_80C106C0[2]; // unable to generate initializer + +void EnRecepgirl_Init(EnRecepgirl *this, GlobalContext *globalCtx) { + EnRecepgirl* this = (EnRecepgirl *) thisx; + void **temp_s0; + void **phi_s0; + + Actor_ProcessInitChain((Actor *) this, D_80C106C0); + ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, (SkelAnime *) this->unk_144, &D_06011B60, (AnimationHeader *) &D_06009890, this + 0x188, this + 0x218, 0x18); + phi_s0 = D_80C106B0; + if (D_80C106C8 == 0) { + do { + temp_s0 = phi_s0 + 4; + temp_s0->unk-4 = Lib_SegmentedToVirtual(*phi_s0); + phi_s0 = temp_s0; + } while (temp_s0 != D_80C106C0); + D_80C106C8 = 1; + } + this->unk_2AC = 2; + if (Flags_GetSwitch(globalCtx, (s32) this->actor.params) != 0) { + this->actor.textId = 0x2ADC; + } else { + this->actor.textId = 0x2AD9; + } + func_80C10148(this); +} +``` +Comment out the `GLOBAL_ASM` line for `Init`, and paste all of this into the file just underneath it: + +```C +[...] +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Init.s") +? func_80C10148(EnRecepgirl *); // extern +extern FlexSkeletonHeader D_06011B60; +static void *D_80C106B0[4] = {(void *)0x600F8F0, (void *)0x600FCF0, (void *)0x60100F0, (void *)0x600FCF0}; +static s32 D_80C106C8 = 0; +InitChainEntry D_80C106C0[2]; // unable to generate initializer + +void EnRecepgirl_Init(Actor *thisx, GlobalContext *globalCtx) { + EnRecepgirl* this = (EnRecepgirl *) thisx; + void **temp_s0; + void **phi_s0; + + Actor_ProcessInitChain((Actor *) this, D_80C106C0); + ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, (SkelAnime *) this->unk_144, &D_06011B60, (AnimationHeader *) &D_06009890, this + 0x188, this + 0x218, 0x18); + phi_s0 = D_80C106B0; + if (D_80C106C8 == 0) { + do { + temp_s0 = phi_s0 + 4; + temp_s0->unk-4 = Lib_SegmentedToVirtual(*phi_s0); + phi_s0 = temp_s0; + } while (temp_s0 != D_80C106C0); + D_80C106C8 = 1; + } + this->unk_2AC = 2; + if (Flags_GetSwitch(globalCtx, (s32) this->actor.params) != 0) { + this->actor.textId = 0x2ADC; + } else { + this->actor.textId = 0x2AD9; + } + func_80C10148(this); +} +[...] +``` + + +Typically for all but the simplest functions, there is a lot that needs fixing before we are anywhere near seeing how close we are to the original code. You will notice that mips2c creates a lot of temporary variables. Usually most of these will turn out to not be real, and we need to remove the right ones to get the code to match. + +To allow the function to find the variables, we need another correction. Half of this has already been done at the top of the file, where we have + +```C +#define THIS ((EnRecepgirl*)thisx) +``` + +To do the other half, replace the recast at the beginning of the function, before any declarations: + +```C +EnRecepgirl* this = THIS; +``` + +Now everything points to the right place, even though the argument of the function seems inconsistent with the contents. + +(Again: this step is only necessary for the "main four" functions, and sometimes functions that are used by these: it relates to how such functions are used outside the actor.) + +While we are carrying out initial changes, you can also find-and-replace any instances of `(Actor *) this` by `&this->actor`. The function now looks like this: + +```C +? func_80C10148(EnRecepgirl *); // extern +extern FlexSkeletonHeader D_06011B60; +static void *D_80C106B0[4] = {(void *)0x600F8F0, (void *)0x600FCF0, (void *)0x60100F0, (void *)0x600FCF0}; +static s32 D_80C106C8 = 0; +InitChainEntry D_80C106C0[2]; // unable to generate initializer + +void EnRecepgirl_Init(Actor *thisx, GlobalContext *globalCtx) { + EnRecepgirl* this = THIS; + void **temp_s0; + void **phi_s0; + + Actor_ProcessInitChain(&this->actor, D_80C106C0); + ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, (SkelAnime *) this->unk_144, &D_06011B60, (AnimationHeader *) &D_06009890, this + 0x188, this + 0x218, 0x18); + phi_s0 = D_80C106B0; + if (D_80C106C8 == 0) { + do { + temp_s0 = phi_s0 + 4; + temp_s0->unk-4 = Lib_SegmentedToVirtual(*phi_s0); + phi_s0 = temp_s0; + } while (temp_s0 != D_80C106C0); + D_80C106C8 = 1; + } + this->unk_2AC = 2; + if (Flags_GetSwitch(globalCtx, (s32) this->actor.params) != 0) { + this->actor.textId = 0x2ADC; + } else { + this->actor.textId = 0x2AD9; + } + func_80C10148(this); +} +``` + +### (Not) dealing with Data + +For now, we do not want to consider the data that mips2c has kindly imported for us: it will only get in the way when we want to rebuild the file to check for OK (`diff.py` will not care, but `make` will complain if it notices a symbol defined twice, and if some data is included twice the ROM will not match anyway). Therefore, put it in the `#if`'d out section and add some externs with the types: + +```C +#if 0 +const ActorInit En_Recepgirl_InitVars = { + ACTOR_EN_RECEPGIRL, + ACTORCAT_NPC, + FLAGS, + OBJECT_BG, + sizeof(EnRecepgirl), + (ActorFunc)EnRecepgirl_Init, + (ActorFunc)EnRecepgirl_Destroy, + (ActorFunc)EnRecepgirl_Update, + (ActorFunc)EnRecepgirl_Draw, +}; + +static void* D_80C106B0[4] = { (void*)0x600F8F0, (void*)0x600FCF0, (void*)0x60100F0, (void*)0x600FCF0 }; + +// static InitChainEntry sInitChain[] = { +static InitChainEntry D_80C106C0[] = { + ICHAIN_U8(targetMode, 6, ICHAIN_CONTINUE), + ICHAIN_F32(targetArrowOffset, 1000, ICHAIN_STOP), +}; + +static s32 D_80C106C8 = 0; + +#endif + +extern void* D_80C106B0[]; +extern InitChainEntry D_80C106C0[]; +extern s32 D_80C106C8; +``` + +**N.B.** As is covered in more detail in [the document about data](data.md), the data *must* be declared in the same order in C as it was in the data assembly file: notice that the order in this example is `En_Recepgirl_InitVars`, `D_80C106B0`, `D_80C106C0`, `D_80C106C8`, the same as in `data/ovl_En_Recepgirl/ovl_En_Recepgirl.data.s`. + + +In the next sections, we shall sort out the various initialisation functions that occur in Init. This actor contains several of the most common ones, but it does not have, for example, a collider. The process is similar to what we discuss below, or you can check the OoT tutorial. + + + +### Init chains + +Almost always, one of the first items in `Init` is a function that looks like + +```C +Actor_ProcessInitChain(&this->actor, D_80C106C0); +``` + +which initialises common properties of actor using an InitChain, which is usually somewhere near the top of the data, in this case in the variable `D_80C106C0`. This is already included in the `#if`'d out data at the top if the file, so we don't have to do anything for now. We can correct the mips2c output for the extern, though: I actually did this when moving the rest of the data in the previous section. + + +### SkelAnime + +This is the combined system that handles actors' skeletons and their animations. It is the other significant part of most actor structs. We see its initialisation in this part of the code: +```C + Actor_ProcessInitChain(&this->actor, D_80C106C0); + ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, (SkelAnime *) this->unk_144, &D_06011B60, (AnimationHeader *) &D_06009890, this + 0x188, this + 0x218, 0x18); + phi_s0 = D_80C106B0; +``` + +An actor with SkelAnime has three structs in the Actor struct that handle it: one called SkelAnime, and two arrays of `Vec3s`, called `jointTable` and `morphTable`. Usually, although not always, they are next to one another. + +There are two different sorts of SkelAnime, although for decompilation purposes there is not much difference between them. Looking at the prototype of `SkelAnime_InitFlex` from `functions.h` (or even the definition in `z_skelanime.c`), +```C +void SkelAnime_InitFlex(GlobalContext* globalCtx, SkelAnime* skelAnime, FlexSkeletonHeader* skeletonHeaderSeg, + AnimationHeader* animationSeg, Vec3s* jointTable, Vec3s* morphTable, s32 limbCount); +``` +we can read off the types of the various arguments: +- The `SkelAnime` struct is at `this + 0x144` +- The `jointTable` is at `this + 0x188` +- The `morphTable` is at `this + 0x218` +- The number of limbs is `0x18 = 24` (we use dec for the number of limbs) +- Because of how SkelAnime works, this means that the `jointTable` and `morphTable` both have `24` elements + +Looking in `z64animation.h`, we find that `SkelAnime` has size `0x44`, and looking in `z64math.h`, that `Vec3s` has size `0x6`. Since ` 0x144 + 0x44 = 0x188 `, `jointTable` is immediately after the `SkelAnime`, and since `0x188 + 0x6 * 0x18 = 0x218`, `morphTable` is immediately after the `jointTable`. Finally, `0x218 + 0x6 * 0x18 = 0x2A8`, and we have filled all the space between the `actor` and `actionFunc`. Therefore the struct now looks like +```C +typedef struct EnRecepgirl { + /* 0x0000 */ Actor actor; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[24]; + /* 0x0218 */ Vec3s morphTable[24]; + /* 0x02A8 */ EnRecepgirlActionFunc actionFunc; + /* 0x02AC */ char unk_2AC[0x8]; +} EnRecepgirl; // size = 0x2B4 +``` + +The last information we get from the SkelAnime function is the types of two of the externed symbols: `D_06011B60` is a `FlexSkeletonHeader`, and `D_06009890` is an `AnimationHeader`. So we can change/add these at the top of the C file: + +```C +extern InitChainEntry D_80C106C0[]; + +extern UNK_TYPE D_06001384; +extern AnimationHeader D_06009890; +extern UNK_TYPE D_0600A280; +extern FlexSkeletonHeader D_06011B60; +``` +As with the data, these externed symbols should be kept in increasing address order. + +They are both passed to the function as pointers, so need `&` to pass the address instead of the actual data. Hence we end up with +```C + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06011B60, &D_06009890, this->jointTable, this->morphTable, 24); +``` +note that `this->jointTable` and `this->morphTable` are arrays, so are already effectively pointers and don't need a `&`. + +### More struct variables: a brief detour into reading some assembly + +This function also gives us information about other things in the struct. The only other reference to `this` (rather than `this->actor` or similar) is in +```C +this->unk_2AC = 2; +``` +This doesn't tell us much except that at `this + 0x2AC` is a number of some kind. What sort of number? For that we will have to look in the assembly code. This will probably look quite intimidating the first time, but it's usually not too bad if you use functions as signposts: IDO will never change the order of function calls, and tends to keep code between functions in roughly the same place, so you can usually guess where you are. + +In this case, we are looking for `this + 0x2AC`. `0x2AC` is not a very common number, so hopefully the only mention of it is in referring to this struct variable. Indeed, if we search the file, we find that the only instruction mentioning `0x2AC` is here: +```mips +/* 0000B0 80C10080 24090002 */ addiu $t1, $zero, 2 +/* 0000B4 80C10084 A24902AC */ sb $t1, 0x2ac($s2) +``` +`addiu` ("add unsigned immediate") adds the last two things and puts the result in the register in the first position. So this says `$t1 = 0 + 2`. The next instruction, `sb` ("store byte") puts the value in the register in the first position in the memory location in the second, which in this case says `$s2 + 0x2ac = $t1`. We can go and find out what is in `$s2` is: it is set *all* the way at the top of the function, in this line: +```mips +/* 000008 80C0FFD8 00809025 */ move $s2, $a0 +``` +This simply copies the contents of the second register into the first one. In this case, it is copying the contents of the function's first argument into `$s2` (because it wants to use it later, and the `$a` registers are assumed to be cleared after a function call). In this case, the first argument is a pointer to `this` (well, `thisx`, but the struct starts with an `Actor`, so it's the same address). So line `B4` of the asm really is saving `2` into the memory location `this + 0x2AC`. + +Anyway, this tells us that the variable is a byte of some kind, so `s8` or `u8`: if it was an `s16/u16` it would have said `sh`, and if it was an `s32/u32` it would have said `sw`. Unfortunately this is all we can determine from this function: MIPS does not have separate instructions for saving signed and unsigned bytes. + +At this point you have two options: guess based on statistics/heuristics, or go and look in the other functions in the actor to find out more information. The useful statistic here is that `u8` is far more common than `s8`, but let's look in the other functions, since we're pretty confident after finding `0x2ac` so easily in `Init`. So, let us grep the actor's assembly folder: +``` +$ grep -r '0x2ac' asm/non_matchings/overlays/ovl_En_Recepgirl/ +asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Draw.s:/* 00065C 80C1062C 921902AC */ lbu $t9, 0x2ac($s0) +asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C100DC.s:/* 000114 80C100E4 908202AC */ lbu $v0, 0x2ac($a0) +asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C100DC.s:/* 00012C 80C100FC A08E02AC */ sb $t6, 0x2ac($a0) +asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C100DC.s:/* 000134 80C10104 A08002AC */ sb $zero, 0x2ac($a0) +asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C100DC.s:/* 00015C 80C1012C 909802AC */ lbu $t8, 0x2ac($a0) +asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C100DC.s:/* 000164 80C10134 A09902AC */ sb $t9, 0x2ac($a0) +asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Init.s:/* 0000B4 80C10084 A24902AC */ sb $t1, 0x2ac($s2) +``` +in which we clearly see `lbu` ("load byte unsigned"), and hence this variable really is a `u8`. Hence we can add this to the actor struct too: +```C +typedef struct EnRecepgirl { + /* 0x0000 */ Actor actor; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[24]; + /* 0x0218 */ Vec3s morphTable[24]; + /* 0x02A8 */ EnRecepgirlActionFunc actionFunc; + /* 0x02AC */ u8 unk_2AC; + /* 0x02AD */ char unk_2AD[0x7]; +} EnRecepgirl; // size = 0x2B4 +``` + +You might think that was a lot of work for one variable, but it's pretty quick when you know what to do. Obviously this would be more difficult with a more common number, but it's often still worth trying. + +Removing some of the declarations for data that we have accounted for, the function now looks like this: +```C +? func_80C10148(EnRecepgirl *); // extern + +void EnRecepgirl_Init(Actor *thisx, GlobalContext *globalCtx) { + EnRecepgirl* this = THIS; + void **temp_s0; + void **phi_s0; + + Actor_ProcessInitChain(&this->actor, D_80C106C0); + ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06011B60, &D_06009890, this->jointTable, this->morphTable, 24); + + phi_s0 = D_80C106B0; + if (D_80C106C8 == 0) { + do { + temp_s0 = phi_s0 + 4; + temp_s0->unk-4 = Lib_SegmentedToVirtual(*phi_s0); + phi_s0 = temp_s0; + } while (temp_s0 != D_80C106C0); + D_80C106C8 = 1; + } + + this->unk_2AC = 2; + if (Flags_GetSwitch(globalCtx, (s32) this->actor.params) != 0) { + this->actor.textId = 0x2ADC; + } else { + this->actor.textId = 0x2AD9; + } + func_80C10148(this); +} +``` + +We have one significant problem and a few minor ones left. + +### Casts and boolean functions + +mips2c likes casting a lot: this is useful for getting types, less so when the type is changed automatically, such as in `Flags_GetSwitch(globalCtx, (s32) this->actor.params)`. Also, if we look at this function's definition, we discover it will only return `true` or `false`, so we can remove the `!= 0`. + +### Functions called + +One minor problem is what `func_80C10148` is: C needs a prototype to compile it properly. mips2c has offered us `? func_80C10148(EnRecepgirl *); // extern`, but this is obviously incomplete: there's no `?` type in C! We shall guess for now that this function returns `void`, for two reasons: +1. It's not used as a condition in a conditional or anything +2. It's not used to assign a value + +To this experience will add a third reason: +3. This is probably a setup function for an actionFunc, which are usually either `void (*)(ActorType*)` or `void (*)(ActorType*, GlobalContext*)`. + +The upshot of all this is to remove mips2c's `? func_80C10148(EnRecepgirl *); // extern`, and add a `void func_80C10148(EnRecepgirl* this);` underneath the declarations for the main four functions: +```C +void EnRecepgirl_Init(Actor* thisx, GlobalContext* globalCtx); +void EnRecepgirl_Destroy(Actor* thisx, GlobalContext* globalCtx); +void EnRecepgirl_Update(Actor* thisx, GlobalContext* globalCtx); +void EnRecepgirl_Draw(Actor* thisx, GlobalContext* globalCtx); + +void func_80C10148(EnRecepgirl* this); +``` + +(we usually leave a blank line after the main four, and put all further declarations in address order). + + +### Loops + +Loops are often some of the hardest things to decompile, because there are many ways to write a loop, only some of which will generate the same assembly. mips2c has had a go at the one in this function, but it usually struggles with loops: don't expect it to get a loop correct, well, at all. + +The code in question is +```C + void **temp_s0; + void **phi_s0; + +[...] + + phi_s0 = D_80C106B0; + if (D_80C106C8 == 0) { + do { + temp_s0 = phi_s0 + 4; + temp_s0->unk-4 = Lib_SegmentedToVirtual(*phi_s0); + phi_s0 = temp_s0; + } while (temp_s0 != D_80C106C0); + D_80C106C8 = 1; + } +``` + +`D_80C106B0` is the array that mips2c has declared above the function, a set of 8-digit hex numbers starting `0x06`. These are likely to be *segmented pointers*, but this is not a very useful piece of information yet. `D_80C106C0` is the InitChain, though, and it seems pretty unlikely that it would be seriously involved in any sort of loop. Indeed, if you tried to compile this now, you would get an error: +``` +cfe: Error: src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.c, line 61: Unacceptable operand of == or != + } while (temp_s0 != D_80C106C0); + -------------------------^ +``` +so this can't possibly be right. + +So what on earth is this loop doing? Probably the best thing to do is manually unroll it and see what it's doing each time. + +0. `phi_s0 = D_80C106B0`, aka `&D_80C106B0[0]`, to `temp_s0 = D_80C106B0 + 4`, i.e. `&D_80C106B0[1]`. But then `temp_s0->unk-4` is 4 backwards from `&D_80C106B0[1]`, which is back at `&D_80C106B0[0]`; the `->` means to look at what is at this address, so `temp_s0->unk-4` is `D_80C106B0[0]`. Equally, `*phi_s0` is the thing at `&D_80C106B0[0]`, i.e. `D_80C106B0[0]`. So the actual thing the first pass does is +```C + D_80C106B0[0] = Lib_SegmentedToVirtual(D_80C106B0[0]); +``` +it then proceeds to set `phi_s0 = &D_80C106B0[1]` for the next iteration. + +1. We go through the same reasoning and find the inside of the loop is +```C + temp_s0 = &D_80C106B0[2]; + D_80C106B0[1] = Lib_SegmentedToVirtual(D_80C106B0[1]); + phi_s0 = &D_80C106B0[2]; +``` + +2. +```C + temp_s0 = &D_80C106B0[3]; + D_80C106B0[2] = Lib_SegmentedToVirtual(D_80C106B0[2]); + phi_s0 = &D_80C106B0[3]; +``` + +3. +```C + temp_s0 = &D_80C106B0[4]; + D_80C106B0[3] = Lib_SegmentedToVirtual(D_80C106B0[3]); + phi_s0 = &D_80C106B0[4]; +``` +But now, `&D_80C106B0[4] = D_80C106B0 + 4 * 4 = D_80C106B0 + 0x10`, and `0x10` after this array's starting address is `D_80C106C0`, i.e. the InitChhain. Hence at this point the looping ends. + +So what this loop actually does is run `Lib_SegmentedToVirtual` on each element of the array `D_80C106B0`. + +At this point, I confess that I guessed what this loop does, and rewrote it how I would have written it, namely how one usually iterates over an array: +```C + s32 i; +[...] + for (i = 0; i < 4; i++) { + D_80C106B0[i] = Lib_SegmentedToVirtual(D_80C106B0[i]); + } +``` + +This is a dangerous game, since there is no guarantee that what you think is the right way to write something bears any relation to either what the original was like, or more importantly, what will give the same codegen as the original. This is a significant leap, since the original appears to be using a pointer iterator! + +However, this is certainly at least equivalent to the original (or at least, to what mips2c gave us: it's not infallible): we can be certain of this because we wrote the thing out in its entirety to understand it! This also allows us to eliminate one of the temps: you'll find with even simple loops mips2c will usually make two temps for the loop variable. + +Hence we end up with + +```C +void func_80C10148(EnRecepgirl* this); +[...] + +void EnRecepgirl_Init(Actor *thisx, GlobalContext *globalCtx) { + EnRecepgirl* this = THIS; + + Actor_ProcessInitChain(&this->actor, D_80C106C0); + ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06011B60, &D_06009890, this->jointTable, this->morphTable, 24); + + if (D_80C106C8 == 0) { + for (i = 0; i < 4; i++) { + D_80C106B0[i] = Lib_SegmentedToVirtual(D_80C106B0[i]); + } + D_80C106C8 = 1; + } + + this->unk_2AC = 2; + + if (Flags_GetSwitch(globalCtx, this->actor.params)) { + this->actor.textId = 0x2ADC; + } else { + this->actor.textId = 0x2AD9; + } + + func_80C10148(this); +} +``` +as our first guess. This doesn't look unreasonable... the question is, does it match? + +## Diff + +Once preliminary cleanup and struct filling is done, most time spent matching functions is done by comparing the original code with the code you have compiled. This is aided by a program called `diff.py`. + +In order to use `diff.py` with the symbol names, we need a copy of the code to compare against. In MM this is done as part of `make init`, and you can regenerate the `expected` directory (which is simply a known-good copy of `build` directory) by running `make diff-init`, which will check for an OK ROM and copy the build directory over. (Of course you need an OK ROM to do this; worst-case, you can checkout master and do a complete rebuild to get it). (You need to remake `expected` if you want to diff a function you have renamed: `diff.py` looks in the mapfiles for the function name, which won't work if the name has changed!) + +Now, we run diff on the function name: in the main directory, +``` +$ ./diff.py -mwo3 EnRecepgirl_Init +``` +(To see what these arguments do, run it with `./diff.py -h` or look in the scripts documentation.) + +![FeelsOKMan completely white diff](images/EnRecepgirl_Init_diff_matching.png) + +And err, well, everything is white, so it matches. Whoops. Guess we'll cover `diff.py` properly next time! (Notice that even though the diff is completely white, there are some differences in the `%hi`s and `%lo`s that access data, because it is now accessed with a relative address rather than an absolute one. If you have the data in the file in the right order, this shouldn't matter.) + +And with that, we have successfully matched our first function. + +**N.B** Notice that we don't yet have much idea of what this code actually does: this should be clarified by going through the rest of the actor's functions, which is discussed in the next document. + +Next: [Other functions in the actor](other_functions.md) diff --git a/docs/tutorial/contents.md b/docs/tutorial/contents.md new file mode 100644 index 000000000..227f4fc7d --- /dev/null +++ b/docs/tutorial/contents.md @@ -0,0 +1,56 @@ +# Getting started + +## [Introduction to decomp](introduction.md) +- What we are doing +- Structure of the code + +## Pre-decompilation +- Building the repo (follow the instructions in the [README.md](../../README.md)) +- Most of us use VSCode. Some useful information is [here](vscode.md). + +- Choosing a first actor (You want something small that has simple interactions with the environment. A simple NPC can also work, and is what we will use as an illustration for most of the tutorial. There is a collection of actors we think are suitable for beginners on the spreadsheet or Trello) + +## Decompilation + +- [Begining decompilation: order, Init and the actor struct](beginning_decomp.md) + - Order of decompilation + - Init and common actor features + - Initchains + - Actors and dynapoly actors + - Colliders + - Skelanime + +- [The rest of the functions in the actor](other_functions.md) + - Order of decompilation + - Action Functions and other functions + +- [Draw functions](draw_functions.md) + +- [Data, migration and non-migration](data.md) + - Importing the data: early and late + - Segmented pointers + - Fake symbols + - Inlining + +## [Object Decompilation](object_decomp.md) (TODO) +- Object files +- How we decompile objects + +## After Decompilation + +- See the [CONTRIBUTING.md](../../CONTRIBUTING.md) for most of the details for submitting PRs. Remember to format again after making adjustments from reviews! +- More information about specific preparations is in [this document](merging.md). + +## Appendices +- [Types, Structs and Padding](types_structs_padding.md) (a miscellany of useful stuff) +- [Advanced control flow](advanced_control_flow.md) (an example of a more complex function which mips2c is not so good at) +- [Using the diff script and the permuter](diff_and_permuter.md) (using the diff script and the permuter to match something) + - control flow (branches) -> instruction ordering -> register allocation -> stack +- [Helper scripts] TODO: link when merged + +To be written, maybe + +- How we use git and GitHub +- Some notes on the basic structure of N64 MIPS +- Glossary +- Conventions diff --git a/docs/tutorial/data.md b/docs/tutorial/data.md new file mode 100644 index 000000000..ae856123e --- /dev/null +++ b/docs/tutorial/data.md @@ -0,0 +1,171 @@ +# Data + +Up: [Contents](contents.md) +Previous: [Draw functions](draw_functions.md) + +## Table of Contents + +- [Data first](#data-first) +- [Extern and data last](#extern-and-data-last) +- [Segmented pointers](#segmented-pointers) +- [Fake symbols](#fake-symbols) +- [Inlining](#inlining) + +Each actor's data is stored in a separate file. EnRecepgirl's data is in `data/overlays/ovl_En_Recepgirl/ovl_En_Recepgirl.data.s`, for example. At some point in the decompilation process we need to convert this raw data into recognisable information for the C to use. + +There are two main ways to do this: either +1. import the data first and type it later, or +2. wait until the data appears in functions, extern it, then import it at the end + +Sometimes something between these two is appropriate: wait until the largest or strangest bits of data appear in functions, get some typing information out of that, and then import it, but for now, let's stick to both of these. + +Both approaches have their advantages and disadvantages. + +## Data first + +This way is good for smaller actors with little data. The OoT tutorial [covers this in plenty of detail](https://github.com/zeldaret/oot/blob/master/docs/tutorial/data.md), and the process in MM is essentially identical, so we won't go over it here. + + +## Extern and data last + +Externing is explained in detail in the document about the [Init function](beginning_decomp.md). To summarize, every time a `D_address` appears that is in the data file, we put a +```C +extern UNK_TYPE D_address; +``` +at the top of the file, in the same order that the data appears in the data file. We can also give it a type if we know what the type actually is (e.g. for colliders, initchains, etc.), and convert the actual data and place it commented-out under the corresponding line. This means we don't have to do everything at once at the end. + +Once we have decompiled enough things to know what the data is, we can import it. The advantage of doing it this way is we should know what type everything is already: in our work on EnRecepgirl, for example, we ended up with the following data at the top of the file +```C +#if 0 +const ActorInit En_Recepgirl_InitVars = { + ACTOR_EN_RECEPGIRL, + ACTORCAT_NPC, + FLAGS, + OBJECT_BG, + sizeof(EnRecepgirl), + (ActorFunc)EnRecepgirl_Init, + (ActorFunc)EnRecepgirl_Destroy, + (ActorFunc)EnRecepgirl_Update, + (ActorFunc)EnRecepgirl_Draw, +}; + +static void* D_80C106B0[4] = { (void*)0x600F8F0, (void*)0x600FCF0, (void*)0x60100F0, (void*)0x600FCF0 }; + +// static InitChainEntry sInitChain[] = { +static InitChainEntry D_80C106C0[] = { + ICHAIN_U8(targetMode, 6, ICHAIN_CONTINUE), + ICHAIN_F32(targetArrowOffset, 1000, ICHAIN_STOP), +}; + +static s32 D_80C106C8 = 0; + +#endif +``` +and the main thing we need to understand is `D_80C106B0` + +*Before doing anything else, make sure `make` gives `OK`.* + +First, we tell the compiler to ignore the original data file. To do this, open the file called `spec` in the main directory of the repository, and search for the actor name. You will find a section that looks like +``` +beginseg + name "ovl_En_Recepgirl" + compress + include "build/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.o" + include "build/data/ovl_En_Recepgirl/ovl_En_Recepgirl.data.o" + include "build/data/ovl_En_Recepgirl/ovl_En_Recepgirl.reloc.o" +endseg +``` +We will eventually remove both of the bottom two lines and replace them with our own reloc file, but for now, just comment out the data line: +``` +beginseg + name "ovl_En_Recepgirl" + compress + include "build/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.o" + //include "build/data/ovl_En_Recepgirl/ovl_En_Recepgirl.data.o" + include "build/data/ovl_En_Recepgirl/ovl_En_Recepgirl.reloc.o" +endseg +``` + +Next remove all the externs, and uncomment their corresponding commented data: +```C +const ActorInit En_Recepgirl_InitVars = { + ACTOR_EN_RECEPGIRL, + ACTORCAT_NPC, + FLAGS, + OBJECT_BG, + sizeof(EnRecepgirl), + (ActorFunc)EnRecepgirl_Init, + (ActorFunc)EnRecepgirl_Destroy, + (ActorFunc)EnRecepgirl_Update, + (ActorFunc)EnRecepgirl_Draw, +}; + +static void* D_80C106B0[4] = { (void*)0x600F8F0, (void*)0x600FCF0, (void*)0x60100F0, (void*)0x600FCF0 }; + +// static InitChainEntry sInitChain[] = { +static InitChainEntry D_80C106C0[] = { + ICHAIN_U8(targetMode, 6, ICHAIN_CONTINUE), + ICHAIN_F32(targetArrowOffset, 1000, ICHAIN_STOP), +}; + +static s32 D_80C106C8 = 0; +``` + +That should be everything, and we should now be able to `make` without the data file with no issues. + + +## Segmented pointers + +The game has a convenient system that allows it to sometimes effectively use offsets into a file instead of raw memory addresses to reference things. This is done by setting a file address to a *segment*. A segmented address is of the form `0x0XYYYYYY`, where `X` is the segment number. There are 16 available segments, and actors always set segment 6 to their object file, which is a file containing assets (skeleton, animations, textures, etc.) that they use. This is what all those `D_06...` are, and it is also what the entries in `D_80C106B0` are: they are currently raw numbers instead of symbols, though, and we would like to replace them. + +There is an obvious problem here, which is that is that these symbols have to be defined *somewhere*, or the linker will complain (indeed, if we change the ones in the array to `D_...`, even if we extern them, we get +``` +mips-linux-gnu-ld: build/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.o:(.data+0x20): undefined reference to `D_0600F8F0' +```` +As we'd expect, of course: we didn't fulfil our promise that they were defined elsewhere.) + +This is mitigated by use of the file `undefined_syms.txt`, which feeds the linker the raw addresses to use as the symbol definitions. If you find a segmented address that is not in already externed, `extern` it at the top of the file and add it to the actor's section in undefined_syms: +```C +extern void* D_0600F8F0; +extern void* D_0600FCF0; +extern void* D_060100F0; +extern void* D_0600FCF0; + +static void* D_80C106B0[4] = { &D_0600F8F0, &D_0600FCF0, &D_060100F0, &D_0600FCF0 }; +``` +and in undefined_syms.txt: +``` +// ovl_En_Recepgirl +D_06000968 = 0x06000968; +D_06001384 = 0x06001384; +D_06009890 = 0x06009890; +D_0600A280 = 0x0600A280; +D_0600AD98 = 0x0600AD98; +D_0600F8F0 = 0x0600F8F0; +D_0600FCF0 = 0x0600FCF0; +D_060100F0 = 0x060100F0; +D_06011B60 = 0x06011B60; +``` + +We will come back and name these later when we do the object. + + +## Fake symbols + +Some symbols in the data have been decompiled wrongly, being incorrectly separated from the previous symbol due to how it was accessed by the actor's functions. However, most of these have now been fixed. Some more detail is given in [Types, structs and padding](types_structs_padding.md) If you are unsure, ask! + + +## Inlining + +After the file is finished, it is possible to move some static data into functions. This requires that: +1. The data is used in only one function +2. The ordering of the data can be maintained + +Additionally, we prefer to keep larger data (more than a line or two) out of functions anyway. + + +# Finally: .bss + +A .bss contains data that is uninitialised (actually initialised to `0`). For most actors all you need to do is declare it at the top of the actor file without giving it a value, once you find out what type it is. In `code`, it's much more of a problem. + +Next: [Documenting](documenting.md) \ No newline at end of file diff --git a/docs/tutorial/diff_and_permuter.md b/docs/tutorial/diff_and_permuter.md new file mode 100644 index 000000000..aa72999d1 --- /dev/null +++ b/docs/tutorial/diff_and_permuter.md @@ -0,0 +1,145 @@ +# `diff.py` and the permuter + +This document is intended as a step-by-step demonstration of matching a reasonably complex function using the diff script `diff.py` and the decomp permuter, both included in the repo. For general information on both see [the tools documentation](../tools.md). + +Until such time as someone finds a suitable function, you can look at the OoT tutorial: [here for diff.py](https://github.com/zeldaret/oot/blob/master/docs/tutorial/beginning_decomp.md#diff) and [here for the permuter](https://github.com/zeldaret/oot/blob/master/docs/tutorial/other_functions.md#the-permuter). + + + + diff --git a/docs/tutorial/disassembly_quirks.md b/docs/tutorial/disassembly_quirks.md new file mode 100644 index 000000000..dacfb78d8 --- /dev/null +++ b/docs/tutorial/disassembly_quirks.md @@ -0,0 +1,36 @@ +# Disassembly quirks + +As MM's disassembly is automatic, there are certain unique problems it has. + +## Renaming functions and variables + +A function must be renamed in `tools/disasm/functions.txt` in addition to the source code, for the disassembler to know what to call the symbol at that address when it sees it. + +Variables must be renamed in `tools/disasm/variables.txt`. It may also be necessary to change their type, count or size to stop the disassembler misusing them. + +You can avoid having to redisassemble every time by running `rename_global_asm.py`, which will rename the individual functions' assembly files in `asm/nonmatchings/` to the name of the function they contain. + + +## Fake and incorrect symbols + +TODO + + +## Resplitting a file + +The files `boot` and `code` are each divided up into dozens of separate files, that are all joined together into one text, data, rodata and bss section when building the ROM. As such, it has been necessary to guess where the file boundaries are, and not every file contains the correct functions or the correct data (rodata is mostly the exception since it is automatically split). + +To change a split for a file, find its entry in `tools/disasm/files.txt`, and change or create entries to accurately reflect where the file(s) should start. For example, it was found that the last function in `z_nmi_buff.c` had nothing to do with the rest, so it should be split into its own file. Looking up the address of the last function, it was found to be at `0x8010C1B0`, so adding the line: + +```diff + 0x8010C0C0 : "z_nmi_buff", ++++ 0x8010C1B0 : "code_8010C1B0", + 0x8010C230 : "z_olib", +``` + +to the file will extract it correctly as a separate file. It also is necessary to make a new C file and move the `GLOBAL_ASM` declaration into it. + +Unfortunately you essentially have to redisassemble after telling the disassembler to resplit a file. + + +## diff --git a/docs/tutorial/documenting.md b/docs/tutorial/documenting.md new file mode 100644 index 000000000..9b2c8e177 --- /dev/null +++ b/docs/tutorial/documenting.md @@ -0,0 +1,601 @@ +# Documenting + +Up: [Contents](contents.md) +Previous: [Data](data.md) + +Decompilation is only the first step: since the point of this project is to understand the game better than ever before, the code needs documentation. In this document, we will go through the basic stuff that it's good to do for any actor: we will not try to understand every single thing the actor does in full detail, but try to name the functions and variables usefully for a full documentation pass later to take advantage of. + +It is helpful to document the functions and variables in the actor before you Pull Request it. The aim is to provide code that is sufficiently clear to be self-documenting, but it is worth leaving a comment on anything you find obscure or confusing. (Pull Request reviews will let you know if you are leaving too many comments.) Useful things to do documentation-wise: + +- Name all (or most) of the functions. +- Name all the variables in the actor struct. +- Create enums for params, and any other numbers that would benefit from that sort of clarity. + +You can test things using the practice rom for a retail version (watches and memory view is especially helpful), as well as the generated rom with Project 64 and something like Spectrum. + +If you want to use `diff.py` after renaming anything, particularly functions, remember to rerun `make diff-init` so it can use the correct symbols. + +Finally, *if you are not sure what something does, either ask or leave it unnamed: it will be less confusing later if things are unnamed than if they are wrongly named* + + +## Renaming things + +Because MM needs to regenerate the assembly code, it is necessary to tell the disassembler the names of functions and variables, so it knows what symbols to assign in the code. This is done via `functions.txt` and `variables.txt`. The best way to rename functions and symbols is via global rename in an editor like VSCode. The next best way is to run `tools/rename_sym.sh`. You should be careful with this script: it has no error-checking! + +Renaming symbols in theory requires re-disassembly. This can often be avoided in the case of functions by running `tools/rename_global_asm.py`, which will rename any individual functions' assembly files with the wrong names, so that the `GLOBAL_ASM`s can spot them. Renaming variables *may* require redisassembly (and if fake symbols are removed, it *will*). + + +## EnRecepgirl + +Currently, the file looks like this: +
+ +Large code block, click to show + + +```C +#include "z_en_recepgirl.h" + +#define FLAGS 0x00000009 + +#define THIS ((EnRecepgirl*)thisx) + +void EnRecepgirl_Init(Actor* thisx, GlobalContext* globalCtx); +void EnRecepgirl_Destroy(Actor* thisx, GlobalContext* globalCtx); +void EnRecepgirl_Update(Actor* thisx, GlobalContext* globalCtx); +void EnRecepgirl_Draw(Actor* thisx, GlobalContext* globalCtx); + +void func_80C10148(EnRecepgirl* this); +void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx); +void func_80C10290(EnRecepgirl* this); +void func_80C102D4(EnRecepgirl * this, GlobalContext * globalCtx); + +const ActorInit En_Recepgirl_InitVars = { + ACTOR_EN_RECEPGIRL, + ACTORCAT_NPC, + FLAGS, + OBJECT_BG, + sizeof(EnRecepgirl), + (ActorFunc)EnRecepgirl_Init, + (ActorFunc)EnRecepgirl_Destroy, + (ActorFunc)EnRecepgirl_Update, + (ActorFunc)EnRecepgirl_Draw, +}; + +extern void* D_0600F8F0; +extern void* D_0600FCF0; +extern void* D_060100F0; + +static void* D_80C106B0[4] = { &D_0600F8F0, &D_0600FCF0, &D_060100F0, &D_0600FCF0 }; + +// static InitChainEntry sInitChain[] = { +static InitChainEntry D_80C106C0[] = { + ICHAIN_U8(targetMode, 6, ICHAIN_CONTINUE), + ICHAIN_F32(targetArrowOffset, 1000, ICHAIN_STOP), +}; + +static s32 D_80C106C8 = 0; + +extern AnimationHeader D_06000968; +extern AnimationHeader D_06001384; +extern AnimationHeader D_06009890; +extern AnimationHeader D_0600A280; +extern AnimationHeader D_0600AD98; +extern FlexSkeletonHeader D_06011B60; + + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Init.s") +void EnRecepgirl_Init(Actor* thisx, GlobalContext* globalCtx) { + EnRecepgirl* this = THIS; + s32 i; + + Actor_ProcessInitChain(&this->actor, D_80C106C0); + ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06011B60, &D_06009890, this->jointTable, this->morphTable, 24); + + if (D_80C106C8 == 0) { + for (i = 0; i < 4; i++) { + D_80C106B0[i] = Lib_SegmentedToVirtual(D_80C106B0[i]); + } + D_80C106C8 = 1; + } + + this->unk_2AC = 2; + + if (Flags_GetSwitch(globalCtx, this->actor.params)) { + this->actor.textId = 0x2ADC; + } else { + this->actor.textId = 0x2AD9; + } + + func_80C10148(this); +} + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Destroy.s") +void EnRecepgirl_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C100DC.s") +void func_80C100DC(EnRecepgirl *this) { + if (this->unk_2AC != 0) { + this->unk_2AC++; + if (this->unk_2AC == 4) { + this->unk_2AC = 0; + return; + } + return; + } + if (Rand_ZeroOne() < 0.02f) { + this->unk_2AC++; + } +} + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10148.s") +void func_80C10148(EnRecepgirl *this) { + if (this->skelAnime.animation == &D_06001384) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 5.0f); + } + this->actionFunc = func_80C1019C; +} + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C1019C.s") +void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime) != 0) { + if (this->skelAnime.animation == &D_0600A280) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 5.0f); + } else { + Animation_ChangeTransitionRepeat(&this->skelAnime, &D_06009890, -4.0f); + } + } + + if (func_800B84D0(&this->actor, globalCtx) != 0) { + func_80C10290(this); + } else if (Actor_IsActorFacingLink(&this->actor, 0x2000)) { + func_800B8614(&this->actor, globalCtx, 60.0f); + if (Player_GetMask(globalCtx) == 2) { + this->actor.textId = 0x2367; + } else if (Flags_GetSwitch(globalCtx, this->actor.params)) { + this->actor.textId = 0x2ADC; + } else { + this->actor.textId = 0x2AD9; + } + } +} + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10290.s") +void func_80C10290(EnRecepgirl *this) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600A280, -4.0f); + this->actionFunc = func_80C102D4; +} + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C102D4.s") +void func_80C102D4(EnRecepgirl *this, GlobalContext *globalCtx) { + u8 temp_v0_2; + + if (SkelAnime_Update(&this->skelAnime) != 0) { + if (this->skelAnime.animation == &D_0600A280) { + Animation_ChangeDefaultRepeat(&this->skelAnime, &D_06001384); + } else if (this->skelAnime.animation == &D_0600AD98) { + if (this->actor.textId == 0x2ADA) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_06000968, 10.0f); + } else { + Animation_ChangeTransitionRepeat(&this->skelAnime, &D_06009890, 10.0f); + } + } else if (this->actor.textId == 0x2ADA) { + Animation_ChangeTransitionRepeat(&this->skelAnime, &D_06009890, 10.0f); + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600A280, -4.0f); + } + } + + temp_v0_2 = func_80152498(&globalCtx->msgCtx); + if (temp_v0_2 == 2) { + this->actor.textId = 0x2ADC; + func_80C10148(this); + return; + } + + if ((temp_v0_2 == 5) && (func_80147624(globalCtx) != 0)) { + if (this->actor.textId == 0x2AD9) { + Actor_SetSwitchFlag(globalCtx, this->actor.params); + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 10.0f); + if ((gSaveContext.weekEventReg[63] & 0x80)) { + this->actor.textId = 0x2ADF; + } else { + this->actor.textId = 0x2ADA; + } + } else if (this->actor.textId == 0x2ADC) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 10.0f); + this->actor.textId = 0x2ADD; + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &D_06000968, 10.0f); + if (this->actor.textId == 0x2ADD) { + this->actor.textId = 0x2ADE; + } else if (this->actor.textId == 0x2ADA) { + this->actor.textId = 0x2ADB; + } else { + this->actor.textId = 0x2AE0; + } + } + func_80151938(globalCtx, this->actor.textId); + } +} + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Update.s") +void EnRecepgirl_Update(Actor *thisx, GlobalContext *globalCtx) { + s32 pad; + EnRecepgirl* this = THIS; + Vec3s sp30; + + this->actionFunc(this, globalCtx); + func_800E9250(globalCtx, &this->actor, &this->unk_2AE, &sp30, this->actor.focus.pos); + func_80C100DC(this); +} + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10558.s") +s32 func_80C10558(GlobalContext *globalCtx, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, Actor *thisx) { + EnRecepgirl* this = THIS; + + if (limbIndex == 5) { + rot->x += this->unk_2AE.y; + } + return false; +} + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10590.s") +void func_80C10590(GlobalContext *globalCtx, s32 limbIndex, Actor *thisx) { + EnRecepgirl* this = THIS; + + if (limbIndex == 5) { + Matrix_RotateY(0x400 - this->unk_2AE.x, MTXMODE_APPLY); + Matrix_GetStateTranslationAndScaledX(500.0f, &this->actor.focus.pos); + } +} + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Draw.s") +void EnRecepgirl_Draw(Actor *thisx, GlobalContext *globalCtx) { + EnRecepgirl* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, D_80C106B0[this->unk_2AC]); + + func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, func_80C10558, NULL, func_80C10590, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +``` + +
+ +(We can delete the `GLOBAL_ASM` lines now.) + +The worst part of documentation is finding somewhere to start. We have a decent place to start here, though, in that we already know the function (or rather, the use) of a couple of the functions, namely the LimbDraws. So we can rename `func_80C10558` to `EnRecepgirl_OverrideLimbDraw` and `func_80C10590` to `EnRecepgirl_UnkLimbDraw`. Remember to do a global rename so that the functions in the assembly are renamed, use `rename_global_asm`, +``` +$ ./tools/rename_global_asm.py +asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10558.s --> asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_OverrideLimbDraw.s +asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10590.s --> asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_UnkLimbDraw.s +``` +as well as the mentions in this chunk of `functions.txt`: +``` + 0x80C0FFD0:("EnRecepgirl_Init",), + 0x80C100CC:("EnRecepgirl_Destroy",), + 0x80C100DC:("func_80C100DC",), + 0x80C10148:("func_80C10148",), + 0x80C1019C:("func_80C1019C",), + 0x80C10290:("func_80C10290",), + 0x80C102D4:("func_80C102D4",), + 0x80C104E8:("EnRecepgirl_Update",), + 0x80C10558:("func_80C10558",), + 0x80C10590:("func_80C10590",), + 0x80C105EC:("EnRecepgirl_Draw",), +``` + +That's probably as much as we can do on functions for now. Next let's think about some of the variables. We have essentially 3 sorts of variable here +- struct variables +- data/bss +- intrafunction/stack variables + +and this is roughly the order of preference for naming them (although not necessarily the logical order to determine what they do). This actor is quite limited in the last category: only `sp30` is unnamed at the moment. Even though `func_800E9250` is decomped, the purpose of the argument in which `sp30` is placed is not clear (and, indeed, is not named), so it's probably best to leave it unnamed for now. (With greater experience, you might analyse `func_800E9250` to work out what this argument is for, but let's not worry about that for now.) + +As for the struct, there are two unnamed variables at the moment: +```C +typedef struct EnRecepgirl { + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[24]; + /* 0x218 */ Vec3s morphTable[24]; + /* 0x2A8 */ EnRecepgirlActionFunc actionFunc; + /* 0x2AC */ u8 unk_2AC; + /* 0x2AE */ Vec3s unk_2AE; +} EnRecepgirl; // size = 0x2B4 +``` + +Let's start with `unk_2AC`. This is set to `2` in `Init`, something interesting happens to it in `func_80C100DC`, but it is used in the `Draw`, here: +```C + gSPSegment(POLY_OPA_DISP++, 0x08, D_80C106B0[this->unk_2AC]); +``` +So it is used as an index into the array `D_80C106B0`, and the element with that index is placed on segment `8`. So we need to work out what this array is to name `unk_2AC`. + +As we discussed last time, `D_80C106B0` is an array of [segmented pointers](data.md#segmented-pointers). Since they are in segment `6`, they are in the actor's object file. Which object? The InitVars tell us: namely, +```C +const ActorInit En_Recepgirl_InitVars = { + ACTOR_EN_RECEPGIRL, + ACTORCAT_NPC, + FLAGS, + OBJECT_BG, +``` +the fourth element is the object (it is actually an enum, but the file itself has the same name as the object enum). So, we need to look at the object file. We are very lucky that a custom tool has been written for such a thing: Z64Utils. + + +## Z64Utils + +The latest release of Z64Utils can be downloaded from [https://github.com/Random06457/Z64Utils/releases]. To use it with MM, you also need a json file to fill in the file names: the latest version can be obtained from [https://github.com/Random06457/Z64Utils-Config]. It should work on Wine. Some graphics cards don't love it, but the 3D graphical part is only required for skeleton and animations. + +Having downloaded and unzipped it, open the baserom file. This will populate the main window with a list: + +![Z64Utils' main window](images/z64utils_main.png) + +Search for the object file, right-click and select "Open in Object Analyzer". It will ask you to choose a segment: this is the segment that the file is put on, and allows Z64Utils to resolve the segmented addresses it references into symbols. The json already knows it should be segment `6`, so just click okay. This will open this window: + +![Z64Utils' object analyzer window](images/z64utils_object_analyzer.png) + +Go to "Analysis -> Find Dlists" and press OK (the defaults are usually fine). This will automatically search for displaylists in the object, which are a sufficiently distinctive format to be easy to find. We want to see the other stuff in the object too, so also do "Analysis -> Analyze Dlists". This will populate the window with even more stuff: + +![Z64Utils, with an analyzed object](images/z64utils_object_analyzed.png) + +We will talk about what all these types of data are next time, but for now, all we want to know is what +```C +extern void* D_0600F8F0; +extern void* D_0600FCF0; +extern void* D_060100F0; +``` +actually are. We know they are set on segment 8, so we need to find where the skeleton uses them. We know from `extern FlexSkeletonHeader D_06011B60;` that this is at `0x06011B60`, so scroll down to it, right-click on it, and choose "Open in Skeleton Viewer". Pick an animation that we know it uses (sometimes Z64Utils misidentifies other things for animations), such as `extern AnimationHeader D_06000968;`, and you will get this error: + +![Z64Utils, error when viewing skeleton](images/z64utils_skeleton_error.png) + +It needs something to be set to segment `8`. Well, that's good, we know that the code does that! Let's find out what. Z64Utils tells you the address, so we can look up the displaylist that wants it: the relevant block is +```C +[...] +// Multi Command Macro Found (6 instructions) +0600DE70: gsDPLoadTLUT(256, 0x100, D_0600F6F0), +// Multi Command Macro Found (7 instructions) +0600DEA0: gsDPLoadTextureBlock(D_08000000, G_IM_FMT_CI, G_IM_SIZ_8b, 32, 32, 0, G_TX_MIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_CLAMP, 5, 5, 0, 0), +0600DED8: gsDPSetTileSize(G_TX_RENDERTILE, 0, 0, (63<<2), (31<<2)), +0600DEE0: gsSPVertex(D_0600B3F0, 19, 0), +0600DEE8: gsSP2Triangles(0, 1, 2, 0, 3, 4, 5, 0), +0600DEF0: gsSP2Triangles(6, 7, 5, 0, 8, 4, 3, 0), +0600DEF8: gsSP2Triangles(7, 6, 9, 0, 5, 10, 3, 0), +0600DF00: gsSP2Triangles(5, 7, 10, 0, 11, 9, 6, 0), +0600DF08: gsSP2Triangles(11, 12, 9, 0, 4, 1, 13, 0), +0600DF10: gsSP2Triangles(6, 14, 11, 0, 13, 5, 4, 0), +0600DF18: gsSP2Triangles(5, 14, 6, 0, 15, 14, 5, 0), +0600DF20: gsSP2Triangles(8, 1, 4, 0, 2, 1, 8, 0), +0600DF28: gsSP2Triangles(13, 16, 5, 0, 13, 14, 17, 0), +0600DF30: gsSP2Triangles(18, 11, 14, 0, 12, 11, 18, 0), +0600DF38: gsSP1Triangle(13, 1, 0, 0), +0600DF40: gsDPPipeSync(), +[...] + +``` +so we see that segment `8` is expecting a texture (we'll go into more detail about precisely what when we talk about making the XML file to extract the object). Therefore, `D_80C106B0` is a set of textures. We have a special type for textures, namely `TexturePtr`. + +## Back to the data + +But what sort of textures? This is an NPC, so what textures on the model would it want to change? The answer is of course the eyes: most NPCs have eye textures, with some sort of routine for changing them to appear to blink. We can set the different textures onto segment `8` and see which is which, but this is enough to know that `D_80C106B0` can be `sEyeTextures` (`s` for `static`: they essentially have to be static so that we can name them like this without the names clashing), and that `unk_2AC` is `eyeTexIndex` (these names are not completely standard, but it's best to be as consistent as possible). + +**N.B.** static data should not be renamed in the assembly or `variables.txt`, since assembly has no notion of file locality and there can be symbol clashes. Therefore it should only be renamed in its respective file, not globally. +```C +extern void* D_0600F8F0; +extern void* D_0600FCF0; +extern void* D_060100F0; + +static TexturePtr sEyeTextures[] = { &D_0600F8F0, &D_0600FCF0, &D_060100F0, &D_0600FCF0 }; +``` + +And now it's rather more obvious what +```C +void func_80C100DC(EnRecepgirl* this) { + if (this->eyeTexIndex != 0) { + this->eyeTexIndex++; + if (this->eyeTexIndex == 4) { + this->eyeTexIndex = 0; + } + } else if (Rand_ZeroOne() < 0.02f) { + this->eyeTexIndex++; + } +} +``` +is doing: it's running a kind of blink routine. This is slightly nonstandard: usually there is a separate timer, but this one simply perturbs the index away from `0` every frame with a 2% chance. This sort of function is usually called `Blink` or `UpdateEyes`. Since it is explicitly called in `Update`, we'll call it `UpdateEyes`, but either is fine; we'll standardise later. + +We have two other pieces of data. There is a suggested name for the InitChain in the code already; just replace it and replace the first line in the definition. + +This leaves one piece of data unnamed, `D_80C106C8`. This is initially set to `0`, checked in `Init` to decide whether to run the loop, and then set to `1` after the loop is finished: +```C + if (D_80C106C8 == 0) { + for (i = 0; i < 4; i++) { + sEyeTextures[i] = Lib_SegmentedToVirtual(sEyeTextures[i]); + } + D_80C106C8 = 1; + } +``` +What is this doing? We need to understand that to name this variable. + +The N64's processors cannot use segmented addresses: they need actual RAM addresses. Therefore the segmented addresses have to be converted before being placed on a segment: this is what `Lib_SegmentedToVirtual` does. So (somewhat unusually) this loop is modifying the addresses in the actor's actual data in RAM. Having converted the addresses once, it wouldn't make any sense to convert them again, but `Init` would run every time an instantiation of the actor is created. Therefore `D_80C106C8` is present to ensure that the addresses only get converted once: it is really a boolean that indicates if the addresses have been converted. So let's call it `texturesDesegmented`, and replace its values by `true` and `false`. + +Finally, clearly `4` is linked to the data over which we're iterating: namely it's the size of the array. We have a macro for this, `ARRAY_COUNT(sEyeTextures)`. + +We've got one struct variable left. To find out what it does, we can look at a function that uses it, for example +```C +s32 EnRecepgirl_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnRecepgirl* this = THIS; + + if (limbIndex == 5) { + rot->x += this->unk_2AE.y; + } + return false; +} + +void EnRecepgirl_UnkLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnRecepgirl* this = THIS; + + if (limbIndex == 5) { + Matrix_RotateY(0x400 - this->unk_2AE.x, MTXMODE_APPLY); + Matrix_GetStateTranslationAndScaledX(500.0f, &this->actor.focus.pos); + } +} +``` +It is used to do a rotation of whatever limb `5` is. (The `+=` is because `rot->x` is the base rotation of the limb, and we have to add the same thing to it every frame to keep the angle changed and constant.) We can use Z64Utils to : setting segment `8` to one of what we know now are the eye textures, we can view the model in the skeleton viewer. The limb numbers in the object are one smaller than those in the actor (the root limb is only a concept for the code, not the object), so we find limb 4: + +![Z64Utils highlighting a limb](images/z64utils_skeleton_head.png) + +Hence this is changing the head rotation. An obvious name is `headRot`. + +## Functions + +Finally, we have to name the rest of the functions. Setup functions are usually named as `_Setup`, so we really only have to name two functions. They are both related to text. if we annotate all the textIds (do not quote the whole message, just give an unambiguous summary), the flow becomes a bit clearer: + +```C +void func_80C10148(EnRecepgirl* this) { + if (this->skelAnime.animation == &D_06001384) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 5.0f); + } + this->actionFunc = func_80C1019C; +} + +void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime) != 0) { + if (this->skelAnime.animation == &D_0600A280) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 5.0f); + } else { + Animation_ChangeTransitionRepeat(&this->skelAnime, &D_06009890, -4.0f); + } + } + + if (func_800B84D0(&this->actor, globalCtx) != 0) { + func_80C10290(this); + } else if (Actor_IsActorFacingLink(&this->actor, 0x2000)) { + func_800B8614(&this->actor, globalCtx, 60.0f); + if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEIS_MASK) { + this->actor.textId = 0x2367; // "... doesn't Kafei want to break off his engagement ... ?" + } else if (Flags_GetSwitch(globalCtx, this->actor.params)) { + this->actor.textId = 0x2ADC; // hear directions again? + } else { + this->actor.textId = 0x2AD9; // "Welcome..." + } + } +} + +void func_80C10290(EnRecepgirl* this) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600A280, -4.0f); + this->actionFunc = func_80C102D4; +} + +void func_80C102D4(EnRecepgirl* this, GlobalContext* globalCtx) { + u8 temp_v0_2; + + if (SkelAnime_Update(&this->skelAnime)) { + if (this->skelAnime.animation == &D_0600A280) { + Animation_ChangeDefaultRepeat(&this->skelAnime, &D_06001384); + } else if (this->skelAnime.animation == &D_0600AD98) { + if (this->actor.textId == 0x2ADA) { // Mayor's office is on the left (meeting ongoing) + Animation_MorphToPlayOnce(&this->skelAnime, &D_06000968, 10.0f); + } else { + Animation_ChangeTransitionRepeat(&this->skelAnime, &D_06009890, 10.0f); + } + } else if (this->actor.textId == 0x2ADA) { // Mayor's office is on the left (meeting ongoing) + Animation_ChangeTransitionRepeat(&this->skelAnime, &D_06009890, 10.0f); + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600A280, -4.0f); + } + } + + temp_v0_2 = func_80152498(&globalCtx->msgCtx); + if (temp_v0_2 == 2) { + this->actor.textId = 0x2ADC; // hear directions again? + func_80C10148(this); + } else if ((temp_v0_2 == 5) && (func_80147624(globalCtx) != 0)) { + if (this->actor.textId == 0x2AD9) { // "Welcome..." + Actor_SetSwitchFlag(globalCtx, this->actor.params); + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 10.0f); + if (gSaveContext.weekEventReg[63] & 0x80) { // showed Couple's Mask to meeting + this->actor.textId = 0x2ADF; // Mayor's office is on the left (meeting ended) + } else { + this->actor.textId = 0x2ADA; // Mayor's office is on the left (meeting ongoing) + } + } else if (this->actor.textId == 0x2ADC) { // hear directions again? + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 10.0f); + this->actor.textId = 0x2ADD; // "So..." + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &D_06000968, 10.0f); + + if (this->actor.textId == 0x2ADD) { // "So..." + this->actor.textId = 0x2ADE; // Mayor's office is on the left, drawing room on the right + } else if (this->actor.textId == + 0x2ADA) { // Mayor's office is on the left (meeting ongoing) + this->actor.textId = 0x2ADB; // drawing room on the right + } else { + this->actor.textId = 0x2AE0; // drawing room on the right, don't go in without an appointment + } + } + func_80151938(globalCtx, this->actor.textId); + } +} +``` +All this branching is to make the conversation look more diverse and interesting. Notably, though, `func_80C1019C` is set to start with, and is only changed when `func_800B84D0(&this->actor, globalCtx) != 0`. This is something to do with talking. The other function handles the rest of the conversation, and hands back to the first if `func_80152498(&globalCtx->msgCtx) == 2`. This function is *something* to do with the text state, which will require `z_message` to be decomped. However, observation in-game will reveal this is something to do with ending dialogue. So we can conclude that the action functions are `EnRecepgirl_Wait` and `EnRecepgirl_Talk`. The setup functions are thus `EnRecepgirl_SetupWait` and `EnRecepgirl_SetupTalk`. + +For more complex actors, we have a tool called `graphovl.py` that can produce function flow graphs for actors: running +``` +$ ./tools/graphovl/graphovl.py En_Recepgirl +``` +produces + +![EnRecepgirl's function flow graph](images/En_Recepgirl.gv.png) + + +## Miscellaneous other documentation + +We like to make macros for reading an actor's `params` (indeed, this is required even if you don't know what the params are for). A simple example is `ObjTree`, which has the following code in its `Init` function: + +```c + if (this->dyna.actor.params & 0x8000) { + Actor_SetScale(&this->dyna.actor, 0.15f); + this->dyna.actor.uncullZoneForward = 4000.0f; + } else { + Actor_SetScale(&this->dyna.actor, 0.1f); + DynaPolyActor_Init(&this->dyna, 1); + CollisionHeader_GetVirtual(&D_06001B2C, &colHeader); + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader); + } +``` + +Looking through the rest of the actor, it becomes apparent that `params & 0x8000` is only used for changing the size of the tree: ones with this bit set are larger. So we make a macro in the header: + +```c +#define OBJTREE_ISLARGE(thisx) ((thisx)->params & 0x8000) +``` + +Notice that we use `thisx`: this makes the form of every one of these macros the same. However, we only use `thisx` if required for matching, so when we add it to the actor, we use `&this->dyna.actor` (in this case, since `ObjTree` is a dynapoly actor). + +```c + if (OBJTREE_ISLARGE(&this->dyna.actor)) { + Actor_SetScale(&this->dyna.actor, 0.15f); + this->dyna.actor.uncullZoneForward = 4000.0f; + } else { + Actor_SetScale(&this->dyna.actor, 0.1f); + DynaPolyActor_Init(&this->dyna, 1); + CollisionHeader_GetVirtual(&D_06001B2C, &colHeader); + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader); + } +``` + +Much clearer! + + +We have now essentially documented this as far as we can without the object, so we'd better do that next. + +Next: [Analysing object files](object_decomp.md) diff --git a/docs/tutorial/draw_functions.md b/docs/tutorial/draw_functions.md new file mode 100644 index 000000000..319d5efbb --- /dev/null +++ b/docs/tutorial/draw_functions.md @@ -0,0 +1,303 @@ +# Draw functions + +Up: [Contents](contents.md) +Previous: [The rest of the functions in the actor](other_functions.md) + +Draw functions behave completely differently from the other functions in an actor. They often use a lot of macros. + +This document will be a bit different: we will look at the draw functions in EnRecepgirl, then consider some more complicated examples. + +## A first example + +Unless it is completely invisible, an actor usually has a draw function as one of the main four actor functions. Hence its prototype looks like + +```C +void EnRecepgirl_Draw(Actor* thisx, GlobalContext* globalCtx); +``` + +From now on, the process is rather different from the decompilation process used for the other functions. Here is the output of mips2c after sorting out the actor struct from Init, and with the arguments set back to `Actor* thisx`: +```C +s32 func_80C10558(GlobalContext *globalCtx, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, Actor *actor); // extern +void func_80C10590(GlobalContext *globalCtx, s32 limbIndex, Actor *actor); // extern +void *D_80C106B0[4] = {(void *)0x600F8F0, (void *)0x600FCF0, (void *)0x60100F0, (void *)0x600FCF0}; + +void EnRecepgirl_Draw(Actor *thisx, GlobalContext *globalCtx) { + EnRecepgirl* this = (EnRecepgirl *) thisx; + GraphicsContext *sp30; + Gfx *temp_v1; + GraphicsContext *temp_a0; + + temp_a0 = globalCtx->state.gfxCtx; + sp30 = temp_a0; + func_8012C28C(temp_a0); + temp_v1 = sp30->polyOpa.p; + sp30->polyOpa.p = temp_v1 + 8; + temp_v1->words.w0 = 0xDB060020; + temp_v1->words.w1 = (u32) D_80C106B0[this->unk_2AC]; + func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, (s32) this->skelAnime.dListCount, func_80C10558, NULL, func_80C10590, (Actor *) this); +} +``` + + +Notable features are the GraphicsContext temps, and blocks of the form + +```C + temp_v1 = sp30->polyOpa.p; + sp30->polyOpa.p = temp_v1 + 8; + temp_v1->words.w0 = 0xDB060020; + temp_v1->words.w1 = (u32) D_80C106B0[this->unk_2AC]; +``` + +(This is a particularly simple example, since there's only one of these blocks. We will give a more involved example later.) + +Each of these blocks converts into a graphics macro. They are usually (but not always) straightforward, but manually converting them is a pain, and there are sometimes special cases. To deal with them easily, we will use a tool from glank's N64 tools. To install these, follow the instructions [here](https://practicerom.com/public/packages/debian/howto.txt). + +For our purposes, we only need one of the programs this provides: `gfxdis.f3dex2`. + + +Graphics are actually 64-bit on the Nintendo 64. This code block is a result of instructions telling the processor what to do with the graphics pointer. There are two main types of graphics pointer (there are a couple of others used in `code`, but actors will only use these two), +- polyOpa ("opaque") for solid textures +- polyXlu ("Xlucent" i.e. "translucent") for translucent textures + +Our example is polyOpa, not surprisingly since our receptionist is solid. + +`words.w0` and `words.w1` contain the actual graphics instruction, in hex format. Usually, `w0` is constant and `w1` contains the arguments. To find out what sort of macro we are dealing with, we use `gfxdis.f3dex2`. `w1` is variable, but we need to give the program a constant placeholder. A common word to use is 12345678, so in this case we run +``` +gfxdis.f3dex2 -x -g "POLY_OPA_DISP++" -d DB06002012345678 +``` + +- `-x` uses hex instead of the default qu macros (never mind what those are, MM doesn't use them) +- `-g` is used to specify which graphics pointer macro to use +- `-d` is for the graphics dword + +Our standard now is to use decimal colors. If you have a constant second argument rather than a variable one, you can also use `-dc` to get decimal colors instead of the default hex. + +The output looks like +``` +gSPSegment(POLY_OPA_DISP++, 0x08, 0x12345678); +``` + +We can now replace the `0x12345678` by the actual second word, namely `D_80C106B0[this->unk_2AC]`. We can see mips2c has pulled in this data again: we saw it before in the `Init`. + +The words look like pointers to assets in the actor's object segment, which would make sense if we're looking for textures to draw. Because this data is used in a graphics macro, it will be either a displaylist or a texture; it may as well stay as `void*` until we come back to it later. + +```C +gSPSegment(POLY_OPA_DISP++, 0x08, D_80C106B0[this->unk_2AC]); +``` + +You repeat this for every block in the function. + +If you have worked on OoT, you will be aware of the functions `Graph_OpenDisps` and `Graph_CloseDisps`, and might be surprised to see them missing here. These functions are actually a debug feature: the `OPEN_DISPS` and `CLOSE_DISPS` macros still exist, but they don't expand to functions. Of course this means you have to guess where they go. A sensible guess for `OPEN_DISPS` is where the `gfxCtx` temp assignment first happens; `CLOSE_DISPS` is a bit harder, although it's basically just a `}`, so it *shouldn't* matter as much. + +It's sensible to eliminate all the `gfxCtx` temps and reintroduce as needed. Also remember to change the prototype and function definition back! +```C +s32 func_80C10558(GlobalContext *globalCtx, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, Actor *actor); +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10558.s") + +void func_80C10590(GlobalContext *globalCtx, s32 limbIndex, Actor *actor); +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10590.s") + +// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Draw.s") +void EnRecepgirl_Draw(Actor *thisx, GlobalContext *globalCtx) { + EnRecepgirl* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, D_80C106B0[this->unk_2AC]); + + func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, func_80C10558, NULL, func_80C10590, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} +``` + +And this matches. + +The last two functions in the actor are used as arguments in `func_801343C0`. This is a `SkelAnime` function, except unlike the OoT ones, it has three function callback arguments instead of two: in `functions.h` or `z_skelanime.c`, we find +```C +void func_801343C0(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, + OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, UnkActorDraw unkDraw, Actor* actor) +``` +The typedefs of the callbacks it uses are in `z64animation.h`: +```C +typedef s32 (*OverrideLimbDraw)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + struct Actor* actor); + +typedef void (*PostLimbDraw)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, + struct Actor* actor); + +[...] + +typedef void (*UnkActorDraw)(struct GlobalContext* globalCtx, s32 limbIndex, struct Actor* actor); +``` +which is where mips2c got them from. + +In this case, only two of them are used, and it is these that are the last functions standing between us and a decompiled actor. + +## OverrideLimbDraw, PostLimbDraw, UnkActorDraw + +Well, we don't have a PostLimbDraw here, but as we see from the prototype, it's much the same as the OverrideLimbDraw but without the `pos` argument and no return value. +```C +s32 func_80C10558(GlobalContext *globalCtx, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, Actor *actor) { + if (limbIndex == 5) { + rot->x += actor->unk2B0; + } + return 0; +} +``` +Only two things to do here: we need to use `EnRecepgirl` to get to `actor + 0x2B0`, and the return value is used as a boolean, so we replace `0` by `false` (`true` means "don't draw the limb", and is hardly ever used). +```C +s32 func_80C10558(GlobalContext *globalCtx, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, Actor *thisx) { + EnRecepgirl* this = THIS; + + if (limbIndex == 5) { + rot->x += this->unk_2AE.y; + } + return false; +} +``` + +As for the UnkActorDraw, it has a much simpler prototype. mips2c gives +```C +void func_80C10590(GlobalContext *globalCtx, s32 limbIndex, Actor *actor) { + if (limbIndex == 5) { + Matrix_RotateY((s16) (0x400 - actor->unk2AE), 1); + Matrix_GetStateTranslationAndScaledX(500.0f, (Vec3f *) &actor->focus); + } +} +``` +There is only minor cleanup needed here: +- recasting the last argument, +- replacing the last argument of `Matrix_RotateY` by the enum `MTXMODE_APPLY` (which means "use the current matrix instead of starting from a new identity matrix"), and the first argument by `0x400 - this->unk_2AE.x`. +- `(Vec3f *) &actor->focus` to `&actor->focus.pos` (this is the same issue as `(Actor*)this`, where mips2c doesn't climb deep enough into the struct). +```C +void func_80C10590(GlobalContext *globalCtx, s32 limbIndex, Actor *thisx) { + EnRecepgirl* this = THIS; + + if (limbIndex == 5) { + Matrix_RotateY(0x400 - this->unk_2AE.x, MTXMODE_APPLY); + Matrix_GetStateTranslationAndScaledX(500.0f, &this->actor.focus.pos); + } +} +``` + +## Some more examples: ObjTree + +Since EnRecepgirl was a bit light on graphics macros, we will look at an example that has a few more. A nice simple one is `ObjTree_Draw`: the original mips2c output is +```C +void ObjTree_Draw(Actor *thisx, GlobalContext *globalCtx) { + s16 sp36; + s16 sp34; + Gfx *sp28; + Gfx *sp20; + Gfx *temp_v0; + Gfx *temp_v0_2; + Gfx *temp_v0_3; + Gfx *temp_v0_4; + GraphicsContext *temp_a0; + GraphicsContext *temp_s0; + + sp36 = (s16) (s32) (f32) thisx->shape.rot.x; + sp34 = (s16) (s32) (f32) thisx->shape.rot.z; + temp_a0 = globalCtx->state.gfxCtx; + temp_s0 = temp_a0; + func_8012C28C(temp_a0); + temp_v0 = temp_s0->polyOpa.p; + temp_s0->polyOpa.p = temp_v0 + 8; + temp_v0->words.w0 = 0xDA380003; + sp28 = temp_v0; + sp28->words.w1 = Matrix_NewMtx(globalCtx->state.gfxCtx); + temp_v0_2 = temp_s0->polyOpa.p; + temp_s0->polyOpa.p = temp_v0_2 + 8; + temp_v0_2->words.w1 = (u32) &D_06000680; + temp_v0_2->words.w0 = 0xDE000000; + Matrix_InsertRotation(sp36, 0, sp34, 1); + temp_v0_3 = temp_s0->polyOpa.p; + temp_s0->polyOpa.p = temp_v0_3 + 8; + temp_v0_3->words.w0 = 0xDA380003; + sp20 = temp_v0_3; + sp20->words.w1 = Matrix_NewMtx(globalCtx->state.gfxCtx); + temp_v0_4 = temp_s0->polyOpa.p; + temp_s0->polyOpa.p = temp_v0_4 + 8; + temp_v0_4->words.w1 = (u32) &D_060007C8; + temp_v0_4->words.w0 = 0xDE000000; +} +``` +We can see there are four blocks here, although only two different macros: +```C + temp_v0 = temp_s0->polyOpa.p; + temp_s0->polyOpa.p = temp_v0 + 8; + temp_v0->words.w0 = 0xDA380003; + sp28 = temp_v0; + sp28->words.w1 = Matrix_NewMtx(globalCtx->state.gfxCtx); +``` +gfxdis gives +``` +$ gfxdis.f3dex2 -x -g POLY_OPA_DISP++ -d DA38000312345678 +gSPMatrix(POLY_OPA_DISP++, 0x12345678, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); +``` +so it becomes +```C +gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); +``` + +```C + temp_v0_2 = temp_s0->polyOpa.p; + temp_s0->polyOpa.p = temp_v0_2 + 8; + temp_v0_2->words.w1 = (u32) &D_06000680; + temp_v0_2->words.w0 = 0xDE000000; +``` +``` +$ gfxdis.f3dex2 -x -g POLY_OPA_DISP++ -d DE00000012345678 +gSPDisplayList(POLY_OPA_DISP++, 0x12345678); +``` +so this one is +```C +gSPDisplayList(POLY_OPA_DISP++, D_06000680); +``` + +```C + temp_v0_3 = temp_s0->polyOpa.p; + temp_s0->polyOpa.p = temp_v0_3 + 8; + temp_v0_3->words.w0 = 0xDA380003; + sp20 = temp_v0_3; + sp20->words.w1 = Matrix_NewMtx(globalCtx->state.gfxCtx); +``` +This is the same as the first one. Indeed, it's identical. +```C + temp_v0_4 = temp_s0->polyOpa.p; + temp_s0->polyOpa.p = temp_v0_4 + 8; + temp_v0_4->words.w1 = (u32) &D_060007C8; + temp_v0_4->words.w0 = 0xDE000000; +``` +This is the same as the second one, but with a different second word. + +Tidying up and inserting `OPEN_DISPS` and `CLOSE_DISPS`, we end up with +```C +void ObjTree_Draw(Actor* thisx, GlobalContext* globalCtx) { + s16 sp36 = (f32) thisx->shape.rot.x; + s16 sp34 = (f32) thisx->shape.rot.z; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, D_06000680); + + Matrix_InsertRotation(sp36, 0, sp34, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, D_060007C8); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} +``` + +## RGB macros and bitpacking + +TODO: find some examples for this one. + +For even more examples, you can consult [the OoT tutorial](https://github.com/zeldaret/oot/blob/master/docs/tutorial/draw_functions.md) + +Next: [Data](data.md) diff --git a/docs/tutorial/images/EnRecepgirl_Init_diff_matching.png b/docs/tutorial/images/EnRecepgirl_Init_diff_matching.png new file mode 100644 index 000000000..9fc473019 Binary files /dev/null and b/docs/tutorial/images/EnRecepgirl_Init_diff_matching.png differ diff --git a/docs/tutorial/images/EnRecepgirl_stack_diff.png b/docs/tutorial/images/EnRecepgirl_stack_diff.png new file mode 100644 index 000000000..c5de5f366 Binary files /dev/null and b/docs/tutorial/images/EnRecepgirl_stack_diff.png differ diff --git a/docs/tutorial/images/En_Recepgirl.gv.png b/docs/tutorial/images/En_Recepgirl.gv.png new file mode 100644 index 000000000..fe3040869 Binary files /dev/null and b/docs/tutorial/images/En_Recepgirl.gv.png differ diff --git a/docs/tutorial/images/fresh_actor_data.png b/docs/tutorial/images/fresh_actor_data.png new file mode 100644 index 000000000..c887ce451 Binary files /dev/null and b/docs/tutorial/images/fresh_actor_data.png differ diff --git a/docs/tutorial/images/func_80C100DC_diff1.png b/docs/tutorial/images/func_80C100DC_diff1.png new file mode 100644 index 000000000..1f899b1b5 Binary files /dev/null and b/docs/tutorial/images/func_80C100DC_diff1.png differ diff --git a/docs/tutorial/images/func_80C100DC_diff2.png b/docs/tutorial/images/func_80C100DC_diff2.png new file mode 100644 index 000000000..db4404d8f Binary files /dev/null and b/docs/tutorial/images/func_80C100DC_diff2.png differ diff --git a/docs/tutorial/images/func_80C100DC_diff3.png b/docs/tutorial/images/func_80C100DC_diff3.png new file mode 100644 index 000000000..b0d25c693 Binary files /dev/null and b/docs/tutorial/images/func_80C100DC_diff3.png differ diff --git a/docs/tutorial/images/func_80C102D4_diff1.png b/docs/tutorial/images/func_80C102D4_diff1.png new file mode 100644 index 000000000..2b4147999 Binary files /dev/null and b/docs/tutorial/images/func_80C102D4_diff1.png differ diff --git a/docs/tutorial/images/func_80C102D4_diff2.png b/docs/tutorial/images/func_80C102D4_diff2.png new file mode 100644 index 000000000..0fefcb43c Binary files /dev/null and b/docs/tutorial/images/func_80C102D4_diff2.png differ diff --git a/docs/tutorial/images/z64utils_main.png b/docs/tutorial/images/z64utils_main.png new file mode 100644 index 000000000..972c9c4a5 Binary files /dev/null and b/docs/tutorial/images/z64utils_main.png differ diff --git a/docs/tutorial/images/z64utils_object_analyzed.png b/docs/tutorial/images/z64utils_object_analyzed.png new file mode 100644 index 000000000..9a2de8dac Binary files /dev/null and b/docs/tutorial/images/z64utils_object_analyzed.png differ diff --git a/docs/tutorial/images/z64utils_object_analyzer.png b/docs/tutorial/images/z64utils_object_analyzer.png new file mode 100644 index 000000000..7a6adec3d Binary files /dev/null and b/docs/tutorial/images/z64utils_object_analyzer.png differ diff --git a/docs/tutorial/images/z64utils_skeleton_error.png b/docs/tutorial/images/z64utils_skeleton_error.png new file mode 100644 index 000000000..821ff69f6 Binary files /dev/null and b/docs/tutorial/images/z64utils_skeleton_error.png differ diff --git a/docs/tutorial/images/z64utils_skeleton_head.png b/docs/tutorial/images/z64utils_skeleton_head.png new file mode 100644 index 000000000..263f06642 Binary files /dev/null and b/docs/tutorial/images/z64utils_skeleton_head.png differ diff --git a/docs/tutorial/introduction.md b/docs/tutorial/introduction.md new file mode 100644 index 000000000..4e2d8324d --- /dev/null +++ b/docs/tutorial/introduction.md @@ -0,0 +1,87 @@ +# Introduction + +In this project, we are decompiling The Legend of Zelda: Majora's Mask. This means that we take the assembly language that is on the cartridge, + +``` +glabel func_809529AC +/* 00038C 809529AC 27BDFFE0 */ addiu $sp, $sp, -0x20 +/* 000390 809529B0 AFBF001C */ sw $ra, 0x1c($sp) +/* 000394 809529B4 AFA40020 */ sw $a0, 0x20($sp) +/* 000398 809529B8 0C02E27E */ jal Actor_HasParent +/* 00039C 809529BC AFA50024 */ sw $a1, 0x24($sp) +/* 0003A0 809529C0 8FA40020 */ lw $a0, 0x20($sp) +/* 0003A4 809529C4 1040000C */ beqz $v0, .L809529F8 +/* 0003A8 809529C8 8FA50024 */ lw $a1, 0x24($sp) +/* 0003AC 809529CC A4800116 */ sh $zero, 0x116($a0) +/* 0003B0 809529D0 8C860098 */ lw $a2, 0x98($a0) +/* 0003B4 809529D4 8C87009C */ lw $a3, 0x9c($a0) +/* 0003B8 809529D8 AFA40020 */ sw $a0, 0x20($sp) +/* 0003BC 809529DC 0C02E140 */ jal func_800B8500 +/* 0003C0 809529E0 AFA00010 */ sw $zero, 0x10($sp) +/* 0003C4 809529E4 8FA40020 */ lw $a0, 0x20($sp) +/* 0003C8 809529E8 3C0E8095 */ lui $t6, %hi(func_80952A1C) +/* 0003CC 809529EC 25CE2A1C */ addiu $t6, $t6, %lo(func_80952A1C) +/* 0003D0 809529F0 10000006 */ b .L80952A0C +/* 0003D4 809529F4 AC8E01F4 */ sw $t6, 0x1f4($a0) +.L809529F8: +/* 0003D8 809529F8 C484009C */ lwc1 $f4, 0x9c($a0) +/* 0003DC 809529FC 8C870098 */ lw $a3, 0x98($a0) +/* 0003E0 80952A00 24060035 */ addiu $a2, $zero, 0x35 +/* 0003E4 80952A04 0C02E287 */ jal func_800B8A1C +/* 0003E8 80952A08 E7A40010 */ swc1 $f4, 0x10($sp) +.L80952A0C: +/* 0003EC 80952A0C 8FBF001C */ lw $ra, 0x1c($sp) +/* 0003F0 80952A10 27BD0020 */ addiu $sp, $sp, 0x20 +/* 0003F4 80952A14 03E00008 */ jr $ra +/* 0003F8 80952A18 00000000 */ nop +``` + +(the commented numbers on the left are the original machine code, the middle the translation into MIPS assembly, the right useful information about the numbers in the code) +and turn it into compilable C code: + +```C +void func_809529AC(EnMs *this, GlobalContext *globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.textId = 0; + func_800B8500(&this->actor, globalCtx, this->actor.xzDistToPlayer, this->actor.playerHeightRel, 0); + this->actionFunc = func_80952A1C; + } else { + func_800B8A1C(&this->actor, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + } +} +``` + +which is intended to be as close to the original code as we can get just by looking at the assembly. We are doing *matching* decomp: in the right context, and with the right compiler settings, the above C compiles into *precisely* the assembly code above, not just equivalent code. + +N.B. We are using only publicly available code. In particular, we are not looking at any of the recent Nintendo source code leaks. + +Progress of the project can be found at [https://zelda64.dev]. The long-term goal of this project is to obtain a complete compilable version of the code for every publicly released version of Majora's Mask (in the same way as the Ocarina of Time project and many other Zelda games). *We are not working on a PC Port, and neither this project nor the ZeldaRET organisation will not be making one*, although the resulting code will be very useful if someone does intend to make such a port. + +Most of the discussion on the project takes place on the Zelda Decompilation Discord (linked in the [README.md](../../README.md)). We are very welcoming to newcomers and are happy to help you with any problems you might have with the decompilation process. + +## What do I need to know to take part? + +Basic knowledge of C, particularly arrays and pointers, is extremely useful. Knowledge of MIPS is not required initially, but if you are serious about decompilation you will soon pick up a lot of it. + +Knowledge of the fundamentals of git and GitHub is required. There are a number of tutorials available online, and a later document in this tutorial describes how you contribute to this project outside the actual decompilation process. + +The most useful knowledge to have is a general understanding of how the game works. An afternoon of constructive mucking about in the [Practice Rom](https://kz.zeldacodes.org/) (aka KZ) will be very beneficial if you have not looked at the game's subsurface workings before. + +## Structure of the code + +A lot of work has already been done on the code to bring it into a format that is easy to decompile. I will discuss actors, since this is where the majority of new people should begin. + +An *actor* is any thing in the game that moves or performs actions or interactions: Link is an actor, enemies are actors, NPCs are actors, props like grass are actors. The vast majority of actors are *overlays*, which means they are loaded only when the game needs them. + +In the code, each actor is associated to several files: there is +- the main .c file, e.g. `src/overlays/actors/ovl_En_Ms/z_en_ms.c` +- the actor's Header file, e.g. `src/overlays/actors/ovl_En_Ms/z_en_ms.h` +- various .o files that tell the `make` script how to incorporate it into building the ROM, + +and then for undecompiled actors, various assembly (.s) files, generally including: +- one for the actor's *data* (this usually includes things like its collision information about how to draw it, and various other stuff that is used in it), e.g. `data/overlays/actors/ovl_En_Ms.data.s` +- one for each function in the actor, e.g. `asm/non_matchings/overlays/actors/ovl_En_Ms/func_809529AC.s` + +(In this project, all assembly code and asset files are extracted from a user-provided ROM: if you look in the GitHub repository, you will see that only decompiled source code is present.) + +The basic process of decomp is to take one or more of the .s files, run it through a decompilation program (mips_to_c) that reads the ASM very literally, and then, through human ingenuity, reshape it into code that not only compiles in the first place, but completely matches the assembly generation of the original code (well-written or otherwise; it's also very likely that our constructed code differs significantly from the original, even if it still compiles to the same thing). diff --git a/docs/tutorial/merging.md b/docs/tutorial/merging.md new file mode 100644 index 000000000..1d8c6ad1c --- /dev/null +++ b/docs/tutorial/merging.md @@ -0,0 +1,97 @@ +# The merging process + +Up: [Contents](contents.md) +Previous: [Documenting](documenting.md) + + +## Preparing to PR + +### Change the `spec` + +Specifically, to use the automatically generated reloc, rather than the original. In the case of an entirely matched actor, you find the section relating to the actor that you edited before: + +``` +beginseg + name "ovl_En_Recepgirl" + include "build/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.o" + //include "build/data/overlays/actors/ovl_En_Recepgirl.data.o" + include "build/data/overlays/actors/ovl_En_Recepgirl.reloc.o" +endseg +``` + +and change to use our reloc: + +``` +beginseg + name "ovl_En_Recepgirl" + include "build/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.o" + include "build/src/overlays/actors/ovl_En_Recepgirl/ovl_En_Recepgirl_reloc.o" +endseg +``` + +(copy the path, then copy the directory name and put `_reloc.o` after it). + +### Non-matchings + +If you can't match a function even with everyone's help in the `mm-decomp-help` discord channel, don't worry overlong about it. Hopefully you can get it to do the same thing as the original (non-matching), and then you set it up to use the original asm for the matching build, and your code for the non-matching. This looks like + +```c +#ifdef NON_MATCHING +// Helpful comment about the nature of the nonmatching +void function() { + // ... +} +#else +#pragma GLOBAL_ASM(asm/.../function.s) +#endif +``` + +in the C file. Also, due to the way `GLOBAL_ASM` works, we also cannot use generated reloc for overlays with nonmatchings, so we have to do the same thing for the reloc file in the spec: + +``` +beginseg + name "ovl_En_Recepgirl" + compress + include "build/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_En_Recepgirl/ovl_En_Recepgirl_reloc.o" +#else + include "build/data/overlays/actors/ovl_En_Recepgirl.reloc.o" +#endif +endseg +``` + +Ideally you should at least be able to get a function to have equivalent behaviour; if not, and you have exhausted all other avenues of getting help, it should be marked in the C file as `NON_EQUIVALENT`, in the same way as a nonmatching. We do not change the spec for non-equivalents: they are treated the same as undecompiled code from a building perspective, lest they break things. + +### Format + +Run the formatting script `format.sh`, to format the C files in the standard way we use. If you have some arrays or struct definitions in your file, check that they have not been obnoxiously padded out: you can usually get a better format without a final comma for short things. + +**N.B.** this is now essential: the CI will fail immediately if it detects files that change when formatted. + +### Merge master + +To make sure the PR builds correctly with the current master, you need to merge `upstream/master` before you make the PR. This tends to break things, that you have to fix to get it to compile correctly again. + + +## Pull Requests + +Push commits to your fork of the repository on GitHub, and then open a pull request. Name the PR something sensible, like + +- `EnRecepgirl OK and documented` (if all the functions match and your documentation is fairly complete) +- `EnRecepgirl OK` (if all the functions match) +- `EnRecepgirl (n nonmatching)` (if you couldn't get one or more functions to match, but to the best of your knowledge they are equivalent code) +- `EnRecepgirl (n nonequivalent)` (if you couldn't get one or more functions to match, and do not believe the code in them has the same effect) + +and so on, although these four tend to cover most cases. Feel free to add a comment describing anything interesting you had to do or issues in non-matchings. + +Please also update the status of the file on Trello/the spreadsheet. + + +### Reviews + +Pull requests may be reviewed by anyone (who knows enough about the conventions of the project), and all must be reviewed and approved by two leads and one extra contributor. + +To implement suggestions made in reviews, it is generally easier to be consistent if you push more commits from your local branch. It is also quite possible that in the meantime some other PR has gone in, and git will ask you to merge master before you add more commits. This is normally fairly painless, although often you have to resolve merge conflicts. If in doubt, backup your work before doing anything, and ask in Discord before doing anything drastic, or if you don't understand what git is telling you. + +There is no need to wait for your PR to be approved and committed before working on your next file. diff --git a/docs/tutorial/object_decomp.md b/docs/tutorial/object_decomp.md new file mode 100644 index 000000000..88fe89eca --- /dev/null +++ b/docs/tutorial/object_decomp.md @@ -0,0 +1,14 @@ +# Analysing object files + +Up: [Contents](contents.md) +Previous: [Documenting](documenting.md) + +TODO: To be written once automated objects are present. + +## Useful tools + +We are very fortunate that several nice tools have been written recently that are excellent for documenting asset files: +- [Z64Utils](https://github.com/Random06457/Z64Utils/releases), for looking at displaylists, textures they reference, the skeleton, animations, etc. +- [Texture64](https://github.com/queueRAM/Texture64/releases), for looking at textures in all the common N64 formats (needed since Z64Utils cannot interpret textures not explicitly referenced in displaylists currently) + +Next: [The merging process](merging.md) \ No newline at end of file diff --git a/docs/tutorial/other_functions.md b/docs/tutorial/other_functions.md new file mode 100644 index 000000000..bdc49036d --- /dev/null +++ b/docs/tutorial/other_functions.md @@ -0,0 +1,605 @@ +# The rest of the functions in the actor + +Up: [Contents](contents.md) +Previous: [Beginning decompilation: the Init function and the Actor struct](beginning_decomp.md) + +## Now what? + +At this point we have a choice to make. Either we could follow the main function flow and decompile `func_80C10148`, or take a look at `Destroy`, which for smaller actors can often be done straight after Init, since it usually just removes colliders and deallocates dynapoly. + +## Destroy + +Destroy will be a dead end, but we might as well do it now. Usually we would regenerate the context first and apply it to mips2c as with `Init`, but if we look at the assembly... +```mips +glabel EnRecepgirl_Destroy +/* 0000FC 80C100CC AFA40000 */ sw $a0, ($sp) +/* 000100 80C100D0 AFA50004 */ sw $a1, 4($sp) +/* 000104 80C100D4 03E00008 */ jr $ra +/* 000108 80C100D8 00000000 */ nop +``` +It doesn't seem to do anything. Indeed, chucking it in mips2c, +``` +$ ../mips_to_c/mips_to_c.py asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Destroy.s +void EnRecepgirl_Destroy(s32 arg0, ? arg1) { + +} +``` +so it really does do nothing. It is worth staying on this briefly to understand what is is doing, though. Even with no context, mips2c knows it takes two arguments because it does two saves onto the stack: the calling convention the N64 uses requires the first four arguments be saved from the registers onto the stack, since the registers are expected to be cleared when a function call happens. It's done a bad job of guessing what they are, but that's to be expected: the assembly only tells us they're words. Thankfully we already know in this case, so we can just replace the `GLOBAL_ASM` by +```C +void EnRecepgirl_Destroy(Actor* thisx, GlobalContext* globalCtx) { + +} +``` +and cross this function off. + +## `func_80C10148` + +We don't really have a choice now, we have to look at this function. Remake the context (no need to change the function type this time), and run mips2c on the function's assembly file: +``` +$ ../mips_to_c/mips_to_c.py asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10148.s data/ovl_En_Recepgirl/ovl_En_Recepgirl.data.s --context ctx.c +extern AnimationHeader D_0600AD98; +extern ? func_80C1019C; + +void func_80C10148(EnRecepgirl *this) { + SkelAnime *temp_a0; + + temp_a0 = &this->skelAnime; + if (&D_06001384 == this->skelAnime.animation) { + this = this; + Animation_MorphToPlayOnce(temp_a0, &D_0600AD98, 5.0f); + } + this->actionFunc = &func_80C1019C; +} +``` + +This gives us some information immediately: `D_0600AD98` is an `AnimationHeader`, and `func_80C1019C` is set as the action function. This means that we know its type, even though mips2c does not: looking in the header, we see the typedef is +```C +typedef void (*EnRecepgirlActionFunc)(struct EnRecepgirl*, GlobalContext*); +``` +and so we prototype `func_80C1019C` as +```C +void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx); +``` +at the top (were it above the function we're currently working on, the prototype could eventually be replaced by the function definition itself, but since it isn't, it goes at the top with the others). + +There are several rather odd things going on here: +- `temp_a0` is only used once. As such it's probably fake. +- There's a weird `this = this` that does nothing +- `if (&D_06001384 == this->skelAnime.animation)` is a bit of a funny way to write the condition: it seems more likely it would be the other way round. +- Also, if we look up `animation`, we find it is an `AnimationHeader*`, so `D_06001384` can be externed as `AnimationHeader`. +- `func_80C1019C` is already a pointer, so the `&` is ineffectual. Our style is to not use `&` on function pointers. + +If we tackle these, we end up with +```C + +void func_80C10148(EnRecepgirl* this); +void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx); + +[...] + +extern AnimationHeader D_06001384; +extern AnimationHeader D_06009890; +extern UNK_TYPE D_0600A280; +extern AnimationHeader D_0600AD98; +extern FlexSkeletonHeader D_06011B60; + +[...] + +void func_80C10148(EnRecepgirl *this) { + if (this->skelAnime.animation == &D_06001384) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 5.0f); + } + this->actionFunc = func_80C1019C; +} +``` +This is a common type of function called a setup (action) function. It runs once and prepares the ground for its corresponding actionfunction to run, whereas the actionfunction is usually run every frame by `Update` (but more on that later). Running `make`, we get OK again. + +Again we have only one way to go + + +## `func_80C1019C` + +Remake the context and run mips2c on this function's assembly file. We get +```C +? func_80C10290(EnRecepgirl *); // extern + +void func_80C1019C(EnRecepgirl *this, GlobalContext *globalCtx) { + SkelAnime *sp24; + SkelAnime *temp_a0; + + temp_a0 = &this->skelAnime; + sp24 = temp_a0; + if (SkelAnime_Update(temp_a0) != 0) { + if (&D_0600A280 == this->skelAnime.animation) { + Animation_MorphToPlayOnce(temp_a0, &D_0600AD98, 5.0f); + } else { + Animation_ChangeTransitionRepeat(temp_a0, &D_06009890, -4.0f); + } + } + if (func_800B84D0((Actor *) this, globalCtx) != 0) { + func_80C10290(this); + return; + } + if (Actor_IsActorFacingLink((Actor *) this, 0x2000) != 0) { + func_800B8614((Actor *) this, globalCtx, 60.0f); + if (Player_GetMask(globalCtx) == 2) { + this->actor.textId = 0x2367; + return; + } + if (Flags_GetSwitch(globalCtx, (s32) this->actor.params) != 0) { + this->actor.textId = 0x2ADC; + return; + } + this->actor.textId = 0x2AD9; + // Duplicate return node #12. Try simplifying control flow for better match + } +} +``` +This is a bit juicier! We can do some preliminary cleanup, then worry about the control flow. +- `sp24` does nothing, so is almost certainly fake. +- `temp_a0` is used in 3 different places, but they're all right next to one another and are unlikely to be required since there's no nontrivial calculation or anything happening. Let's remove it too and see what happens. +- We've got another reversed comparison, `&D_0600A280 == this->skelAnime.animation`. +- `D_0600A280` is an `AnimationHeader`. +- `(Actor *) this` should be replaced by `&this->actor`. +- `Flags_GetSwitch is a boolean and we don't need to cast the argument, as we have discussed before. (We don't know about the other functions in the conditions, so leave them for now.) +- Prototype `func_80C10290`: it is reasonable to guess it's another setup function, so `void func_80C10290(EnRecepgirl* this);`. + +Changing all these, we end up with +```C +void func_80C10148(EnRecepgirl* this); +void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx); +void func_80C10290(EnRecepgirl* this); + +[...] + +extern AnimationHeader D_06001384; +extern AnimationHeader D_06009890; +extern AnimationHeader D_0600A280; +extern AnimationHeader D_0600AD98; +extern FlexSkeletonHeader D_06011B60; + +[...] + +void func_80C1019C(EnRecepgirl *this, GlobalContext *globalCtx) { + if (SkelAnime_Update(&this->skelAnime) != 0) { + if (&D_0600A280 == this->skelAnime.animation) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 5.0f); + } else { + Animation_ChangeTransitionRepeat(&this->skelAnime, &D_06009890, -4.0f); + } + } + if (func_800B84D0(&this->actor, globalCtx) != 0) { + func_80C10290(this); + return; + } + if (Actor_IsActorFacingLink(&this->actor, 0x2000) != 0) { + func_800B8614(&this->actor, globalCtx, 60.0f); + if (Player_GetMask(globalCtx) == 2) { + this->actor.textId = 0x2367; + return; + } + if (Flags_GetSwitch(globalCtx, this->actor.params)) { + this->actor.textId = 0x2ADC; + return; + } + this->actor.textId = 0x2AD9; + // Duplicate return node #12. Try simplifying control flow for better match + } +} +``` +If we look with diff.py, we find this matches. But we can replace some of the `return`s by `else`s: generally, we use elses unless +- After an `Actor_Kill` +- Sometimes after setting an actionfunction +- There's no way to avoid an early return + +Here, it's debatable whether to keep the first, since `func_80C10290` is likely a setup function. The latter two should be changed to elses, though. For now, let's replace all of them. This leaves us with +```C +void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime) != 0) { + if (this->skelAnime.animation == &D_0600A280) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 5.0f); + } else { + Animation_ChangeTransitionRepeat(&this->skelAnime, &D_06009890, -4.0f); + } + } + + if (func_800B84D0(&this->actor, globalCtx) != 0) { + func_80C10290(this); + } else if (Actor_IsActorFacingLink(&this->actor, 0x2000)) { + func_800B8614(&this->actor, globalCtx, 60.0f); + if (Player_GetMask(globalCtx) == 2) { + this->actor.textId = 0x2367; + } else if (Flags_GetSwitch(globalCtx, this->actor.params)) { + this->actor.textId = 0x2ADC; + } else { + this->actor.textId = 0x2AD9; + } + } +} +``` +which still matches. Lastly, we have an enum for the output of `Player_GetMask` and other mask-related things: in `z64player.h` we find +```C +typedef enum { + /* 0x00 */ PLAYER_MASK_NONE, + /* 0x01 */ PLAYER_MASK_MASK_OF_TRUTH, + /* 0x02 */ PLAYER_MASK_KAFEIS_MASK, +[...] + /* 0x19 */ PLAYER_MASK_MAX +} PlayerMask; +``` +and so we can write the last if as `Player_GetMask(globalCtx) == PLAYER_MASK_KAFEIS_MASK`. + +Again, we have no choice in what to do next. + + +## `func_80C10290` + +Remaking the context and running mips2c gives +```C +void func_80C102D4(EnRecepgirl *, GlobalContext *); // extern + +void func_80C10290(EnRecepgirl *this) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600A280, -4.0f); + this->actionFunc = func_80C102D4; +} +``` +so all we have to do is add the function prototype for the newest action function. Not surprisingly, this matches without changing anything. + + +## `func_80C102D4` + +
+ +Large code block, click to show + + +```C +extern AnimationHeader D_06000968; + +void func_80C102D4(EnRecepgirl *this, GlobalContext *globalCtx) { + SkelAnime *sp20; + AnimationHeader *temp_v0; + SkelAnime *temp_a0; + u16 temp_v0_3; + u16 temp_v0_4; + u8 temp_v0_2; + + temp_a0 = &this->skelAnime; + sp20 = temp_a0; + if (SkelAnime_Update(temp_a0) != 0) { + temp_v0 = this->skelAnime.animation; + if (&D_0600A280 == temp_v0) { + Animation_ChangeDefaultRepeat(sp20, &D_06001384); + } else if (&D_0600AD98 == temp_v0) { + if (this->actor.textId == 0x2ADA) { + Animation_MorphToPlayOnce(sp20, &D_06000968, 10.0f); + } else { + Animation_ChangeTransitionRepeat(sp20, &D_06009890, 10.0f); + } + } else if (this->actor.textId == 0x2ADA) { + Animation_ChangeTransitionRepeat(sp20, &D_06009890, 10.0f); + } else { + Animation_MorphToPlayOnce(sp20, &D_0600A280, -4.0f); + } + } + temp_v0_2 = func_80152498(&globalCtx->msgCtx); + if (temp_v0_2 == 2) { + this->actor.textId = 0x2ADC; + func_80C10148(this); + return; + } + if (((temp_v0_2 & 0xFF) == 5) && (func_80147624(globalCtx) != 0)) { + temp_v0_3 = this->actor.textId; + if (temp_v0_3 == 0x2AD9) { + Actor_SetSwitchFlag(globalCtx, (s32) this->actor.params); + Animation_MorphToPlayOnce(sp20, &D_0600AD98, 10.0f); + if ((*(&gSaveContext + 0xF37) & 0x80) != 0) { + this->actor.textId = 0x2ADF; + } else { + this->actor.textId = 0x2ADA; + } + } else if (temp_v0_3 == 0x2ADC) { + Animation_MorphToPlayOnce(sp20, &D_0600AD98, 10.0f); + this->actor.textId = 0x2ADD; + } else { + Animation_MorphToPlayOnce(sp20, &D_06000968, 10.0f); + temp_v0_4 = this->actor.textId; + if (temp_v0_4 == 0x2ADD) { + this->actor.textId = 0x2ADE; + } else if (temp_v0_4 == 0x2ADA) { + this->actor.textId = 0x2ADB; + } else { + this->actor.textId = 0x2AE0; + } + } + func_80151938(globalCtx, this->actor.textId); + } +} +``` + +
+ +Well, this is a big one! We get one more extern, for `D_06000968`. A lot of the temps used in the conditionals look fake, with the exception of `temp_v0_2`: because the function is only called once but the temp is used twice, the temp must be real. Removing the others and switching the `animation` conditionals, +```C +void func_80C102D4(EnRecepgirl *this, GlobalContext *globalCtx) { + u8 temp_v0_2; + + if (SkelAnime_Update(&this->skelAnime) != 0) { + if (this->skelAnime.animation == &D_0600A280) { + Animation_ChangeDefaultRepeat(&this->skelAnime, &D_06001384); + } else if (this->skelAnime.animation == &D_0600AD98) { + if (this->actor.textId == 0x2ADA) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_06000968, 10.0f); + } else { + Animation_ChangeTransitionRepeat(&this->skelAnime, &D_06009890, 10.0f); + } + } else if (this->actor.textId == 0x2ADA) { + Animation_ChangeTransitionRepeat(&this->skelAnime, &D_06009890, 10.0f); + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600A280, -4.0f); + } + } + + temp_v0_2 = func_80152498(&globalCtx->msgCtx); + if (temp_v0_2 == 2) { + this->actor.textId = 0x2ADC; + func_80C10148(this); + return; + } + + if (((temp_v0_2 & 0xFF) == 5) && (func_80147624(globalCtx) != 0)) { + if (this->actor.textId == 0x2AD9) { + Actor_SetSwitchFlag(globalCtx, this->actor.params); + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 10.0f); + if ((*(&gSaveContext + 0xF37) & 0x80) != 0) { + this->actor.textId = 0x2ADF; + } else { + this->actor.textId = 0x2ADA; + } + } else if (this->actor.textId == 0x2ADC) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 10.0f); + this->actor.textId = 0x2ADD; + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &D_06000968, 10.0f); + if (this->actor.textId == 0x2ADD) { + this->actor.textId = 0x2ADE; + } else if (this->actor.textId == 0x2ADA) { + this->actor.textId = 0x2ADB; + } else { + this->actor.textId = 0x2AE0; + } + } + func_80151938(globalCtx, this->actor.textId); + } +} +``` +There remains one thing we need to fix before trying to compile it, namely `*(&gSaveContext + 0xF37) & 0x80`. This is really a funny way of writing an array access, because mips2c will get confused about arrays in structs. Opening up `z64save.h`, we find in the `SaveContext` struct that +```C + /* 0x0EF8 */ u8 weekEventReg[100]; // "week_event_reg" + /* 0x0F5C */ u32 mapsVisited; // "area_arrival" +``` +so it's somewhere in `weekEventReg`. `0xF37 - 0xEF8 = 0x3F = 63`, and it's a byte array, so the access is actually `gSaveContext.weekEventReg[63] & 0x80`. Now it will compile. We also don't use `!= 0` for flag comparisons: just `if (gSaveContext.weekEventReg[63] & 0x80)` will do. + +Running `./diff.py -mwo3 func_80C102D4` and scrolling down, we discover that this doesn't match! + +![First run of diff.py on func_80C102D4](images/func_80C102D4_diff1.png) + +The yellow shows registers that don't match, the different colours on the registers help you to estimate where the problems are. Usually it's best to start at the top and work down if possible: any regalloc problems at the top tend to propagate most of the way down. In our case, the first problem is +``` +3f0: andi t0,v0,0xff r 153 3f0: andi t1,v0,0xff +``` +somehow we skipped over `t0`. Where is this in the code? The `153` in the middle is the line number in the C file (the `3f0`s are the offsets into the assembly file), we have `--source` if you want to see the code explicitly, or you can do it the old-fashioned way, and work it out from nearby function calls. In this case, `func_80C10148` is run straight after, and the only place that is called is +```C + temp_v0_2 = func_80152498(&globalCtx->msgCtx); + if (temp_v0_2 == 2) { + this->actor.textId = 0x2ADC; + func_80C10148(this); + return; + } + + if (((temp_v0_2 & 0xFF) == 5) && (func_80147624(globalCtx) != 0)) { +``` + +If you look at the conditionals and the declaration of `temp_v0_2`, you may notice something odd: `temp_v0_2` is a `u8`. Therefore the `& 0xFF` does nothing! It's surprisingly common for this to happen, be it leaving out a `& 0xFF` or adding an extraneous one. If we remove it, we get a match: + +![func_80C102D4 now matching](images/func_80C102D4_diff2.png) + +Notice that indeed the subsequent regalloc, which might have looked like a bigger problem than the initial part, was also fixed: skipping a register in one place will throw the registers off below too. + +And now we've run out of functions. Time for `Update`. + + +## Update + +Update runs every frame and usually is responsible for the actor's common logic updates: for example, updating timers, blinking, updating collision, running the `actionFunc`, and so on, either directly or through other functions it calls. A lot of subsidiary functions that are not common to every state (e.g. updating position, or the text when talking, etc.) are carried out by one of the action functions we have already decomped. + +Remake the context and run mips2c: +```C +? func_80C100DC(EnRecepgirl *); // extern + +void EnRecepgirl_Update(Actor *thisx, GlobalContext *globalCtx) { + EnRecepgirl* this = (EnRecepgirl *) thisx; + ? sp30; + + this->actionFunc(this, globalCtx); + func_800E9250(globalCtx, (Actor *) this, this + 0x2AE, (Vec3s *) &sp30, (bitwise Vec3f) this->actor.focus.pos.x, this->actor.focus.pos.y, this->actor.focus.pos.z); + func_80C100DC(this); +} +``` +If we search for `func_80C100DC`, we find that this is the only time it is used. Hence we can be almost certain that its prototype is `void func_80C100DC(EnRecepgirl* this);`. This function occurs above `Update`, so you can put the prototype next to the `GLOBAL_ASM` and remove it when we decompile that function. + +Change the function and the prototype back to `Actor* thisx`, and add the casting temp: +```C +void func_80C100DC(EnRecepgirl *); +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C100DC.s") + +[...] + +void EnRecepgirl_Update(Actor *thisx, GlobalContext *globalCtx) { + EnRecepgirl* this = THIS; + ? sp30; + + this->actionFunc(this, globalCtx); + func_800E9250(globalCtx, &this->actor, this + 0x2AE, (Vec3s *) &sp30, (bitwise Vec3f) this->actor.focus.pos.x, this->actor.focus.pos.y, this->actor.focus.pos.z); + func_80C100DC(this); +} +``` +Now, our problem is `func_800E9250`. The arguments all look terrible! Indeed, if we look at the actual function in `src/code/code_800E8EA0.c` (found by searching), we find that it should be +```C +s32 func_800E9250(GlobalContext* globalCtx, Actor* actor, Vec3s* param_3, Vec3s* param_4, Vec3f param_5) +``` +So mips2c has made a bit of a mess here: +- the third argument should be a `Vec3s`. Hence `this + 0x2AE` is a `Vec3s*`, and so `this->unk_2AE` is a `Vec3s` +- `&sp30` is a `Vec3s*`, so `sp30` is a `Vec3s` (it's clearly not used for anything, just used to "dump" a side-effect of the function) +- The last argument is supposed to be an actual `Vec3f` + +Fixing all of this, we end up with +```C +void EnRecepgirl_Update(EnRecepgirl *this, GlobalContext *globalCtx) { + EnRecepgirl* this = THIS; + Vec3s sp30; + + this->actionFunc(this, globalCtx); + func_800E9250(globalCtx, &this->actor, &this->unk_2AE, &sp30, this->actor.focus.pos); + func_80C100DC(this); +} +``` +and can fill in the top end of the struct: +```C +typedef struct EnRecepgirl { + /* 0x0000 */ Actor actor; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[24]; + /* 0x0218 */ Vec3s morphTable[24]; + /* 0x02A8 */ EnRecepgirlActionFunc actionFunc; + /* 0x02AC */ u8 unk_2AC; + /* 0x02AD */ char unk_2AD[0x1]; + /* 0x02AE */ Vec3s unk_2AE; +} EnRecepgirl; // size = 0x2B4 +``` + +It's entirely possible that `unk_2AD` is not real, and is just padding: see [Types, structs, and padding](types_structs_padding.md) for the details. We'll find out once we've finished all the functions. If we look at the diff, we find that one line is different: + +![EnRecepgirl_Update's stack difference](images/EnRecepgirl_stack_diff.png) + +So `sp30` is in the wrong place: it's `4` too high on the stack in ours. This is because the main four functions do not actually take `GlobalContext`: they really take `Gamestate` and recast it with a temp, just like `EnRecepgirl* this = THIS;`. We haven't implemented this in the repo yet, though, so for now, it suffices to put a pad on the stack where it would go instead: experience has shown when it matters, it goes above the actor recast, so we end up with +```C +void EnRecepgirl_Update(Actor *thisx, GlobalContext *globalCtx) { + s32 pad; + EnRecepgirl* this = THIS; + Vec3s sp30; + + this->actionFunc(this, globalCtx); + func_800E9250(globalCtx, &this->actor, &this->unk_2AE, &sp30, this->actor.focus.pos); + func_80C100DC(this); +} +``` +and this now matches. + +**N.B.** sometimes using an actual `GlobalContext* globalCtx` temp is required for matching: add it to your bag o' matching memes. + +### *Some remarks about the function stack + +(Feel free to skip this if you'd rather finish the actor first.) + +The (function) stack is used to store variables. It has rather more space and is somewhat less volatile than registers (it still can't be used outside a function, except by a called function accessing its arguments). The stack a function sets up for itself to use is called its *stack frame* or *function frame* (or just *function stack* or *the stack*, although strictly speaking the frame itself is not a stack, since not just the top variable is accessed), and the function frames themselves form an (genuine) stack called the *call stack*. In MIPS this stack grows downwards, and its size is always a multiple of 0x8 (in case you want to put a 64-bit value on it, although almost no N64 game functions do this). The compiler uses the stack in a single function frame in the following way: + +| user-defined variables | +| compiler-defined varibles | +| saved registers | +| argument registers/stack | + +where sp is at the very bottom of this table, and the function that called the current function would have its frame above this one. We have seen a couple of aspects of this stack behaviour already: saving the function arguments onto it in [`EnRecepgirl_Destroy`](#destroy), and here, requiring an extre user stack variable to be the correct size. + +Anyway, back to EnRecepgirl. 4 functions to go... + +## `func_80C100DC` + +This is the final non-draw function. You know what to do now: remake the context and run mips2c: +```C +void func_80C100DC(EnRecepgirl *this) { + u8 temp_t6; + u8 temp_v0; + + temp_v0 = this->unk_2AC; + temp_t6 = temp_v0 + 1; + if (temp_v0 != 0) { + this->unk_2AC = temp_t6; + if ((temp_t6 & 0xFF) == 4) { + this->unk_2AC = 0; + return; + } + // Duplicate return node #5. Try simplifying control flow for better match + return; + } + if (Rand_ZeroOne() < 0.02f) { + this->unk_2AC += 1; + } +} +``` + +Well, hmm. It's pretty hard to tell what's going on here. Finally it's time to really use `diff.py`. this function is a bit more typical of what to expect: this actor has been very easy so far! + +![func_80C100DC, first diff](images/func_80C100DC_diff1.png) + +Well, it's still *pretty* close. But the registers are all wrong. Firstly, `temp_t6` is already `u8`, so the `& 0xFF` is again ineffective, so let's try removing it... + +![func_80C100DC, second diff](images/func_80C100DC_diff2.png) + +It's not obvious that did much: it even looks a bit worse. +```C + temp_v0 = this->unk_2AC; + temp_t6 = temp_v0 + 1; + if (temp_v0 != 0) { + this->unk_2AC = temp_t6; +``` +may remind you of that loop we decompiled, where mips2c unnecessarily made two temps. Let's walk through what this does. +- First, it saves the value of `this->unk_2AC` into `v0` +- Then, it adds one to it and stores it in `t6`. +- It checks if the first saved value is zero +- If it is, it sets `this->unk_2AC` to the incremented value and carries on. + +Well, if we allow ourselves to bend the order of operations a little, there's a much simpler way to write this with no temps, namely +```C + if (this->unk_2AC != 0) { + this->unk_2AC++; +``` +So let's try removing both temps: +```C +void func_80C100DC(EnRecepgirl *this) { + if (this->unk_2AC != 0) { + this->unk_2AC++; + if (this->unk_2AC == 4) { + this->unk_2AC = 0; + return; + } + return; + } + if (Rand_ZeroOne() < 0.02f) { + this->unk_2AC++; + } +} +``` + +![func_80C100DC, matching](images/func_80C100DC_diff3.png) + +There we go. + +Even though this matches, it is not quite according to our style: remember what was said earlier about early returns. Here, both of them can be removed and replaced by a single else without affecting matching: +```C +void func_80C100DC(EnRecepgirl *this) { + if (this->unk_2AC != 0) { + this->unk_2AC++; + if (this->unk_2AC == 4) { + this->unk_2AC = 0; + } + } else if (Rand_ZeroOne() < 0.02f) { + this->unk_2AC++; + } +} +``` +and this is how we prefer it to be written. + +With that, the last remaining function is `EnJj_Draw`. Draw functions have an extra layer of macroing that is required, so we shall cover them separately. + +Next: [Draw functions](draw_functions.md) diff --git a/docs/tutorial/types_structs_padding.md b/docs/tutorial/types_structs_padding.md new file mode 100644 index 000000000..dc72e0100 --- /dev/null +++ b/docs/tutorial/types_structs_padding.md @@ -0,0 +1,159 @@ +# Types, structs, and padding + +Reminders: +- In N64 MIPS, 1 word is 4 bytes (yes, the N64 is meant to be 64-bit, but it mostly isn't used like it in MM or OoT) +- A byte is 8 bits, or 2 hex digits + + +## Types + +The following are the common data types used everywhere: + +| Name | Size | Comment | +| ---- | ----- | -------- | +| char | 1 byte | character | +| u8 | 1 byte | unsigned byte | +| s8 | 1 byte | signed byte | +| u16 | 2 bytes | unsigned short | +| s16 | 2 bytes | signed short | +| u32 | 4 bytes/1 word | unsigned int | +| s32 | 4 bytes/1 word | signed int | +| void* | 4 bytes/1 word | pointer | +| uintptr_t | 4 bytes/1 word | pointer^ | +| intptr_t | 4 bytes/1 word | pointer^ | + +A pointer is sometimes mistaken for an `s32`. The last two, marked with `^`, are special types allowing for arithmetic on generic pointers, and are to be used over `u32`. + +`s32` is the default thing to use in the absence of any other information about the data. + +Useful data for guessing types: +- `u8` is about 7 times more common than `s8` +- `s16` is about 16 times more common than `u16` +- `s32` is about 8 times more common than `u32` + +Another useful thing to put here: the typedef for an action function is +```C +typedef void (*ActorNameActionFunc)(struct ActorName*, GlobalContext*); +``` +where you replace `ActorName` by the actual actor name as used elsewhere in the actor, e.g. `EnRecepgirl`. In MM these typedefs have been automatically generated, so you don't need to constantly copy from here or another actor any more. + + +## Some Common Structs + +Here are the usual names and the sizes of some of the most common structs used in actors and their structs: +| Type | Usual name | Size | +| ----------------------- | --------------------- | --------------- | +| `Actor` | `actor` | 0x144 | +| `DynaPolyActor` | `dyna` | 0x15C | +| `Vec3f` | | 0xC | +| `Vec3s` | | 0x6 | +| `SkelAnime` | `skelAnime` | 0x44 | +| `Vec3s[limbCount]` | `jointTable` | 0x6 * limbCount | +| `Vec3s[limbCount]` | `morphTable` | 0x6 * limbCount | +| `ColliderCylinder` | `collider` | 0x4C | +| `ColliderQuad` | `collider` | 0x80 | +| `ColliderJntSph` | `collider` | 0x20 | +| `ColliderJntSphElement` | `colliderElements[n]` | 0x40 * n | +| `ColliderTris` | `collider` | 0x20 | +| `ColliderTrisElement` | `colliderElements[n]` | 0x5C * n | + +Note that `Actor` and `DynaPolyActor` have changed size from OoT. + + +## Padding + +### Alignment + +A stored variable or piece of data does not always start immediately after the previous one: there may be padding in between: `0`s that are never written or referred to, and so ignored. This is to do with how the processor accesses memory: it reads 1 word at a time, so multibyte objects are aligned so they cross as few word boundaries as possible. + +The clearest example of this is that variables with types that are 1 word in size (`s32`s and pointers, for example) are automatically shifted so that they start at the beginning of the next word, i.e. at an offset ending with one of `0,4,8,C`: this is called 4-alignment. This will also happen to `s16`s, but with 2-alignment + +### Struct padding + +In actor structs, this manifests as some of the char arrays not being completely replaced by actual variables. + +```C +typedef struct EnRecepgirl { + /* 0x0000 */ Actor actor; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[24]; + /* 0x0218 */ Vec3s morphTable[24]; + /* 0x02A8 */ EnRecepgirlActionFunc actionFunc; + /* 0x02AC */ u8 unk_2AC; + /* 0x02AE */ Vec3s unk_2AE; +} EnRecepgirl; // size = 0x2B4 +``` + +Notice that even though `unk_2AC` is a `u8`, `unk_2AE` is at `this + 0x2AE`, rather than `0x2AD`: we removed the extra char of padding while working on this actor. + +How do structs themselves align? A struct has the same alignment properties as its longest constituent (that is not itself a struct). For example, a `Vec3f` has 4-alignment, while a `Vec3s` has 2-alignment. + +A struct may also pad at the end: it will pad to the size of its largest non-struct element. Notably, every actor struct has size a whole number of words as well, so this phenomenon also occurs at the ends of structs. For example, ObjTree has the following actor struct: + +```C +typedef struct ObjTree { + /* 0x0000 */ DynaPolyActor dyna; + /* 0x015C */ ColliderCylinder collider; + /* 0x01A8 */ ObjTreeActionFunc actionFunc; + /* 0x01AC */ f32 unk_1AC; + /* 0x01B0 */ s16 unk_1B0; + /* 0x01B2 */ s16 unk_1B2; + /* 0x01B4 */ s16 unk_1B4; +} ObjTree; // size = 0x1B8 +``` + +The struct pads to be `0x1B8` in size even though the last actual variable ends at `0x1B6`. + +For more information on this topic, there are plenty of guides elsewhere on the Internet, for example [The Lost Art of Structure Packing](http://www.catb.org/esr/structure-packing/). *The main thing to bear in mind for decomp purposes is that after finishing the functions, there may be some small parts of the actor struct that are just not used, because they were originally just struct padding.* + +### Padding at the end of sections + +In the ROM, each actor is layed out in the following order: + +- .text (Function instructions, separated into .s files, aka .text) +- .data (contents of the .data.s file) +- .rodata (read-only data, includes strings, floats, jumptables etc., almost entirely moved to the appropriate function files in the MM repo) +- .bss (varibles initialised to 0, not assigned a value when declared) +- .reloc (relocation information: you can ignore this) + +Each section is 0x10/16-aligned (qword aligned), i.e. each new section begins at an address with last digit `0`. This means that there can occur up to three words of padding at the end of each section. + +(The same occurs with any object divided into multiple .c files: each new file becomes 0x10 aligned.) + +#### Padding at the end of .text (function instructions) + +In function instructions, this manifests as a set of `nop`s at the end of the last function: for example, in EnRecepGirl, +``` +/* 0006B0 80C10680 27BD0038 */ addiu $sp, $sp, 0x38 +/* 0006B4 80C10684 03E00008 */ jr $ra +/* 0006B8 80C10688 00000000 */ nop +/* 0006BC 80C1068C 00000000 */ nop +``` + +the second `nop` is just extra `0`s of padding, as you can see in the machine code (third column in the comment) + +Once the rest of the functions match, this is automatic. So you never need to worry about these. + +#### Padding at the end of .data + +In data, the last entry may contain up to 3 words of 0s as padding. These can safely be removed when migrating data, but make sure that you don't remove something that actually is accessed by the function and happens to be 0! + +For example, in `ObjTree` we found that the last symbol in the data, +``` +glabel D_80B9A5BC +/* 00006C 80B9A5BC */ .word 0x08000000 +/* 000070 80B9A5C0 */ .word 0x00000000 +/* 000074 80B9A5C4 */ .word 0xFE000000 +/* 000078 80B9A5C8 */ .word 0x00000000 +/* 00007C 80B9A5CC */ .word 0x00000000 +``` +had 2 words of padding: only the first 3 words are actually used in the `CollisionCheckInfoInit2`. + +### Padding within the .data section + +Every distinct symbol in data is 4-aligned (word-aligned). So in the data, even if you have two `u8`s, they will be stored in addresses starting successive words: + +```C +u8 byte1 = 1 // will go to address ending in 0 +u8 byte2 = 2 // Will go to address ending in 4 +``` diff --git a/docs/tutorial/vscode.md b/docs/tutorial/vscode.md new file mode 100644 index 000000000..91f2f659c --- /dev/null +++ b/docs/tutorial/vscode.md @@ -0,0 +1,84 @@ +# VSCode + +A lot of people on this project use VSCode as their coding environment. + +## Extensions + +There are a number of useful extensions available to make work more efficient: + +- C/C++ IntelliSense +- Clang-Format +- HexInspector (hover on numbers for float and other info) +- NumberMonger (convert hex to decimal and vice versa) +- ~~bracket pair colorizer 2~~ (now obsolete due to VSCode's built-in bracket colouring) +- Better MIPS Support + + + + +## Useful stuff to know: + +- Ctrl + Alt + Up/Down (on Windows, on Linux it's Ctrl + Shift + Up/Down or Shift + Alt + Up/Down) gives multicursors across consecutive lines. If you want several cursors in a more diverse arrangement, middle clicking works, at least on Windows. +- Alt + Up/Down moves lines up/down. +- Shift + Alt + Up/Down (Linux: Ctrl + Shift + Alt + Up/Down) copies lines up/down. +- Ctrl + P offers a box to use to search for and open files. +- Ctrl + Shift + P offers a box for commands like editing settings or reloading the window. + +- Make use of VSCode's search/search-and-replace features. + - Ctrl + Click goes to a definition. + - Ctrl + F for search in current file + - Ctrl + H for replace in current file + - Ctrl + Shift + F for search in all files + - Ctrl + Shift + H for replace in all files + - F2 for Rename symbol + +Many of VS Code's other shortcuts can be found on [its getting started page](https://code.visualstudio.com/docs/getstarted/keybindings), which also has links to OS-specific PDFs. + +## C/C++ configuration + +You can create a `.vscode/c_cpp_properties.json` file with `C/C++: Edit Configurations (JSON)` in the command box to customise how IntelliSense reads the repository (stuff like where to look for includes, flags, compiler defines, etc.) to make VSCode's IntelliSense plugin better able to understand the structure of the repository. This is a good default one to use for this project's repository: + +```jsonc +{ + "configurations": [ + { + "name": "Linux", + "compilerPath": "${default}", // Needs to not be "" for -m32 to work + "compilerArgs": [ + "-m32" // Removes integer truncation warnings with gbi macros + ], + "intelliSenseMode": "${default}", // Shouldn't matter + "includePath": [ // Matches makefile's includes + "${workspaceFolder}/**", + "src", + "assets", + "build", + "include" + ], + "defines": [ + "_LANGUAGE_C" // For gbi.h + ], + "cStandard": "gnu89", // C89 + some GNU extensions from C99 like C++ comments + "cppStandard": "${default}" // Only ZAPD uses C++, so doesn't really matter + } + ], + "version": 4 +} +``` + +## Settings + +Add the following to (or create) the `.vscode/settings.json` file for VSCode to search the gitignored asset and assembly files by default: + +```jsonc +{ + "search.useIgnoreFiles": false, + "search.exclude": { + "**/.git": true, + "baserom/**": true, + "build/**": true, + "expected/**": true, + "nonmatchings/**": true, + }, +} +``` diff --git a/docs/useful_conversions.md b/docs/useful_conversions.md new file mode 100644 index 000000000..102c20daa --- /dev/null +++ b/docs/useful_conversions.md @@ -0,0 +1,275 @@ +# Useful conversions + +This article contains some useful conversion tables. Beware that we will omit the `0x` prefix on hex numbers: it will be evident from context which base is intended. + +- [Degrees and hex/binary angles](#degrees-and-hex-binary-angles) + * [Small angles](#small-angles) + * [Larger angles](#larger-angles) +- [Round decimal numbers in hex](#round-decimal-numbers-in-hex) + * [Small](#small) + * [Medium](#medium) + * [Large](#large) +- [Extra large](#extra-large) +- [Shifts/powers of 2 in dec and hex](#shifts-powers-of-2-in-dec-and-hex) + +## Degrees and hex/binary angles + +Conversion of degrees to binary angles in the two common ways, that give different answers. Table is produced using this script: + +```bash +$ printf "%s\t%s\t%s\n" "d" "d * 2^16/360" "2^16/360 * d" ; for i in {0..360..5} ; do printf "%d\t%X\t\t%X\n" "$i" $(( "$i" * 0x10000 / 360 )) $(( 0x10000 / 360 * "$i" )) ; done +``` + +### Small angles + +| `d` | `d * 2^16/360` | `2^16/360 * d` | +| ----: | -------------: | -------------: | +| 0 | 0 | 0 | +| 1 | B6 | B6 | +| 2 | 16C | 16C | +| 3 | 222 | 222 | +| 4 | 2D8 | 2D8 | +| 5 | 38E | 38E | +| 6 | 444 | 444 | +| 7 | 4FA | 4FA | +| 8 | 5B0 | 5B0 | +| 9 | 666 | 666 | +| 10 | 71C | 71C | +| 11 | 7D2 | 7D2 | +| 12 | 888 | 888 | +| 13 | 93E | 93E | +| 14 | 9F4 | 9F4 | +| 15 | AAA | AAA | +| 16 | B60 | B60 | +| 17 | C16 | C16 | +| 18 | CCC | CCC | +| 19 | D82 | D82 | +| 20 | E38 | E38 | +| 21 | EEE | EEE | +| 22 | FA4 | FA4 | +| 23 | 105B | 105A | +| 24 | 1111 | 1110 | +| 25 | 11C7 | 11C6 | +| 26 | 127D | 127C | +| 27 | 1333 | 1332 | +| 28 | 13E9 | 13E8 | +| 29 | 149F | 149E | +| 30 | 1555 | 1554 | + +### Larger angles + +| `d` | `d * 2^16/360` | `2^16/360 * d` | +| -----: | -------------: | -------------: | +| 0 | 0 | 0 | +| 5 | 38E | 38E | +| 10 | 71C | 71C | +| 15 | AAA | AAA | +| 20 | E38 | E38 | +| 25 | 11C7 | 11C6 | +| 30 | 1555 | 1554 | +| 35 | 18E3 | 18E2 | +| 40 | 1C71 | 1C70 | +| 45 | 2000 | 1FFE | +| 50 | 238E | 238C | +| 55 | 271C | 271A | +| 60 | 2AAA | 2AA8 | +| 65 | 2E38 | 2E36 | +| 70 | 31C7 | 31C4 | +| 75 | 3555 | 3552 | +| 80 | 38E3 | 38E0 | +| 85 | 3C71 | 3C6E | +| 90 | 4000 | 3FFC | +| 95 | 438E | 438A | +| 100 | 471C | 4718 | +| 105 | 4AAA | 4AA6 | +| 110 | 4E38 | 4E34 | +| 115 | 51C7 | 51C2 | +| 120 | 5555 | 5550 | +| 125 | 58E3 | 58DE | +| 130 | 5C71 | 5C6C | +| 135 | 6000 | 5FFA | +| 140 | 638E | 6388 | +| 145 | 671C | 6716 | +| 150 | 6AAA | 6AA4 | +| 155 | 6E38 | 6E32 | +| 160 | 71C7 | 71C0 | +| 165 | 7555 | 754E | +| 170 | 78E3 | 78DC | +| 175 | 7C71 | 7C6A | +| 180 | 8000 | 7FF8 | +| 185 | 838E | 8386 | +| 190 | 871C | 8714 | +| 195 | 8AAA | 8AA2 | +| 200 | 8E38 | 8E30 | +| 205 | 91C7 | 91BE | +| 210 | 9555 | 954C | +| 215 | 98E3 | 98DA | +| 220 | 9C71 | 9C68 | +| 225 | A000 | 9FF6 | +| 230 | A38E | A384 | +| 235 | A71C | A712 | +| 240 | AAAA | AAA0 | +| 245 | AE38 | AE2E | +| 250 | B1C7 | B1BC | +| 255 | B555 | B54A | +| 260 | B8E3 | B8D8 | +| 265 | BC71 | BC66 | +| 270 | C000 | BFF4 | +| 275 | C38E | C382 | +| 280 | C71C | C710 | +| 285 | CAAA | CA9E | +| 290 | CE38 | CE2C | +| 295 | D1C7 | D1BA | +| 300 | D555 | D548 | +| 305 | D8E3 | D8D6 | +| 310 | DC71 | DC64 | +| 315 | E000 | DFF2 | +| 320 | E38E | E380 | +| 325 | E71C | E70E | +| 330 | EAAA | EA9C | +| 335 | EE38 | EE2A | +| 340 | F1C7 | F1B8 | +| 345 | F555 | F546 | +| 350 | F8E3 | F8D4 | +| 355 | FC71 | FC62 | +| 360 | 10000 | FFF0 | + +Similarly for small angles with a smaller increment: + + + +## Round decimal numbers in hex + +```bash +printf "%s\t%s\n" "dec" "hex" ; for i in {0..100..5} ; do printf "%d\t%X\n" "$i" "$i" ; done +``` + +### Small + +| dec | hex | +| -----: | --: | +| 0 | 0 | +| 5 | 5 | +| 10 | A | +| 15 | F | +| 20 | 14 | +| 25 | 19 | +| 30 | 1E | +| 35 | 23 | +| 40 | 28 | +| 45 | 2D | +| 50 | 32 | +| 55 | 37 | +| 60 | 3C | +| 65 | 41 | +| 70 | 46 | +| 75 | 4B | +| 80 | 50 | +| 85 | 55 | +| 90 | 5A | +| 95 | 5F | +| 100 | 64 | + + +### Medium + +| dec | hex | +| -----: | ---: | +| 100 | 64 | +| 150 | 96 | +| 200 | C8 | +| 250 | FA | +| 300 | 12C | +| 350 | 15E | +| 400 | 190 | +| 450 | 1C2 | +| 500 | 1F4 | +| 550 | 226 | +| 600 | 258 | +| 650 | 28A | +| 700 | 2BC | +| 750 | 2EE | +| 800 | 320 | +| 850 | 352 | +| 900 | 384 | +| 950 | 3B6 | +| 1000 | 3E8 | + + +### Large + +| dec | hex | +| -----: | ----: | +| 1000 | 3E8 | +| 1500 | 5DC | +| 2000 | 7D0 | +| 2500 | 9C4 | +| 3000 | BB8 | +| 3500 | DAC | +| 4000 | FA0 | +| 4500 | 1194 | +| 5000 | 1388 | +| 5500 | 157C | +| 6000 | 1770 | +| 6500 | 1964 | +| 7000 | 1B58 | +| 7500 | 1D4C | +| 8000 | 1F40 | +| 8500 | 2134 | +| 9000 | 2328 | +| 9500 | 251C | +| 10000 | 2710 | + + +## Extra large +| dec | hex | +| -----: | ----: | +| 10000 | 2710 | +| 11000 | 2AF8 | +| 12000 | 2EE0 | +| 13000 | 32C8 | +| 14000 | 36B0 | +| 15000 | 3A98 | +| 16000 | 3E80 | +| 17000 | 4268 | +| 18000 | 4650 | +| 19000 | 4A38 | +| 20000 | 4E20 | +| 21000 | 5208 | +| 22000 | 55F0 | +| 23000 | 59D8 | +| 24000 | 5DC0 | +| 25000 | 61A8 | +| 26000 | 6590 | +| 27000 | 6978 | +| 28000 | 6D60 | +| 29000 | 7148 | +| 30000 | 7530 | + +## Shifts/powers of 2 in dec and hex + +```bash +$ printf "%s\t%s\t%s\n" "n" "1 << n (hex)" "1 << n (dec)" ; for i in {0..15..1} ; do printf "%d\t%X\t\t%d\n" "$i" $(( 1 << "$i" )) $(( 1 << "$i" )) ; done +``` +`1 << n` is the same as `2^n`. + +| `n` | `1 << n` (hex) | `1 << n` (dec) | +| -----: | -------------: | -------------: | +| 0 | 1 | 1 | +| 1 | 2 | 2 | +| 2 | 4 | 4 | +| 3 | 8 | 8 | +| 4 | 10 | 16 | +| 5 | 20 | 32 | +| 6 | 40 | 64 | +| 7 | 80 | 128 | +| 8 | 100 | 256 | +| 9 | 200 | 512 | +| 10 | 400 | 1024 | +| 11 | 800 | 2048 | +| 12 | 1000 | 4096 | +| 13 | 2000 | 8192 | +| 14 | 4000 | 16384 | +| 15 | 8000 | 32768 | + + diff --git a/extract_assets.py b/extract_assets.py index 066c1de3c..dda5efaec 100755 --- a/extract_assets.py +++ b/extract_assets.py @@ -1,7 +1,8 @@ #!/usr/bin/env python3 -import argparse, json, os, signal, time -from multiprocessing import Pool, Event, Manager +import argparse, json, os, signal, time, colorama, multiprocessing + +colorama.init() EXTRACTED_ASSETS_NAMEFILE = ".extracted-assets.json" @@ -15,10 +16,10 @@ def ExtractFile(xmlPath, outputPath, outputSourcePath): # Don't extract if another file wasn't extracted properly. return - execStr = "tools/ZAPD/ZAPD.out e -eh -i %s -b baserom/ -o %s -osf %s -gsf 1 -rconf tools/ZAPDConfigs/MM/Config.xml" % (xmlPath, outputPath, outputSourcePath) + execStr = f"tools/ZAPD/ZAPD.out e -eh -i {xmlPath} -b baserom/ -o {outputPath} -osf {outputSourcePath} -gsf 1 -rconf tools/ZAPDConfigs/MM/Config.xml {ZAPDArgs}" if globalUnaccounted: - execStr += " -wu" + execStr += " -Wunaccounted" print(execStr) exitValue = os.system(execStr) @@ -69,14 +70,33 @@ def initializeWorker(abort, unaccounted: bool, extractedAssetsTracker: dict, man def main(): parser = argparse.ArgumentParser(description="baserom asset extractor") parser.add_argument("-s", "--single", help="asset path relative to assets/, e.g. objects/gameplay_keep") - parser.add_argument("-t", "--threads", help="Number of cpu cores to extract with.") parser.add_argument("-f", "--force", help="Force the extraction of every xml instead of checking the touched ones.", action="store_true") + parser.add_argument("-j", "--jobs", help="Number of cpu cores to extract with.") parser.add_argument("-u", "--unaccounted", help="Enables ZAPD unaccounted detector warning system.", action="store_true") + parser.add_argument("-Z", help="Pass the argument on to ZAPD, e.g. `-ZWunaccounted` to warn about unaccounted blocks in XMLs. Each argument should be passed separately, *without* the leading dash.", metavar="ZAPD_ARG", action="append") args = parser.parse_args() + global ZAPDArgs + ZAPDArgs = "" + if args.Z is not None: + badZAPDArg = False + for i in range(len(args.Z)): + z = args.Z[i] + if z[0] == '-': + print(f"{colorama.Fore.LIGHTRED_EX}error{colorama.Fore.RESET}: argument \"{z}\" starts with \"-\", which is not supported.", file=os.sys.stderr) + badZAPDArg = True + else: + args.Z[i] = "-" + z + + if badZAPDArg: + exit(1) + + ZAPDArgs = " ".join(args.Z) + print("Using extra ZAPD arguments: " + ZAPDArgs) + global mainAbort - mainAbort = Event() - manager = Manager() + mainAbort = multiprocessing.Event() + manager = multiprocessing.Manager() signal.signal(signal.SIGINT, SignalHandler) extractedAssetsTracker = manager.dict() @@ -88,7 +108,7 @@ def main(): if asset_path is not None: fullPath = os.path.join("assets", "xml", asset_path + ".xml") if not os.path.exists(fullPath): - print(f"Error. File {fullPath} doesn't exists.", file=os.sys.stderr) + print(f"Error. File {fullPath} does not exist.", file=os.sys.stderr) exit(1) initializeWorker(mainAbort, args.unaccounted, extractedAssetsTracker, manager) @@ -104,12 +124,20 @@ def main(): if file.endswith(".xml"): xmlFiles.append(fullPath) - numCores = int(args.threads or 0) - if numCores <= 0: - numCores = 1 - print("Extracting assets with " + str(numCores) + " CPU cores.") - with Pool(numCores, initializer=initializeWorker, initargs=(mainAbort, args.unaccounted, extractedAssetsTracker, manager)) as p: - p.map(ExtractFunc, xmlFiles) + try: + numCores = int(args.jobs or 0) + if numCores <= 0: + numCores = 1 + print("Extracting assets with " + str(numCores) + " CPU core" + ("s" if numCores > 1 else "") + ".") + with multiprocessing.get_context("fork").Pool(numCores, initializer=initializeWorker, initargs=(mainAbort, args.unaccounted, extractedAssetsTracker, manager)) as p: + p.map(ExtractFunc, xmlFiles) + except (multiprocessing.ProcessError, TypeError): + print("Warning: Multiprocessing exception ocurred.", file=os.sys.stderr) + print("Disabling mutliprocessing.", file=os.sys.stderr) + + initializeWorker(mainAbort, args.unaccounted, extractedAssetsTracker, manager) + for singlePath in xmlFiles: + ExtractFunc(singlePath) with open(EXTRACTED_ASSETS_NAMEFILE, 'w', encoding='utf-8') as f: serializableDict = dict() diff --git a/format.sh b/format.sh index 89a0906ad..1c9389a9a 100755 --- a/format.sh +++ b/format.sh @@ -5,6 +5,16 @@ FORMAT_OPTS="-i -style=file" TIDY_OPTS="-p . --fix --fix-errors" COMPILER_OPTS="-fno-builtin -std=gnu90 -Iinclude -Isrc -D_LANGUAGE_C -DNON_MATCHING" +# https://backreference.org/2010/05/23/sanitizing-files-with-no-trailing-newline/index.html +# "gets the last character of the file pipes it into read, which will exit with a nonzero exit code if it encounters EOF before newline (so, if the last character of the file isn't a newline). If read exits nonzero, then append a newline onto the file using echo (if read exits 0, that satisfies the ||, so the echo command isn't run)." (https://stackoverflow.com/a/34865616) +function add_final_newline () { + for file in "$@" + do + tail -c1 $file | read -r _ || echo >> $file + done +} +export -f add_final_newline + shopt -s globstar if [ -z `command -v clang-format-${FORMAT_VER}` ] @@ -20,7 +30,7 @@ if (( $# > 0 )); then echo "Running clang-tidy..." clang-tidy ${TIDY_OPTS} "$@" -- ${COMPILER_OPTS} &> /dev/null echo "Adding missing final new lines..." - sed -i -e '$a\' "$@" + add_final_newline "$@" echo "Done formatting file(s) $*" exit fi @@ -31,6 +41,6 @@ clang-format-${FORMAT_VER} ${FORMAT_OPTS} src/**/*.c echo "Running clang-tidy..." clang-tidy ${TIDY_OPTS} src/**/*.c -- ${COMPILER_OPTS} &> /dev/null echo "Adding missing final new lines..." -find src/ -type f -name "*.c" -exec sed -i -e '$a\' {} \; -find assets/xml/ -type f -name "*.xml" -exec sed -i -e '$a\' {} \; +find src/ -type f -name "*.c" -exec bash -c 'add_final_newline "$@"' bash {} + +find assets/xml/ -type f -name "*.xml" -exec bash -c 'add_final_newline "$@"' bash {} + echo "Done formatting all files." diff --git a/include/functions.h b/include/functions.h index ba90cdf77..3efa216e8 100644 --- a/include/functions.h +++ b/include/functions.h @@ -71,7 +71,7 @@ void Fault_Wait5Seconds(void); void Fault_WaitForButtonCombo(void); void Fault_DrawMemDumpPage(const char* title, u32* addr, u32 param_3); void Fault_DrawMemDump(u32 pc, u32 sp, u32 unk0, u32 unk1); -void Fault_FindNextStackCall(u32** sp, u32** pc, u32** ra); +void Fault_FindNextStackCall(uintptr_t* spPtr, uintptr_t* pcPtr, uintptr_t* raPtr); void Fault_DrawStackTrace(OSThread* t, u32 flags); void osSyncPrintfStackTrace(OSThread* t, u32 flags); void Fault_ResumeThread(OSThread* t); @@ -96,12 +96,12 @@ void FaultDrawer_SetFontColor(u16 color); void FaultDrawer_SetCharPad(s8 padW, s8 padH); void FaultDrawer_SetCursor(s32 x, s32 y); void FaultDrawer_FillScreen(void); -FaultDrawer* FaultDrawer_FormatStringFunc(FaultDrawer* arg, const char* str, s32 count); -void FaultDrawer_VPrintf(const char* str, char* args); +void* FaultDrawer_FormatStringFunc(void* arg, const char* str, size_t count); +void FaultDrawer_VPrintf(const char* fmt, va_list ap); void FaultDrawer_Printf(const char* fmt, ...); void FaultDrawer_DrawText(s32 x, s32 y, const char* fmt, ...); void FaultDrawer_SetDrawerFB(void* fb, u16 w, u16 h); -void FaultDrawer_SetInputCallback(void* func); +void FaultDrawer_SetInputCallback(FaultDrawerCallback callback); void FaultDrawer_Init(void); void func_80084940(void); void func_80084968(void); @@ -167,7 +167,7 @@ s32 PadSetup_Init(OSMesgQueue* mq, u8* outMask, OSContStatus* status); // void func_800867B4(void); // void func_800867D4(void); // void func_800867F4(void); -// void func_80086814(void); +f32 func_80086814(f32 x); // void func_80086834(void); // void func_80086880(void); // void func_800869A4(void); @@ -305,8 +305,8 @@ void osViBlack(u8 active); s32 __osSiRawReadIo(u32 devAddr, u32* data); OSId osGetThreadId(OSThread* t); void osSpTaskYield(void); -s32 __osPfsGetNextPage(OSPfs* param_1, __OSInode* param_2, u8 param_3, u8 param_4); -s32 osPfsReadWriteFile(OSPfs* pfs, s32 file_no, u8 flag, s32 offset, s32 size_in_bytes, u8* data_buffer); +s32 __osPfsGetNextPage(OSPfs* pfs, u8* bank, __OSInode* inode, __OSInodeUnit* page); +s32 osPfsReadWriteFile(OSPfs* pfs, s32 fileNo, u8 flag, s32 offset, s32 size, u8* data); s32 __osPfsGetStatus(OSMesgQueue* queue, s32 channel); // void __osPfsRequestOneChannel(void); // void __osPfsGetOneChannelData(void); @@ -381,7 +381,7 @@ void guRotateF(float mf[4][4], f32 a, f32 x, f32 y, f32 z); void guRotate(Mtx* m, f32 a, f32 x, f32 y, f32 z); void __osSetGlobalIntMask(u32 mask); s32 osVoiceInit(OSMesgQueue* siMessageQ, OSVoiceHandle* hd, s32 channel); -s32 __osContChannelReset(OSMesgQueue* mq, s32 count); +s32 __osContChannelReset(OSMesgQueue* mq, s32 channel); s32 __osVoiceSetADConverter(OSMesgQueue* mq, s32 port, u8 arg2); s32 osAiSetFrequency(u32 frequency); s32 __osContRamRead(OSMesgQueue* mq, s32 channel, u16 address, u8* buffer); @@ -493,58 +493,43 @@ void* __osMemcpy(void* dst, void* src, size_t size); // void EnItem00_DrawHeartContainer(EnItem00* this, GlobalContext* globalCtx); // void EnItem00_DrawHeartPiece(EnItem00* this, GlobalContext* globalCtx); // s16 func_800A7650(s16 dropId); -EnItem00* Item_DropCollectible(GlobalContext* globalCtx, Vec3f* spawnPos, u32 params); -Actor* Item_DropCollectible2(GlobalContext* globalCtx, Vec3f* spawnPos, u32 params); +Actor* Item_DropCollectible(GlobalContext* globalCtx, Vec3f* spawnPos, u32 params); +Actor* Item_DropCollectible2(GlobalContext* globalCtx, Vec3f* spawnPos, s32 params); void Item_DropCollectibleRandom(GlobalContext* globalCtx, Actor* fromActor, Vec3f* spawnPos, s16 params); s32 func_800A8150(s32 index); s32 func_800A817C(s32 index); s32 func_800A81A4(GlobalContext* globalCtx, s32 a1, s32 a2); -void func_800A81F0(EffectBlure* this, Vec3f* p1, Vec3f* p2); -void func_800A8514(void* effectParams); -void EffectBlure_Initcommon(EffectBlure* params); -void EffectBlure_Init1(EffectBlure* params, EffBlureInit1* init); -void EffectBlure_Init2(EffectBlure* params, EffBlureInit2* init); -void EffectBlure_Destroy(EffectBlure* params); -s32 EffectBlure_Update(EffectBlure* params); -// void func_800A8C78(void); -// void func_800A8DE8(void); -// void func_800A92FC(void); -// void func_800A9330(void); -// void func_800A9804(void); -// void func_800AA190(void); -// void func_800AA460(void); -// void func_800AA498(void); -// void func_800AA700(void); -// void func_800AABE0(void); -void EffectBlure_Draw(EffectBlure* params, GraphicsContext* gfxCtx); -void EffectShieldParticle_Init(EffShieldParticleParams* params, EffShieldParticleInit* init); -void EffectShieldParticle_Destroy(EffShieldParticleParams* params); -s32 EffectShieldParticle_Update(EffShieldParticleParams* params); -void EffectShieldParticle_CalculateColors(EffShieldParticleParams* params, Color_RGBA8* primColor, Color_RGBA8* envColor); -void EffectShieldParticle_Draw(EffShieldParticleParams* params, GraphicsContext* gfxCtx); -void EffectSpark_Init(EffSparkParams* params, EffSparkParams* init); -void EffectSpark_Destroy(EffSparkParams* params); -s32 EffectSpark_Update(EffSparkParams* params); -void EffectSpark_Draw(EffSparkParams* params, GraphicsContext* gfxCtx); -void func_800AE2A0(GlobalContext* globalCtx, Color_RGBA8* arg1, s16 arg2, s16 arg3); -void func_800AE434(GlobalContext* globalCtx, Color_RGBA8* color, s16 sParm3, s16 sParm4); +void EffectBlure_AddVertex(EffectBlure* this, Vec3f* p1, Vec3f* p2); +void EffectBlure_AddSpace(EffectBlure* this); +void EffectBlure_Init1(void* thisx, void* initParamsx); +void EffectBlure_Init2(void* thisx, void* initParamsx); +void EffectBlure_Destroy(void* thisx); +s32 EffectBlure_Update(void* thisx); +void EffectBlure_Draw(void* thisx, GraphicsContext* gfxCtx); +void EffectShieldParticle_Init(void* thisx, void* initParamsx); +void EffectShieldParticle_Destroy(void* thisx); +s32 EffectShieldParticle_Update(void* thisx); +void EffectShieldParticle_Draw(void* thisx, GraphicsContext* gfxCtx); +void EffectSpark_Init(void* thisx, void* initParamsx); +void EffectSpark_Destroy(void* thisx); +s32 EffectSpark_Update(void* thisx); +void EffectSpark_Draw(void* thisx, GraphicsContext* gfxCtx); +void func_800AE2A0(GlobalContext* globalCtx, Color_RGBA8* color, s16 arg2, s16 arg3); +void func_800AE434(GlobalContext* globalCtx, Color_RGBA8* color, s16 arg2, s16 arg3); void func_800AE5A0(GlobalContext* globalCtx); -void func_800AE5E4(GlobalContext* globalCtx, Color_RGBA8* arg1, s16 arg2, s16 arg3); -void func_800AE778(GlobalContext* globalCtx, Color_RGBA8* color, s16 param_3, s16 param_4); +void func_800AE5E4(GlobalContext* globalCtx, Color_RGBA8* color, s16 arg2, s16 arg3); +void func_800AE778(GlobalContext* globalCtx, Color_RGBA8* color, s16 arg2, s16 arg3); void func_800AE8EC(GlobalContext* globalCtx); -void func_800AE930(CollisionContext* colCtx, s32 param_2, Vec3f* param_3, f32 param_4, s16 param_5, CollisionPoly* param_6, s32 param_7); -void func_800AEF44(s32 arg0); -void EffectTireMark_InitParticle(EffTireMarkParticle* particle); -void EffectTireMark_Init(EffTireMarkParams* params, EffTireMarkInit* init); -void EffectTireMark_Destroy(EffTireMarkParams* params); -s32 EffectTireMark_Update(EffTireMarkParams* params); -void EffectTireMark_InitVertices(F3DVertexColor* vertices, EffTireMarkParticle* particle, s32 index, s32 alpha); -void EffectTireMark_Draw(EffTireMarkParams* params, GraphicsContext* gfxCtx); -GlobalContext* Effect_GetContext(void); -void* Effect_GetParams(s32 index); -void Effect_InitCommon(EffCommon* common); +void func_800AE930(CollisionContext* colCtx, EffectTireMark* this, Vec3f* pos, f32 arg3, s16 angle, CollisionPoly* colPoly, s32 arg6); +void func_800AEF44(EffectTireMark* this); +void EffectTireMark_Init(void* thisx, void* initParamsx); +void EffectTireMark_Destroy(void* thisx); +s32 EffectTireMark_Update(void* thisx); +void EffectTireMark_Draw(void* thisx, GraphicsContext* gfxCtx); +GlobalContext* Effect_GetGlobalCtx(void); +void* Effect_GetByIndex(s32 index); void Effect_Init(GlobalContext* globalCtx); -void Effect_Add(GlobalContext* globalCtx, s32* index, s32 type, u8 param_4, u8 param_5, void* initParams); +void Effect_Add(GlobalContext* globalCtx, s32* pIndex, s32 type, u8 arg3, u8 arg4, void* initParams); void Effect_DrawAll(GraphicsContext* gfxCtx); void Effect_UpdateAll(GlobalContext* globalCtx); void Effect_Destroy(GlobalContext* globalCtx, s32 index); @@ -603,11 +588,13 @@ void EffectSsGSpk_SpawnSmall(GlobalContext* globalCtx, Actor* actor, Vec3f* pos, void EffectSsKiraKira_SpawnDispersed(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, Color_RGBA8* envColor, s16 scale, s32 life); // void EffectSsKiraKira_SpawnFocused(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE2 param_7, UNK_TYPE4 param_8); // void EffectSsBomb2_SpawnFade(UNK_TYPE4 uParm1, Vec3f* pzParm2, Vec3f* pzParm3, Vec3f* pzParm4); -// void EffectSsBomb2_SpawnLayered(UNK_TYPE4 param_1, Vec3f* param_2, Vec3f* param_3, Vec3f* param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6); +void EffectSsBomb2_SpawnLayered(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, + s16 scaleStep); // void EffectSsBlast_Spawn(UNK_TYPE4 uParm1, Vec3f* pzParm2, Vec3f* pzParm3, Vec3f* pzParm4, Color_RGBA8* param_5, Color_RGBA8* param_6, UNK_TYPE2 param_7, UNK_TYPE2 param_8, UNK_TYPE2 param_9, UNK_TYPE2 param_10); -// void EffectSsBlast_SpawnWhiteCustomScale(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7); +void EffectSsBlast_SpawnWhiteCustomScale(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, + s16 scaleStep, s16 life); // void EffectSsBlast_SpawnShockwave(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE2 param_7); -// void EffectSsBlast_SpawnWhiteShockwave(void); +void EffectSsBlast_SpawnWhiteShockwave(GlobalContext* globalCtx, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3); // void EffectSsGSpk_SpawnAccel(UNK_TYPE4 uParm1, UNK_TYPE4 uParm2, Vec3f* pzParm3, Vec3f* pzParm4, Vec3f* param_5, Color_RGBA8* param_6, Color_RGBA8* param_7, UNK_TYPE2 param_8, UNK_TYPE2 param_9); // void EffectSsGSpk_SpawnNoAccel(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE2 param_8, UNK_TYPE2 param_9); // void EffectSsGSpk_SpawnFuse(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); @@ -665,7 +652,7 @@ void func_800B3030(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* // void EffectSsDeadDs_Spawn(UNK_TYPE4 uParm1, Vec3f* pzParm2, Vec3f* pzParm3, Vec3f* pzParm4, UNK_TYPE2 param_5, UNK_TYPE2 param_6, UNK_TYPE2 param_7, UNK_TYPE4 param_8); // void func_800B31BC(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE4 param_6); void EffectSsIceSmoke_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale); -// void EffectSsIceBlock_Spawn(UNK_TYPE4 uParm1, Vec3f* pzParm2, Vec3f* pzParm3, Vec3f* pzParm4, UNK_TYPE2 param_5); +void EffectSsIceBlock_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale); void FlagSet_Update(GameState* gameState); void FlagSet_Draw(GameState* gameState); void Overlay_LoadGameState(GameStateOverlay* gameState); @@ -869,13 +856,13 @@ void func_800BC154(GlobalContext* globalCtx, ActorContext* actorCtx, Actor* acto // void func_800BC1B4(void); Actor* func_800BC270(GlobalContext* globalCtx, Actor* actor, f32 arg2, UNK_TYPE4 arg3); Actor* func_800BC444(GlobalContext* globalCtx, Actor* actor, f32 arg2); -// void func_800BC4EC(void); +s16 func_800BC4EC(Actor* actor, GlobalContext* globalCtx, f32 distance, s16 angle); s32 func_800BC5B8(GlobalContext* globalCtx, Actor* actor); s32 func_800BC5EC(GlobalContext* globalCtx, Actor* actor); void func_800BC620(Vec3f* arg0, Vec3f* arg1, u8 arg2, GlobalContext* globalCtx); // void func_800BC770(void); // void func_800BC7D8(void); -// void func_800BC848(void); +void func_800BC848(Actor* actor, GlobalContext* globalCtx, s16 arg2, s16 arg3); // void func_800BC8B8(void); // void func_800BCB50(void); void func_800BCB70(Actor* actor, u16 arg1, u16 arg2, s16 arg3, s16 arg4); @@ -1269,7 +1256,7 @@ s16 Camera_ClearFlags(Camera* camera, s16 flags); // void func_800E0238(void); void func_800E02AC(Camera* camera, Actor* actor); void func_800E0308(Camera* camera, Actor* actor); -// void func_800E031C(void); +f32 func_800E031C(Camera* camera); void func_800E0348(Camera* camera); DamageTable* DamageTable_Get(s32 index); void DamageTable_Clear(DamageTable* damageTable); @@ -1547,8 +1534,8 @@ void func_800EDF24(Actor* actor, GlobalContext* globalCtx, u32 arg2); void func_800EDF78(Actor* actor, GlobalContext* globalCtx, s32 iParm3); void func_800EE0CC(Actor* actor, GlobalContext* globalCtx, s32 iParm3); s32 func_800EE1D8(GlobalContext* globalCtx); -u32 func_800EE200(GlobalContext* globalCtx, u32 uParm2); -u32 func_800EE29C(GlobalContext* globalCtx, u32 uParm2); +u32 func_800EE200(GlobalContext* globalCtx, u16 uParm2); +u32 func_800EE29C(GlobalContext* globalCtx, u16 uParm2); u32 func_800EE2F4(GlobalContext* globalCtx); void GetItem_Draw(GlobalContext* globalCtx, s16 index); void func_800EE364(GlobalContext* globalCtx, s16 index); @@ -1583,22 +1570,22 @@ void func_800F03C0(GlobalContext* globalCtx); void func_800F048C(GlobalContext* globalCtx, Vec3f* param_2, u8 param_3, u16 param_4, u8 param_5); void Audio_PlaySoundAtPosition(GlobalContext* globalCtx, Vec3f* position, s32 param_3, u16 sfxId); void func_800F0590(GlobalContext* globalCtx, Vec3f* arg1, s32 arg2, s32 arg3); -// void func_800F05C0(void); -// void func_800F07C0(void); -// void func_800F0888(void); -// void func_800F0944(void); -// void func_800F09B4(void); -// void func_800F0A20(void); -// void func_800F0A94(void); -// void func_800F0BB4(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5); -// void func_800F0CE4(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE4 param_6); -// void func_800F0DD4(void); -// void func_800F0E94(void); -// void func_800F0EEC(void); -// void func_800F0F28(void); -// void func_800F0FF0(void); -// void func_800F10AC(void); -// void func_800F112C(void); +u16 ElfMessage_GetFirstCycleHint(GlobalContext* globalCtx); +s32 EnHy_ChangeAnim(SkelAnime* skelAnime, s16 animIndex); +Actor* EnHy_FindNearestDoor(Actor* actor, GlobalContext* globalCtx); +void EnHy_ChangeObjectAndAnim(EnHy* enHy, GlobalContext* globalCtx, s16 animIndex); +s32 EnHy_UpdateSkelAnime(EnHy* enHy, GlobalContext* globalCtx); +void EnHy_Blink(EnHy* enHy, s32 arg1); +s32 EnHy_Init(EnHy* enHy, GlobalContext* globalCtx, FlexSkeletonHeader* skeletonHeaderSeg, s16 animIndex); +void func_800F0BB4(EnHy* enHy, GlobalContext* globalCtx, Actor* arg2, s16 arg3, s16 arg4); +s32 func_800F0CE4(EnHy* enHy, GlobalContext* globalCtx, ActorFunc draw, s16 arg3, s16 arg4, f32 arg5); +s32 func_800F0DD4(EnHy* enHy, GlobalContext* globalCtx, s16 arg2, s16 arg3); +s32 EnHy_SetPointFowards(EnHy* enHy, GlobalContext* globalCtx, f32 gravity, s16 animIndex); +s32 EnHy_SetPointBackwards(EnHy* enHy, GlobalContext* globalCtx, s16 animIndex); +s32 EnHy_MoveForwards(EnHy* enHy, f32 arg1); +s32 EnHy_MoveBackwards(EnHy* enHy, f32 arg1); +void EnHy_UpdateCollider(EnHy* enHy, GlobalContext* globalCtx); +s32 EnHy_PlayWalkingSound(EnHy* enHy, GlobalContext* globalCtx, f32 arg2); u16 Text_GetFaceReaction(GlobalContext* globalCtx, u32 reactionSet); void EnvFlags_UnsetAll(GlobalContext* globalCtx); void EnvFlags_Set(GlobalContext* globalCtx, s16 flag); @@ -1624,7 +1611,7 @@ ActorCutscene* ActorCutscene_GetCutscene(s16 index); s16 ActorCutscene_GetAdditionalCutscene(s16 index); s16 ActorCutscene_GetLength(s16 index); // void func_800F2138(void); -// void func_800F2178(void); +s32 func_800F2178(s16 arg0); s16 ActorCutscene_GetCurrentCamera(s16 index); // void func_800F21CC(void); s32 func_800F22C4(s16 param_1, Actor* actor); @@ -1659,8 +1646,8 @@ UNK_TYPE func_800F41E4(GlobalContext* globalCtx, ActorContext* actorCtx); void func_800F4A10(GlobalContext* globalCtx); void func_800F4C0C(GlobalContext* globalCtx); -void func_800F4E20(GlobalContext* globalCtx); -void func_800F4F28(GlobalContext* globalCtx); +void KaleidoSetup_Init(GlobalContext* globalCtx); +void KaleidoSetup_Destroy(GlobalContext* globalCtx); void Font_LoadChar(GlobalContext* globalCtx, u16 codePointIndex, s32 offset); void Font_LoadCharNES(GlobalContext* globalCtx, u8 codePointIndex, s32 offset); void Font_LoadMessageBoxEndIcon(Font* font, u16 icon); @@ -1672,7 +1659,7 @@ u32 func_800F5954(u8* param_1, u32 param_2, u32 param_3, u8 param_4, u8 param_5) f32 func_800F5A8C(u16 arg0, u16 arg1, u16 arg2, GlobalContext* globalContext); // void func_800F5B10(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5); // void func_800F5CD0(void); -// void func_800F6834(void); +void func_800F6834(GlobalContext* globalCtx, s32 waterLightsIndex); // void func_800F694C(void); // void func_800F6A04(void); // void func_800F6A40(void); @@ -1708,7 +1695,7 @@ void Kankyo_FadeOutGameOverLights(GlobalContext* globalCtx); // void func_800FC3DC(void); void func_800FC444(GraphicsContext* gfxCtx, u8 arg1, u8 arg2, u8 arg3, u8 arg4, UNK_TYPE arg5); // void func_800FC64C(void); -// void func_800FD2B4(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5); +s32 func_800FD2B4(GlobalContext* globalCtx, f32 arg1, f32 arg2, f32 arg3, f32 arg4); void func_800FD538(Color_RGB8* param_1, Color_RGB8* param_2, f32 param_3, Vec3s* param_4); void func_800FD59C(GlobalContext* globalCtx, Color_RGB8* pzParm2, f32 fParm3); void func_800FD5E0(GlobalContext* globalCtx, Color_RGB8* pzParm2, f32 fParm3); @@ -2078,7 +2065,7 @@ void func_801149A0(s32 arg0, s16 arg1); // void func_80114B84(void); // void func_80114CA0(void); UNK_TYPE func_80114E90(void); -UNK_TYPE func_80114F2C(UNK_TYPE arg0); +UNK_TYPE func_80114F2C(u8 arg0); // void func_80114FD0(void); // void func_80115130(void); // void func_801152B8(void); @@ -2091,7 +2078,7 @@ void func_80115844(GlobalContext* globalCtx, s16 param_2); s32 func_80115908(GlobalContext* globalCtx, u8 param_2); void func_801159c0(s16 param_1); void func_801159EC(s16 arg0); -void func_80115A14(s32 arg0, s16 arg1); +void func_80115A14(s16 arg0, s16 arg1); void Parameter_AddMagic(GlobalContext* globalCtx, s16 arg1); void func_80115D5C(GameState* gamestate); // void func_80115DB4(void); @@ -2129,8 +2116,8 @@ void func_80121FC4(GlobalContext* globalCtx); Path* Path_GetByIndex(GlobalContext* globalCtx, s16 index, s16 max); f32 Path_OrientAndGetDistSq(Actor* actor, Path* path, s16 waypoint, s16* yaw); void Path_CopyLastPoint(Path* path, Vec3f* dest); -// void func_80122660(void); -// UNK_TYPE4 func_80122670(s32* param_1, Input* input); +void FrameAdvance_Init(FrameAdvanceContext* frameAdvCtx); +s32 FrameAdvance_Update(FrameAdvanceContext* frameAdvCtx, Input* input); // void func_801226E0(void); void func_80122744(GlobalContext* globalCtx, UNK_PTR arg1, u32 arg2, Vec3s* arg3); s32 func_80122760(GlobalContext* globalCtx, UNK_PTR arg1, f32 arg2); @@ -2161,7 +2148,7 @@ s32 func_80123590(GlobalContext* globalCtx, Actor* actor); s32 func_80123810(GlobalContext* globalCtx); // void func_80123960(void); // void func_801239AC(void); -// void func_80123AA4(void); +void func_80123AA4(Player* player, s32 arg1); // void func_80123BD4(void); // void func_80123C58(void); // void func_80123C90(void); @@ -2174,7 +2161,7 @@ void func_80123F2C(GlobalContext* globalCtx, s32 arg1); // void func_80124020(void); u8 Player_GetMask(GlobalContext* globalCtx); void Player_RemoveMask(GlobalContext* globalCtx); -// void func_8012405C(void); +s32 func_8012405C(GlobalContext* globalCtx); // void func_80124088(void); s32 func_801240C8(Player* player); // void func_801240DC(void); @@ -2631,7 +2618,7 @@ void func_8013A46C(s32 flag); u32 func_8013A4C4(s32 flag); s16 func_8013A504(s16 val); s32 func_8013A530(GlobalContext* globalCtx, Actor* actor, s32 flag, Vec3f* pos, Vec3s* rot, f32 distanceMin, f32 distanceMax, s16 angleError); -Actor* func_8013A7C0(GlobalContext* globalCtx, s32 arg1); +struct EnDoor* SubS_FindDoor(GlobalContext* globalCtx, s32 unk_1A5); Gfx* func_8013A860(GlobalContext* globalCtx, s32 idx, void** skeleton, Vec3s* jointTable, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, UnkActorDraw unkActorDraw, Actor* actor, Mtx** mtx, Gfx* gfx); Gfx* func_8013AB00(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount, OverrideLimbDraw overrideLimbDraw, PostLimbDraw postLimbDraw, UnkActorDraw unkActorDraw, Actor* actor, Gfx* gfx); s32 func_8013AD6C(GlobalContext* globalCtx); @@ -2644,7 +2631,7 @@ void func_8013B350(Vec3f* arg0, f32* arg1, f32 arg2, s32 arg3, s32 arg4, Vec3s* s32 func_8013B6B0(Path* path, f32* arg1, s32* arg2, s32 arg3, s32 arg4, s32* arg5, f32* arg6, Vec3f* arg7, s32 arg8); void func_8013B878(GlobalContext* globalCtx, Path* path, s32 arg2, Vec3f* arg3); Path* func_8013BB34(GlobalContext* globalCtx, u8 arg1, s32 arg2); -Actor* func_8013BB7C(Actor* actor, GlobalContext* globalCtx, u8 actorCategory, s16 actorId); +Actor* SubS_FindNearestActor(Actor* actor, GlobalContext* globalCtx, u8 actorCategory, s16 actorId); s32 func_8013BC6C(SkelAnime* skelAnime, ActorAnimationEntryS* arg1, s32 arg2); s32 func_8013BD40(Actor* actor, Path* path, s32 arg2); Path* func_8013BEDC(GlobalContext* globalCtx, u8 arg1, u8 arg2, s32* arg3); @@ -2665,9 +2652,9 @@ s32 func_8013D768(Actor* actor, Vec3f* arg1, s16 arg2); s16 func_8013D83C(Path* path, s32 pointIdx, Vec3f* pos, f32* distSq); s8 func_8013D8DC(s8 arg0, GlobalContext* globalCtx); s8 func_8013D924(s16 arg0, GlobalContext* globalCtx); -Actor* func_ActorCategoryIterateById(GlobalContext* globalCtx, Actor* actorListStart, u8 actorCategory, s16 actorId); +Actor* SubS_FindActor(GlobalContext* globalCtx, Actor* actorListStart, u8 actorCategory, s16 actorId); s32 func_8013D9C8(GlobalContext* globalCtx, s16* arg1, s16* arg2, s32 arg3); -u8 func_8013DB90(GlobalContext* globalCtx, Vec3f* arg1, f32 arg2); +s32 func_8013DB90(GlobalContext* globalCtx, Vec3f* arg1, f32 arg2); s32 func_8013DC40(Path* arg0, s32 arg1, s32 arg2, Vec3f* arg3); void func_8013DCE0(GlobalContext* globalCtx, Vec3f* arg1, Actor* arg2, struct_8013DF3C_arg1* arg3, Path* arg4, s32 arg5, s32 arg6, s32 arg7, s32 arg8, u8 arg9); s32 func_8013DE04(GlobalContext* globalCtx, struct_8013DF3C_arg1* arg1, struct_8013DF3C_arg1_unk_func1 arg2, struct_8013DF3C_arg1_unk_func2 arg3, struct_8013DF3C_arg1_unk_func2 arg4, struct_8013DF3C_arg1_unk_func2 arg5); @@ -2680,17 +2667,17 @@ s32 func_8013E2D4(Actor* actor, s16 arg1, s16 arg2, s32 arg3); s32 func_8013E3B8(Actor* actor, s16 cutscenes[], s16 len); void func_8013E4B0(Vec3f* arg0, Vec3f* arg1, Vec3s* arg2, Plane* plane); s32 func_8013E5CC(Vec3f* arg0, Vec3s* arg1, Vec3f* arg2, Vec3f* arg3, Vec3f* arg4, Vec3f* arg5); -Actor* func_8013E640(GlobalContext* globalCtx, Actor* arg1, Actor* actorListStart, u8 actorCategory, s16 actorId, void* arg5, func_8013E640_arg6 arg6); +Actor* SubS_FindActorCustom(GlobalContext* globalCtx, Actor* actor, Actor* actorListStart, u8 actorCategory, s16 actorId, void* verifyData, VerifyActor verifyActor); s32 func_8013E748(Actor* actor, GlobalContext* globalCtx, f32 arg2, f32 arg3, s32 arg4, Vec3s* arg5, func_8013E748_arg6 arg6); s32 func_8013E7C0(GlobalContext* globalCtx, Actor* actor, Vec3s* arg2); void func_8013E8F8(Actor* actor, GlobalContext* globalCtx, f32 arg2, f32 arg3, s32 arg4, s16 arg5, s16 arg6); s32 func_8013E950(Vec3f* arg0, Vec3f* arg1, s16 arg2, Vec3f* arg3, Vec3f* arg4, s16* arg5, s16* arg6, s16* arg7, s16* arg8, u16 arg9, u16 arg10, u16 arg11, u16 arg12); // void func_8013EC10(void); -void func_8013EC44(f32 arg0, u8 arg1, u8 arg2, u8 arg3); +void func_8013EC44(f32 a, u8 b, u8 c, u8 d); void func_8013ECE0(f32 xyzDistToPlayerSq, u8 arg1, u8 arg2, u8 arg3); void func_8013ED9C(void); void func_8013EDD0(void); -// void func_8013EE04(void); +u32 func_8013EE04(void); void func_8013EE24(void); // void func_8013EE38(void); // void func_8013EE48(void); @@ -2754,15 +2741,15 @@ void func_801420C0(void* arg0); void func_801420F4(void* arg0); void func_80142100(void* arg0, Gfx** gfx, u32 arg2); s32 func_80142440(SkyboxContext* skyboxCtx, Vtx* vtx, s32 arg2, s32 arg3, s32 arg4, s32 arg5, s32 arg6, s32 arg7, - s32 arg8); -void func_80143148(SkyboxContext* skyboxCtx, s32 arg1); -void func_801431E8(GameState* gameState, SkyboxContext* skyboxCtx, s16 skyType); + s32 arg8); +void func_80143148(SkyboxContext* skyboxCtx, s32 arg1); +void func_801431E8(GameState* gameState, SkyboxContext* skyboxCtx, s16 skyType); void func_80143324(GlobalContext* globalCtx, SkyboxContext* skyboxCtx, s16 skyType); void func_801434E4(GameState* gameState, SkyboxContext* skyboxCtx, s16 skyType); -// void func_801435A0(void); -// void func_80143624(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE1 param_5, UNK_TYPE1 param_6, UNK_TYPE1 param_7); -// void func_80143668(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7); -// void func_80143A04(void); +Mtx* SkyboxDraw_UpdateMatrix(SkyboxContext* skyboxCtx, f32 x, f32 y, f32 z); +void SkyboxDraw_SetColors(SkyboxContext* skyboxCtx, u8 primR, u8 primG, u8 primB, u8 envR, u8 envG, u8 envB); +void SkyboxDraw_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyboxId, s16 blend, f32 x, f32 y, f32 z); +void SkyboxDraw_Noop(SkyboxContext* skyboxCtx); void func_80143A10(u8 owlId); // void func_80143A54(void); void func_80143AC4(void); @@ -2902,17 +2889,17 @@ void ShrinkWindow_Draw(GraphicsContext* gfxCtx); // void func_801631DC(void); // void func_80163334(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); // void func_80163660(void); -// void func_80163700(void); -// void func_80163758(void); -// void func_801637B4(void); -void func_80163804(GlobalContext* globalCtx); -// void func_8016388C(void); -// void func_801638D8(void); -// void func_801639A0(void); -void func_801639EC(GlobalContext* globalCtx); -void func_80163A38(GlobalContext* globalCtx); -// void func_80163A58(void); -// void func_80163C0C(void); +void* KaleidoManager_FaultAddrConvFunc(void* address, void* param); +void KaleidoManager_LoadOvl(KaleidoMgrOverlay* ovl); +void KaleidoManager_ClearOvl(KaleidoMgrOverlay* ovl); +void KaleidoManager_Init(GlobalContext* globalCtx); +void KaleidoManager_Destroy(); +void* KaleidoManager_GetRamAddr(void* vram); +void KaleidoScopeCall_LoadPlayer(void); +void KaleidoScopeCall_Init(GlobalContext* globalCtx); +void KaleidoScopeCall_Destroy(GlobalContext* globalCtx); +void KaleidoScopeCall_Update(GlobalContext* globalCtx); +void KaleidoScopeCall_Draw(GlobalContext* globalCtx); // void func_80163C90(void); // void func_80163D80(void); // void func_80163DC0(void); @@ -2950,8 +2937,8 @@ void func_80165438(UNK_PTR param_1); // void func_80165460(void); // void func_80165608(void); // void func_80165630(void); -// void func_80165658(void); -void func_8016566C(s32 arg0); +void func_80165658(u32 arg0); +void func_8016566C(u32 arg0); void func_80165690(void); // void func_801656A4(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE4 param_8); // void func_80165DCC(void); @@ -2970,7 +2957,7 @@ void func_80166B30(GlobalContext* globalCtx); void func_80167814(GlobalContext* globalCtx); void func_80167DE4(GlobalContext* globalCtx); // void func_80167F0C(void); -void func_80168090(GlobalContext* globalCtx); +void Play_Draw(GlobalContext* globalCtx); void func_80168DAC(GlobalContext* globalCtx); void Play_Update(GlobalContext* globalCtx); s32 func_801690CC(GlobalContext* globalCtx); @@ -3004,14 +2991,14 @@ void func_80169E6C(GlobalContext* globalCtx, s32 param_1, s32 param_2); // void func_80169ECC(void); void func_80169EFC(GlobalContext* globalCtx); void func_80169F78(GlobalContext* globalCtx); -// void func_80169FDC(void); +void func_80169FDC(GlobalContext* globalCtx); // void func_80169FFC(void); s32 FrameAdvance_IsEnabled(GlobalContext* globalCtx); // UNK_TYPE4 func_8016A02C(s32 param_1, s32 param_2, s16* param_3); // void func_8016A0AC(void); s32 func_8016A168(void); // void func_8016A178(void); -// void func_8016A268(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE1 param_5, UNK_TYPE1 param_6); +void func_8016A268(GlobalContext* globalCtx, s32 param_2, s32 param_3, s32 param_4, s32 param_5, s32 param_6); void Play_Init(GameState* gameState); // void func_8016AC10(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE4 param_8, UNK_TYPE4 param_9, UNK_TYPE4 param_10); // void func_8016AE1C(void); @@ -3192,7 +3179,7 @@ void Sched_Init(SchedContext* sched, void* stack, OSPri pri, UNK_TYPE arg3, UNK_ void func_801773A0(void* arg0); void func_801773C4(void* arg0); void SpeedMeter_DrawTimeEntries(void* displayList, GraphicsContext* gfxCtx); -// void func_80177A84(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE4 param_8, UNK_TYPE4 param_9); +// void func_80177A84(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE2 param_5, UNK_TYPE4 param_6, UNK_TYPE4 param_7, UNK_TYPE4 param_8, UNK_TYPE4 param_9); //void func_80177AC8(void); void SpeedMeter_DrawAllocEntries(void* displayList, GraphicsContext* gfxCtx, GameState* gameState); void func_801780F0(Mtx* param_1, f32 param_2, f32 param_3, f32 param_4, f32 param_5, f32 param_6, f32 param_7); @@ -3230,7 +3217,7 @@ f32 Rand_ZeroFloat(f32 scale); f32 randPlusMinusPoint5Scaled(f32 scale); f32 Math3D_Normalize(Vec3f* vec); s32 Math3D_PlaneVsLineSegClosestPoint(f32 planeAA, f32 planeAB, f32 planeAC, f32 planeADist, f32 planeBA, f32 planeBB, f32 planeBC, f32 planeBDist, Vec3f* linePointA, Vec3f* linePointB, Vec3f* closestPoint); -// UNK_TYPE4 func_80179798(Vec3f* param_1, Vec3f* param_2, Vec3f* param_3, Vec3f* param_4, Vec3f* param_5, Vec3f* param_6); +s32 func_80179798(Vec3f* param_1, Vec3f* param_2, Vec3f* param_3, Vec3f* param_4, Vec3f* param_5, Vec3f* param_6); // void func_80179A44(void); void func_80179B34(float fParm1, f32 fParm2, f32 fParm5, f32 fParm6, f32 param_5, f32 param_6, f32 param_7, float* param_8, float* param_9); // UNK_TYPE4 func_80179B94(f32 fParm1, f32 fParm2, f32 fParm5, f32 param_4, f32 param_5, f32 param_6, f32 param_7, f32 param_8, Vec3f* param_9); @@ -3371,7 +3358,7 @@ void Matrix_InsertRotationAroundUnitVector_f(f32 rotation, Vec3f* vector, s32 ap void Matrix_InsertRotationAroundUnitVector_s(s16 rotation, Vec3f* vector, s32 appendToState); u64* SysUcode_GetUCodeBoot(void); -u32 SysUcode_GetUCodeBootSize(void); +size_t SysUcode_GetUCodeBootSize(void); u64* SysUcode_GetUCode(void); u64* SysUcode_GetUCodeData(void); @@ -3656,8 +3643,8 @@ AudioTask* func_80192BE0(void); // void func_80194568(void); // void func_80194668(void); // void func_801946E4(void); -// void func_80194710(void); -// void func_80194750(void); +void Audio_InvalDCache(void* buf, size_t size); +void Audio_WritebackDCache(void* buf, size_t size); // void func_80194790(void); // void func_80194840(void); // void func_801948B0(void); @@ -3805,9 +3792,9 @@ void func_8019F230(void); // cancel // void func_8019F258(void); // void func_8019F300(void); void func_8019F420(Vec3f* pos, u16 sfxId); -// void func_8019F4AC(void); +void func_8019F4AC(Vec3f* pos, u16 sfxId); void func_8019F540(u8 arg0); -// void func_8019F570(void); +void func_8019F570(Vec3f* pos, s8 arg1); // void func_8019F5AC(void); // void func_8019F638(void); // void func_8019F780(void); @@ -3816,14 +3803,14 @@ void func_8019F540(u8 arg0); void func_8019F88C(Vec3f* arg0, u16 sfxId, UNK_TYPE arg2); // void func_8019F900(void); // void func_8019FA18(void); -void func_8019FAD8(Vec3f* param_1, u16 param_2, f32 param_3); +void func_8019FAD8(Vec3f* param_1, u16 sfxId, f32 param_3); // void func_8019FB0C(void); // void func_8019FC20(void); // void func_8019FCB8(void); // void func_8019FD90(void); void func_8019FDC8(UNK_PTR arg0, u16 sfxId, UNK_TYPE arg2); // void func_8019FE1C(void); -// void func_8019FE74(void); +void func_8019FE74(f32* arg0, f32 arg1, s32 arg2); // void func_8019FEDC(void); // void func_8019FF38(void); // void func_8019FF9C(void); @@ -3839,7 +3826,7 @@ void func_801A0204(s8 seqId); // void func_801A046C(void); // void func_801A0554(void); // void func_801A05F0(void); -// void func_801A0654(void); +void func_801A0654(Vec3f* arg0, u16 sfxId, s32 arg2); // void func_801A0810(void); // void func_801A0868(void); // void func_801A09D4(void); @@ -3898,7 +3885,7 @@ void func_801A3CD8(s8 param_1); // void func_801A3D98(void); // void func_801A3E38(void); // void func_801A3EC0(void); -// void func_801A3F54(void); +void func_801A3F54(s32 arg0); // void func_801A3F6C(UNK_TYPE1 param_1, UNK_TYPE1 param_2, UNK_TYPE1 param_3, UNK_TYPE1 param_4, UNK_TYPE4 param_5, UNK_TYPE4 param_6); // void func_801A3FB4(void); // void func_801A3FFC(UNK_TYPE1 param_1); @@ -3917,10 +3904,10 @@ void Audio_PreNMI(void); // void func_801A44D4(void); s32 func_801A46F8(void); // void func_801A4748(void); -// void func_801A479C(void); +void func_801A479C(Vec3f* arg0, u16 sfxId, s32 arg2); // void func_801A47DC(void); // void func_801A48E0(void); -// void func_801A4A28(void); +void func_801A4A28(s32 arg0); // void func_801A4B80(void); void func_801A4C30(void); // void func_801A4C54(void); @@ -3932,8 +3919,8 @@ void func_801A4D00(void); // void func_801A4EB0(void); // void func_801A4EB8(void); // void func_801A4FD8(void); -// void func_801A5080(void); -// void func_801A5100(void); +void func_801A5080(u16 arg0); +u16 func_801A5100(void); // void func_801A5118(void); s32 func_801A51F0(s32 errorCode); // void func_801A5228(void); @@ -3962,7 +3949,7 @@ void func_801A5CFC(u16 sfxId, Vec3f* param_2, u8 param_3, f32* param_4, f32* par void func_801A72CC(Vec3f* uParm1); void func_801A7328(Vec3f* pos, u16 sfxId); // void func_801A7484(void); -// void func_801A75E8(void); +void func_801A75E8(u16 sfxId); // void func_801A7720(void); void func_801A7794(u32 param_1, u32 param_2, u32 param_3); // void func_801A7828(void); diff --git a/include/initvars.h b/include/initvars.h index a1dbe1fa1..797e73876 100644 --- a/include/initvars.h +++ b/include/initvars.h @@ -1,6 +1,39 @@ #ifndef _INITVARS_H_ #define _INITVARS_H_ +extern EffectSsInit Effect_Ss_Dust_InitVars; +extern EffectSsInit Effect_Ss_Kirakira_InitVars; +extern EffectSsInit Effect_Ss_Bomb2_InitVars; +extern EffectSsInit Effect_Ss_Blast_InitVars; +extern EffectSsInit Effect_Ss_G_Spk_InitVars; +extern EffectSsInit Effect_Ss_D_Fire_InitVars; +extern EffectSsInit Effect_Ss_Bubble_InitVars; +extern EffectSsInit Effect_Ss_G_Ripple_InitVars; +extern EffectSsInit Effect_Ss_G_Splash_InitVars; +extern EffectSsInit Effect_Ss_G_Fire_InitVars; +extern EffectSsInit Effect_Ss_Lightning_InitVars; +extern EffectSsInit Effect_Ss_Dt_Bubble_InitVars; +extern EffectSsInit Effect_Ss_Hahen_InitVars; +extern EffectSsInit Effect_Ss_Stick_InitVars; +extern EffectSsInit Effect_Ss_Sibuki_InitVars; +extern EffectSsInit Effect_Ss_Stone1_InitVars; +extern EffectSsInit Effect_Ss_Hitmark_InitVars; +extern EffectSsInit Effect_Ss_Fhg_Flash_InitVars; +extern EffectSsInit Effect_Ss_K_Fire_InitVars; +extern EffectSsInit Effect_Ss_Solder_Srch_Ball_InitVars; +extern EffectSsInit Effect_Ss_Kakera_InitVars; +extern EffectSsInit Effect_Ss_Ice_Piece_InitVars; +extern EffectSsInit Effect_Ss_En_Ice_InitVars; +extern EffectSsInit Effect_Ss_Fire_Tail_InitVars; +extern EffectSsInit Effect_Ss_En_Fire_InitVars; +extern EffectSsInit Effect_Ss_Extra_InitVars; +extern EffectSsInit Effect_Ss_Dead_Db_InitVars; +extern EffectSsInit Effect_Ss_Dead_Dd_InitVars; +extern EffectSsInit Effect_Ss_Dead_Ds_InitVars; +extern EffectSsInit Effect_Ss_Ice_Smoke_InitVars; +extern EffectSsInit Effect_En_Ice_Block_InitVars; +extern EffectSsInit Effect_Ss_Sbn_InitVars; + extern ActorInit Arms_Hook_InitVars; extern ActorInit Arrow_Fire_InitVars; extern ActorInit Arrow_Ice_InitVars; diff --git a/include/io/controller.h b/include/io/controller.h index cbd4963ae..9e36f9b62 100644 --- a/include/io/controller.h +++ b/include/io/controller.h @@ -99,8 +99,8 @@ typedef struct { /* 0x00 */ u32 ramarray[15]; - /* 0x3C */ u32 pifstatus; -} OSPifRam; + /* 0x3C */ u32 status; +} OSPifRam; // size = 0x40 typedef struct { diff --git a/include/macros.h b/include/macros.h index 6dc1e5e4e..1afbde243 100644 --- a/include/macros.h +++ b/include/macros.h @@ -63,6 +63,7 @@ ((((void)0, gSaveContext.equips.equipment) & gEquipMasks[equip]) >> gEquipShifts[equip]) #define CUR_UPG_VALUE_VOID(upg) \ ((((void)0, gSaveContext.inventory.upgrades) & gUpgradeMasks[upg]) >> gUpgradeShifts[upg]) +#define INV_CONTENT_VOID(item) ((void)0, gSaveContext.inventory.items)[SLOT(item)] #define CUR_FORM ((gSaveContext.playerForm == PLAYER_FORM_HUMAN) ? 0 : gSaveContext.playerForm) @@ -101,6 +102,7 @@ extern GraphicsContext* __gfxCtx; s32 __dispPad #define CLOSE_DISPS(gfxCtx) \ + (void)0; \ } \ (void)0 diff --git a/include/segment_symbols.h b/include/segment_symbols.h index 004493672..3f02baa5c 100644 --- a/include/segment_symbols.h +++ b/include/segment_symbols.h @@ -73,7 +73,7 @@ DECLARE_OVERLAY_SEGMENT(opening) DECLARE_OVERLAY_SEGMENT(file_choose) DECLARE_OVERLAY_SEGMENT(daytelop) DECLARE_OVERLAY_SEGMENT(kaleido_scope) -DECLARE_OVERLAY_SEGMENT(Player_Actor) +DECLARE_OVERLAY_SEGMENT(player_actor) DECLARE_OVERLAY_SEGMENT(En_Test) DECLARE_OVERLAY_SEGMENT(En_GirlA) diff --git a/include/ultra64/sptask.h b/include/ultra64/sptask.h index e89557267..ef4aa4d04 100644 --- a/include/ultra64/sptask.h +++ b/include/ultra64/sptask.h @@ -2,6 +2,7 @@ #define _SPTASK_H_ #include "PR/ultratypes.h" +#include "libc/stddef.h" /* Task Types */ #define M_NULTASK 0 @@ -80,7 +81,7 @@ typedef struct { /* 0x04 */ u32 flags; /* 0x08 */ u64* ucodeBoot; - /* 0x0C */ u32 ucodeBootSize; + /* 0x0C */ u32 ucodeBootSize; // ucode will load these sizes with lw, so need to be 32-bit /* 0x10 */ u64* ucode; /* 0x14 */ u32 ucodeSize; @@ -101,8 +102,7 @@ typedef struct { /* 0x3C */ u32 yieldDataSize; } OSTask_t; // size = 0x40 -typedef union -{ +typedef union { OSTask_t t; long long int force_structure_alignment; } OSTask; diff --git a/include/variables.h b/include/variables.h index bd2407563..8a006acb4 100644 --- a/include/variables.h +++ b/include/variables.h @@ -18,7 +18,7 @@ extern u16 gFramebuffer1[SCREEN_HEIGHT][SCREEN_WIDTH]; // at 0x80000500 extern u8 D_80025D00[]; // data -extern UNK_TYPE1 D_800969C0; +extern u64 rspbootTextStart[]; extern u8 D_80096B20; extern vu8 gViConfigUseDefault; extern u8 gViConfigAdditionalScanLines; @@ -382,9 +382,7 @@ extern UNK_PTR D_801AE260[3]; // extern UNK_TYPE4 D_801AE2BC; // extern UNK_TYPE4 D_801AE2CC; // extern UNK_TYPE4 D_801AE2DC; -extern F3DVertex sEffectShieldParticleVertices[4]; -extern EffInfo sEffInfoTable[5]; -extern EffectSsInfo EffectSS2Info; +// extern EffectSsInfo sEffectSsInfo; // extern UNK_TYPE1 D_801AE3B0; // extern UNK_TYPE1 D_801AE3B4; // extern UNK_TYPE4 D_801AE3B8; @@ -412,7 +410,7 @@ extern EffectSsInfo EffectSS2Info; // extern UNK_TYPE1 D_801AE48A; // extern UNK_TYPE1 D_801AE48C; // extern UNK_TYPE1 D_801AE490; -extern EffectSsOverlay particleOverlayTable[39]; +extern EffectSsOverlay gParticleOverlayTable[39]; // extern FlagSetEntry sFlagEntries[]; // extern s32 sEntryIndex; // extern u32 sCurrentBit; @@ -870,8 +868,8 @@ extern ColChkVsFunc sOCVsFuncs[COLSHAPE_MAX][COLSHAPE_MAX]; extern CollisionCheckInfo defaultColChkInfo; extern ColChkApplyFunc sApplyDamageFuncs[COLSHAPE_MAX]; extern ColChkLineFunc sOCLineCheckFuncs[COLSHAPE_MAX]; -extern EffShieldParticleInit shieldParticleInitMetal; -extern EffShieldParticleInit shieldParticleInitWood; +extern EffectShieldParticleInit shieldParticleInitMetal; +extern EffectShieldParticleInit shieldParticleInitWood; // extern UNK_TYPE4 D_801BB090; // extern UNK_TYPE1 D_801BB094; // extern UNK_TYPE1 D_801BB0DC; @@ -889,7 +887,6 @@ extern s801BB170 D_801BB170[118]; // extern UNK_TYPE1 D_801BC210; extern Gfx D_801BC240[9]; extern Gfx D_801BC288[3]; -// extern UNK_TYPE1 D_801BC2A0; // extern UNK_TYPE1 D_801BC3F0; // extern UNK_TYPE1 D_801BC400; // extern UNK_TYPE1 D_801BC410; @@ -912,7 +909,7 @@ extern s32 graphNumGameStates; // extern UNK_TYPE2 D_801BDA7C; extern s32 D_801BDA9C; extern UNK_TYPE4 D_801BDAA0; -// extern UNK_TYPE4 D_801BDAA4; +extern UNK_TYPE4 D_801BDAA4; // extern UNK_TYPE2 D_801BDAA8; // extern UNK_TYPE2 D_801BDAAA; // extern UNK_TYPE2 D_801BDAAC; @@ -1263,7 +1260,7 @@ extern UNK_PTR D_801C02F8; // extern UNK_TYPE1 D_801C07F0; // extern UNK_TYPE1 D_801C0820; // extern UNK_TYPE1 D_801C0838; -// extern UNK_TYPE1 D_801C0850; +extern Gfx D_801C0850[]; // extern UNK_TYPE1 D_801C0860; extern UNK_PTR D_801C0870; // extern UNK_TYPE1 D_801C0890; @@ -1553,10 +1550,9 @@ extern char D_801D0714[]; // extern UNK_TYPE1 D_801D08E8; // extern UNK_TYPE1 D_801D0900; extern ActorInit Player_InitVars; -// extern UNK_TYPE1 D_801D0B70; +extern KaleidoMgrOverlay gKaleidoMgrOverlayTable[2]; // extern UNK_TYPE1 D_801D0B8C; -// extern UNK_TYPE4 D_801D0BA8; -// extern UNK_TYPE4 D_801D0BAC; +extern KaleidoMgrOverlay* gKaleidoMgrCurOvl; // extern UNK_TYPE4 D_801D0BB0; // extern UNK_TYPE1 D_801D0C80; // extern UNK_TYPE1 D_801D0CB0; @@ -1632,12 +1628,12 @@ extern PadMgr* padmgrContext; // extern UNK_TYPE4 D_801D1538; extern UNK_PTR D_801D1540; // extern f32 sFactorialTbl[13]; -extern Vec3f D_801D15B0; -extern Vec3s D_801D15BC; -extern Mtx D_801D1DE0; -extern MtxF D_801D1E20; -extern UNK_PTR D_801D1E60; -extern UNK_PTR D_801D1E64; +extern Vec3f gZeroVec3f; +extern Vec3s gZeroVec3s; +extern Mtx gIdentityMtx; +extern MtxF gIdentityMtxF; +// extern u64* initialgspUcodeText; +// extern u64* initialgspUcodeData; // extern UNK_TYPE1 D_801D1E70; // extern UNK_TYPE1 D_801D2E80; // extern UNK_TYPE1 D_801D2F80; @@ -1704,7 +1700,7 @@ extern UNK_PTR D_801D618C; // extern UNK_TYPE1 D_801D6648; // extern UNK_TYPE1 D_801D664C; // extern UNK_TYPE1 D_801D6650; -// extern UNK_TYPE4 D_801D6654; +extern f32 D_801D6654; // extern UNK_TYPE1 D_801D6658; // extern UNK_TYPE1 D_801D665C; // extern UNK_TYPE1 D_801D6660; @@ -1822,14 +1818,14 @@ extern UNK_PTR D_801D8B24; // extern UNK_TYPE1 D_801D8E48; // extern UNK_TYPE1 D_801D8E50; // extern UNK_TYPE1 D_801D8F70; -// extern UNK_TYPE1 D_801D9090; -// extern UNK_TYPE1 D_801D9C10; -// extern UNK_TYPE1 D_801DA350; -// extern UNK_TYPE1 D_801DA510; -// extern UNK_TYPE1 D_801DAC50; -// extern UNK_TYPE1 D_801DADD0; -// extern UNK_TYPE1 D_801DAE10; -extern UNK_PTR D_801DB450; +// extern SfxParams sEnemyBankParams[]; +// extern SfxParams sPlayerBankParams[]; +// extern SfxParams sItemBankParams[]; +// extern SfxParams sEnvBankParams[]; +// extern SfxParams sSystemBankParams[]; +// extern SfxParams sOcarinaBankParams[]; +// extern SfxParams sVoiceBankParams[]; +extern SfxParams* gSfxParams[7]; // extern UNK_TYPE1 D_801DB470; // extern UNK_TYPE1 D_801DB474; extern UNK_PTR D_801DB478[7]; @@ -3090,8 +3086,8 @@ extern f32 D_801E0E24; extern f64 D_801E0EB0; // extern UNK_TYPE4 D_801E1068; extern UNK_PTR D_801E10B0; -// extern UNK_TYPE2 D_801E1102; -// extern UNK_TYPE4 D_801E1104; +extern const s16 gAudioTatumInit[]; +extern const AudioContextInitSizes gAudioContextInitSizes; // extern UNK_TYPE4 D_801E1108; // extern UNK_TYPE4 D_801E110C; // extern UNK_TYPE2 D_801E1180; @@ -3099,21 +3095,13 @@ extern UNK_PTR D_801E10B0; // extern UNK_TYPE2 D_801E1630; // extern UNK_TYPE1 D_801E1E40; // extern UNK_TYPE1 D_801E1E80; -// extern UNK_TYPE1 D_801E2160; -// extern UNK_TYPE1 D_801E3790; +extern u64 gspF3DEX2_NoN_fifoTextStart[]; +extern u64 gspF3DEX2_NoN_fifoDataStart[]; extern u64 gJpegUCodeData[]; // extern UNK_TYPE1 D_801E3FA0; // bss -extern EffTables sEffTable; -// extern UNK_TYPE1 D_801E4514; -// extern UNK_TYPE1 D_801E4E08; -// extern UNK_TYPE1 D_801E531C; -// extern UNK_TYPE1 D_801E69E0; -// extern UNK_TYPE1 D_801E9AA0; -// extern UNK_TYPE1 D_801ED4C0; // extern UNK_TYPE1 D_801ED890; -// extern UNK_TYPE1 D_801ED894; // extern UNK_TYPE1 D_801ED8A0; // extern UNK_TYPE1 D_801ED8B0; // extern UNK_TYPE1 D_801ED8B4; @@ -3198,12 +3186,12 @@ extern Vec3f D_801EE1E0; extern Vec3f D_801EE1F0; // extern UNK_TYPE1 D_801EE1F4; // extern UNK_TYPE1 D_801EE1F8; -extern EffSparkParams D_801EE200; +extern EffectSparkInit D_801EE200; extern TriNorm D_801EE6C8; extern TriNorm D_801EE700; -extern EffSparkParams D_801EE738; -extern EffSparkParams D_801EEC00; -extern EffSparkParams D_801EF0C8; +extern EffectSparkInit D_801EE738; +extern EffectSparkInit D_801EEC00; +extern EffectSparkInit D_801EF0C8; extern TriNorm D_801EF590; extern TriNorm D_801EF5C8; extern TriNorm D_801EF600; @@ -3228,7 +3216,7 @@ extern GameInfo* gGameInfo; // extern UNK_TYPE2 D_801F4DCC[8]; // extern UNK_TYPE1 D_801F4DDC; // extern UNK_TYPE1 D_801F4DE0; -// extern UNK_TYPE2 D_801F4DE2; +extern s16 D_801F4DE2; extern ActorCutscene* actorCutscenes; extern s16 actorCutsceneCount; extern u8 actorCutsceneWaiting[16]; @@ -3317,7 +3305,7 @@ extern Arena sZeldaArena; // extern UNK_TYPE1 D_801F6AD4; // extern UNK_TYPE1 D_801F6AD5; // extern UNK_TYPE1 D_801F6ADA; -// extern UNK_TYPE1 D_801F6AE0; +// extern UNK_TYPE1 sSkyboxDrawMatrix; // extern UNK_TYPE1 D_801F6AF0; // extern UNK_TYPE1 D_801F6AF2; // extern UNK_TYPE4 D_801F6B00; @@ -3343,9 +3331,9 @@ extern ShrinkWindowContext gShrinkWindowContext; extern ShrinkWindowContext* gShrinkWindowContextPtr; // extern UNK_TYPE4 D_801F6B50; // extern UNK_TYPE1 D_801F6B58; -// extern UNK_TYPE1 D_801F6BF0; -// extern UNK_TYPE1 D_801F6C00; -// extern UNK_TYPE1 D_801F6C04; +extern FaultAddrConvClient sKaleidoAreaFaultClient; +extern void (*sKaleidoScopeUpdateFunc)(GlobalContext* globalCtx); +extern void (*sKaleidoScopeDrawFunc)(GlobalContext* globalCtx); // extern UNK_TYPE1 D_801F6C10; extern Input D_801F6C18; // extern UNK_TYPE1 D_801F6C30; @@ -3413,7 +3401,7 @@ extern OSViMode* D_801FBB88; extern u16* gZBufferPtr; extern void* D_801FBB90; extern u64* gGfxSPTaskOutputBufferPtr; -extern u32 gGfxSPTaskOutputBufferSize; +extern size_t gGfxSPTaskOutputBufferSize; // extern UNK_TYPE1 D_801FBB9C; // extern UNK_TYPE1 D_801FBBA0; extern u16 (*gZBuffer)[SCREEN_WIDTH * SCREEN_HEIGHT]; @@ -3785,7 +3773,7 @@ extern u16 gFramebuffer0[SCREEN_HEIGHT][SCREEN_WIDTH]; // keep objects extern Gfx D_040008D0[]; -extern UNK_TYPE D_040032B0; +extern Gfx D_040032B0[]; extern UNK_TYPE D_0400CF58; extern UNK_TYPE D_0400CF88; extern UNK_TYPE D_0400CF98; @@ -3878,16 +3866,9 @@ extern UNK_TYPE D_0400E3D8; extern UNK_TYPE D_0400E408; extern UNK_TYPE D_0400E410; extern UNK_TYPE D_0400E418; -extern CollisionHeader D_0400E710; // Pink Deku Flower collision -extern AnimationHeader D_0400EB7C; // Deku Flower intense flutter animation -extern Gfx D_0400ED80; // Pink Deku Flower display list -extern SkeletonHeader D_04011518; // Pink Deku Flower skeleton -extern AnimationHeader D_040117A8; // Deku Flower small flutter animation -extern CollisionHeader D_040118D8; // Gold Deku Flower collision -extern Gfx D_04011BD0; // Gold Deku Flower display list -extern SkeletonHeader D_040127E8; // Gold Deku Flower skeleton extern UNK_TYPE D_04012860; extern UNK_TYPE D_040128BC; +extern u64 D_04014570[]; extern UNK_TYPE D_04015FA0; extern UNK_TYPE D_04016360; extern UNK_TYPE D_0401A4D0; @@ -3906,24 +3887,18 @@ extern Gfx D_04023210[]; extern UNK_TYPE D_04023288; extern Gfx D_04023348[]; extern Gfx D_04023428[]; -extern UNK_TYPE D_04025850; +extern Gfx D_04025850[]; +extern Gfx D_04025970[]; extern UNK_TYPE D_04025DD0; extern UNK_TYPE D_040281DC; extern UNK_TYPE D_04028FEC; -extern UNK_TYPE D_04029140; +extern AnimationHeader D_04029140; extern Gfx D_04029CB0[]; extern Gfx D_04029CF0[]; extern UNK_TYPE D_04029D20; -extern AnimationHeader D_0402B494; -extern AnimatedMaterial D_0402C818; -extern AnimatedMaterial D_0402C890; -extern AnimatedMaterial D_0402C908; -extern AnimatedMaterial D_0402C980; -extern AnimatedMaterial D_0402C9F8; -extern FlexSkeletonHeader D_0402CA98; extern Gfx D_0402E510[]; -extern UNK_TYPE D_0402E65C; -extern UNK_TYPE D_0402F0EC; +extern AnimationHeader D_0402E65C; +extern AnimationHeader D_0402F0EC; extern Gfx D_04030100[]; // Floor shockwave ring extern Gfx D_040301B0[]; extern UNK_TYPE D_04032270; @@ -3948,9 +3923,10 @@ extern UNK_TYPE D_04050D10; extern UNK_TYPE D_04051180; extern UNK_TYPE D_04051238; extern AnimationHeader D_0405140C; -extern UNK_TYPE D_040527F0; -extern UNK_TYPE D_040528B0; +extern Gfx D_040527F0[]; +extern Gfx D_040528B0[]; extern Gfx D_04054A90[]; +extern u64 D_04054F20[]; extern UNK_TYPE D_04055628; extern Gfx D_04057B10[]; extern Gfx D_04058BA0[]; @@ -3986,10 +3962,11 @@ extern UNK_TYPE D_04062020; extern UNK_TYPE D_04062040; extern UNK_TYPE D_04062060; extern Gfx D_040622C0[]; -extern UNK_TYPE D_0406AB30; +extern Gfx D_0406AB30[]; extern UNK_TYPE D_0406B730; extern UNK_TYPE D_0406BB0C; extern UNK_TYPE D_0406F380; +extern Gfx D_040706E0[]; extern UNK_TYPE D_04073F00; extern UNK_TYPE D_04075400; extern Gfx D_04075A40[]; @@ -4000,7 +3977,7 @@ extern UNK_TYPE D_04079B10; extern Gfx D_0407AB10[]; // sun (sparkles when small) displaylist extern Gfx D_0407AB58[]; extern UNK_TYPE D_0407AFB0; -extern Gfx D_0407D590[]; +extern Gfx gGameplayKeepDrawFlameDL[]; extern UNK_TYPE D_0407D650; extern UNK_TYPE D_0407F218; extern UNK_TYPE D_040815D0; @@ -4011,13 +3988,13 @@ extern UNK_TYPE D_04091CE0; extern Gfx D_05000C40[]; extern UNK_TYPE D_05001D20; -extern UNK_TYPE D_050061E8; -extern UNK_TYPE D_05006420; -extern UNK_TYPE D_050066B0; +extern Gfx D_050061E8[]; +extern Gfx D_05006420[]; +extern Gfx D_050066B0[]; extern UNK_TYPE D_05007498; extern Gfx D_05007890[]; -extern UNK_TYPE D_050078A0; -extern UNK_TYPE D_05007938; +extern Gfx D_050078A0[]; +extern Gfx D_05007938[]; extern Gfx D_05007980[]; extern UNK_TYPE D_05007E00; extern UNK_TYPE D_05008018; @@ -4034,7 +4011,7 @@ extern UNK_TYPE D_0502324C; // other segments extern GfxMasterList D_0E000000; - +extern Mtx D_01000000; extern UNK_TYPE D_0F000000; diff --git a/include/z64.h b/include/z64.h index e8c138e0b..636449c33 100644 --- a/include/z64.h +++ b/include/z64.h @@ -428,6 +428,8 @@ typedef union { // Address at the end of normal RDRAM after which is room for a screen buffer #define FAULT_FB_ADDRESS (NORMAL_RDRAM_END - sizeof(u16[SCREEN_HEIGHT][SCREEN_WIDTH])) +typedef void (*FaultDrawerCallback)(void); + typedef struct { /* 0x00 */ u16* fb; /* 0x04 */ u16 w; @@ -440,7 +442,7 @@ typedef struct { /* 0x12 */ u16 backColor; /* 0x14 */ u16 cursorX; /* 0x16 */ u16 cursorY; - /* 0x18 */ u32* font; + /* 0x18 */ const u32* font; /* 0x1C */ u8 charW; /* 0x1D */ u8 charH; /* 0x1E */ s8 charWPad; @@ -448,7 +450,7 @@ typedef struct { /* 0x20 */ u16 printColors[10]; /* 0x34 */ u8 escCode; /* 0x35 */ u8 osSyncPrintfEnabled; - /* 0x38 */ void* inputCallback; + /* 0x38 */ FaultDrawerCallback inputCallback; } FaultDrawer; // size = 0x3C typedef struct GfxPrint { @@ -700,6 +702,22 @@ typedef struct { /* 0x344 */ u32 unk_344; } InterfaceContext; // size = 0x348 +typedef struct { + /* 0x00 */ void* loadedRamAddr; + /* 0x04 */ uintptr_t vromStart; + /* 0x08 */ uintptr_t vromEnd; + /* 0x0C */ void* vramStart; + /* 0x10 */ void* vramEnd; + /* 0x14 */ uintptr_t offset; // loadedRamAddr - vramStart + /* 0x18 */ const char* name; +} KaleidoMgrOverlay; // size = 0x1C + +typedef enum { + /* 0x00 */ KALEIDO_OVL_KALEIDO_SCOPE, + /* 0x01 */ KALEIDO_OVL_PLAYER_ACTOR, + /* 0x02 */ KALEID_OVL_MAX +} KaleidoMgrOverlayType; + typedef struct { /* 0x00 */ u16 unk_0; /* 0x02 */ u16 unk_2; @@ -764,11 +782,10 @@ typedef struct { typedef struct { /* 0x00000 */ View view; - /* 0x00168 */ void* skyboxStaticSegment[2]; - /* 0x00170 */ char unk170[8]; // more static segments? + /* 0x00168 */ void* skyboxStaticSegment[4]; /* 0x00178 */ void* skyboxPaletteStaticSegment; - /* 0x0017C */ Gfx* unk17C; - /* 0x00180 */ Gfx* unk180; + /* 0x0017C */ Gfx* dListBuf; + /* 0x00180 */ Gfx* roomDL; /* 0x00184 */ Vtx* roomVtx; /* 0x00188 */ DmaRequest unk188; /* 0x001A8 */ DmaRequest unk1A8; @@ -789,6 +806,10 @@ typedef struct { /* 0x00227 */ u8 envB; } SkyboxContext; // size = 0x228 +typedef enum { + /* 0x05 */ SKYBOX_CUTSCENE_MAP = 5 +} SkyboxId; + typedef struct ListAlloc { /* 0x00 */ struct ListAlloc* prev; /* 0x04 */ struct ListAlloc* next; @@ -1253,14 +1274,8 @@ struct FireObj { struct TargetContext { /* 0x00 */ Vec3f unk0; /* 0x0C */ Vec3f unkC; - /* 0x18 */ f32 unk18; - /* 0x1C */ f32 unk1C; - /* 0x20 */ f32 unk20; - /* 0x24 */ f32 unk24; - /* 0x28 */ f32 unk28; - /* 0x2C */ f32 unk2C; - /* 0x30 */ f32 unk30; - /* 0x34 */ f32 unk34; + /* 0x18 */ Color_RGBAf unk18; + /* 0x28 */ Color_RGBAf unk28; /* 0x38 */ Actor* unk38; /* 0x3C */ Actor* unk3C; /* 0x40 */ f32 unk40; @@ -1396,9 +1411,9 @@ struct GlobalContext { /* 0x18794 */ void* unk_18794; //! @TODO: Determine function prototype /* 0x18798 */ s32 (*setPlayerTalkAnim)(struct GlobalContext* globalCtx, void* talkAnim, s32 arg2); /* 0x1879C */ s16 unk_1879C[10]; - /* 0x187B0 */ MtxF projectionMatrix; + /* 0x187B0 */ MtxF viewProjectionMtxF; /* 0x187F0 */ Vec3f unk_187F0; - /* 0x187FC */ MtxF mf_187FC; + /* 0x187FC */ MtxF billboardMtxF; /* 0x1883C */ Mtx* unk_1883C; /* 0x18840 */ u32 gameplayFrames; /* 0x18844 */ u8 unk_18844; @@ -1457,6 +1472,30 @@ typedef struct { /* 0x24 */ s16 unk_24; } struct_800BD888_arg1; // size = 0x28 +typedef struct EnHy { + /* 0x000 */ Actor actor; + /* 0x144 */ UNK_TYPE1 unk_144[0x8]; + /* 0x14C */ SkelAnime skelAnime; + /* 0x190 */ s8 unk190; + /* 0x191 */ s8 unk191; + /* 0x192 */ s8 unk192; + /* 0x193 */ s8 animObjIndex; + /* 0x194 */ ColliderCylinder collider; + /* 0x1E0 */ UNK_TYPE1 unk_1E0[0x4]; + /* 0x1E4 */ Path* path; + /* 0x1E8 */ s16 curPoint; + /* 0x1EA */ UNK_TYPE1 unk_1EA[0x2]; + /* 0x1EC */ Vec3f leftFootPos; + /* 0x1F8 */ Vec3f rightFootPos; + /* 0x204 */ u8 isLeftFootOnGround; + /* 0x205 */ u8 isRightFootOnGround; + /* 0x206 */ Vec3s jointTable[16]; + /* 0x266 */ Vec3s morphTable[16]; + /* 0x2C6 */ UNK_TYPE1 unk_2C6[0x120]; + /* 0x3E6 */ s16 eyeTexIndex; + /* 0x3E8 */ s16 blinkTimer; +} EnHy; + typedef struct { /* 0x0 */ u8 unk0; /* 0x4 */ s32 unk4; @@ -1465,7 +1504,7 @@ typedef struct { typedef s32 (*func_8013E748_arg6)(struct GlobalContext*, Actor*, Vec3s*); -typedef s32 (*func_8013E640_arg6)(struct GlobalContext*, Actor*, Actor*, void*); +typedef s32 (*VerifyActor)(struct GlobalContext*, Actor*, Actor*, void*); struct struct_8013DF3C_arg1; typedef void (*struct_8013DF3C_arg1_unk_func1)(struct GlobalContext*, struct struct_8013DF3C_arg1*); diff --git a/include/z64actor.h b/include/z64actor.h index 2b35bec24..9cbf9885e 100644 --- a/include/z64actor.h +++ b/include/z64actor.h @@ -15,6 +15,8 @@ struct GlobalContext; struct Lights; struct CollisionPoly; +struct EnDoor; + typedef void(*ActorFunc)(struct Actor* this, struct GlobalContext* globalCtx); typedef struct { diff --git a/include/z64animation.h b/include/z64animation.h index abd95423b..8d6df14c8 100644 --- a/include/z64animation.h +++ b/include/z64animation.h @@ -49,6 +49,14 @@ typedef struct { /* 0x08 */ Gfx* dLists[2]; // Near and far } LodLimb; // size = 0x10 +typedef struct { + /* 0x00 */ Vec3s jointPos; // Root is position in model space, children are relative to parent + /* 0x06 */ u8 child; + /* 0x07 */ u8 sibling; + /* 0x08 */ s32 unk_8; // Type of data contained in segment + /* 0x0C */ void* segment; // Segment address of data. Currently unclear what. +} SkinLimb; // size = 0x10 + // Model has limbs with only rigid meshes typedef struct { /* 0x00 */ void** segment; @@ -271,6 +279,43 @@ typedef s32 (*OverrideCurveLimbDraw)(struct GlobalContext* globalCtx, SkelAnimeC typedef void (*PostCurveLimbDraw)(struct GlobalContext* globalCtx, SkelAnimeCurve* skelCuve, s32 limbIndex, struct Actor* actor); +// TODO the name of this struct is imported from OoT and cannot change until the ZAPD name also changes +typedef struct { + /* 0x000 */ u16 unk_0; + /* 0x002 */ s16 unk_2; + /* 0x004 */ s16 unk_4; + /* 0x006 */ s8 unk_6; + /* 0x007 */ s8 unk_7; + /* 0x008 */ s8 unk_8; + /* 0x009 */ u8 unk_9; +} Struct_800A57C0; // size = 0xA + +// TODO the name of this struct is imported from OoT and cannot change until the ZAPD name also changes +typedef struct { + /* 0x000 */ u8 unk_0; + /* 0x002 */ s16 x; + /* 0x004 */ s16 y; + /* 0x006 */ s16 z; + /* 0x008 */ u8 unk_8; +} Struct_800A598C_2; // size = 0xA + +// TODO the name of this struct is imported from OoT and cannot change until the ZAPD name also changes +typedef struct { + /* 0x000 */ u16 unk_0; + /* 0x002 */ u16 unk_2; + /* 0x004 */ u16 unk_4; + /* 0x008 */ Struct_800A57C0* unk_8; + /* 0x00C */ Struct_800A598C_2* unk_C; +} Struct_800A598C; // size = 0x10 + +// TODO the name of this struct is imported from OoT and cannot change until the ZAPD name also changes +typedef struct { + /* 0x000 */ u16 unk_0; + /* 0x002 */ u16 unk_2; + /* 0x004 */ Struct_800A598C* unk_4; + /* 0x008 */ Gfx* unk_8; +} Struct_800A5E28; // size = 0xC + typedef struct struct_80B8E1A8 { /* 0x00 */ AnimationHeader* animationSeg; /* 0x04 */ f32 playbackSpeed; diff --git a/include/z64cutscene.h b/include/z64cutscene.h index 51e60799e..0f2a6e678 100644 --- a/include/z64cutscene.h +++ b/include/z64cutscene.h @@ -29,11 +29,11 @@ typedef struct { /* 0x00 */ u16 unk0; // action; // "dousa" /* 0x02 */ u16 startFrame; /* 0x04 */ u16 endFrame; - /* 0x06 */ UNK_TYPE1 pad6[0xA]; - /* 0x10 */ s32 unk10; - /* 0x14 */ UNK_TYPE1 pad14[0x8]; - /* 0x1C */ s32 unk1C; - /* 0x20 */ UNK_TYPE1 pad20[0x10]; + /* 0x06 */ u16 unk6; + /* 0x08 */ u16 unk8; + /* 0x0C */ Vec3i unk0C; + /* 0x18 */ Vec3i unk18; + /* 0x24 */ UNK_TYPE1 unk24[0xC]; } CsCmdActorAction; // size = 0x30 typedef struct { diff --git a/include/z64effect.h b/include/z64effect.h index adb690732..d9211ef5e 100644 --- a/include/z64effect.h +++ b/include/z64effect.h @@ -10,14 +10,6 @@ struct GraphicsContext; struct GlobalContext; -typedef void(*eff_destroy_func)(void* params); - -typedef void(*eff_draw_func)(void* params, struct GraphicsContext* gfxCtx); - -typedef void(*eff_init_func)(void* params, void* init); - -typedef s32(*eff_update_func)(void* params); - #define SPARK_COUNT 3 #define BLURE_COUNT 25 #define SHIELD_PARTICLE_COUNT 3 @@ -41,37 +33,45 @@ typedef s32(*eff_update_func)(void* params); #define rgObjBankIdx regs[11] typedef struct { - /* 0x0 */ u8 active; - /* 0x1 */ u8 unk1; - /* 0x2 */ u8 unk2; - /* 0x3 */ UNK_TYPE1 pad3[0x1]; -} EffCommon; // size = 0x4 + /* 0x00 */ u8 active; + /* 0x01 */ u8 unk1; + /* 0x02 */ u8 unk2; +} EffectStatus; // size = 0x03 typedef struct { /* 0x00 */ Vec3f velocity; /* 0x0C */ Vec3f position; - /* 0x18 */ Vec3s unk18; - /* 0x1E */ Vec3s unk1E; -} EffSparkParticle; // size = 0x24 + /* 0x18 */ Vec3s unkVelocity; + /* 0x1E */ Vec3s unkPosition; +} EffectSparkElement; // size = 0x24 typedef struct { /* 0x000 */ Vec3s position; - /* 0x008 */ s32 numParticles; // Will be calculated as particleFactor1 * particleFactor2 + 2 - /* 0x00C */ EffSparkParticle particles[32]; - /* 0x48C */ f32 velocity; + /* 0x008 */ s32 numElements; // "table_size"; calculated as uDiv * vDiv + 2 + /* 0x00C */ EffectSparkElement elements[32]; + /* 0x48C */ f32 speed; /* 0x490 */ f32 gravity; - /* 0x494 */ u32 particleFactor1; - /* 0x498 */ u32 particleFactor2; + /* 0x494 */ u32 uDiv; // "u_div" + /* 0x498 */ u32 vDiv; // "v_div" /* 0x49C */ Color_RGBA8 colorStart[4]; /* 0x4AC */ Color_RGBA8 colorEnd[4]; - /* 0x4BC */ s32 age; + /* 0x4BC */ s32 timer; /* 0x4C0 */ s32 duration; -} EffSparkParams; // size = 0x4C4 +} EffectSparkInit; // size = 0x4C4 typedef struct { - /* 0x000 */ EffCommon base; - /* 0x004 */ EffSparkParams params; -} EffSpark; // size = 0x4C8 + /* 0x000 */ Vec3s position; + /* 0x008 */ s32 numElements; // "table_size"; calculated as uDiv * vDiv + 2 + /* 0x00C */ EffectSparkElement elements[32]; + /* 0x48C */ f32 speed; + /* 0x490 */ f32 gravity; + /* 0x494 */ u32 uDiv; // "u_div" + /* 0x498 */ u32 vDiv; // "v_div" + /* 0x49C */ Color_RGBA8 colorStart[4]; + /* 0x4AC */ Color_RGBA8 colorEnd[4]; + /* 0x4BC */ s32 timer; + /* 0x4C0 */ s32 duration; +} EffectSpark; // size = 0x4C4 typedef struct { /* 0x00 */ s32 state; @@ -82,13 +82,15 @@ typedef struct { } EffectBlureElement; // size = 0x18 typedef struct { - /* 0x000 */ UNK_TYPE1 pad0[0x184]; - /* 0x184 */ Color_RGBA8 unk184; - /* 0x188 */ Color_RGBA8 unk188; - /* 0x18C */ Color_RGBA8 unk18C; - /* 0x190 */ Color_RGBA8 unk190; - /* 0x194 */ UNK_TYPE1 pad194[0xC]; -} EffBlureInit1; // size = 0x1A0 + /* 0x000 */ char unk_00[0x184]; + /* 0x184 */ u8 p1StartColor[4]; + /* 0x188 */ u8 p2StartColor[4]; + /* 0x18C */ u8 p1EndColor[4]; + /* 0x190 */ u8 p2EndColor[4]; + /* 0x194 */ s32 elemDuration; + /* 0x198 */ s32 unkFlag; + /* 0x19C */ s32 calcMode; +} EffectBlureInit1; // size = 0x1A0 typedef struct { /* 0x00 */ s32 calcMode; @@ -104,7 +106,7 @@ typedef struct { /* 0x1B */ u8 mode4Param; /* 0x1C */ Color_RGBA8 altPrimColor; // used with drawMode 1 /* 0x20 */ Color_RGBA8 altEnvColor; // used with drawMode 1 -} EffBlureInit2; // size = 0x24 +} EffectBlureInit2; // size = 0x24 typedef struct { /* 0x000 */ EffectBlureElement elements[16]; @@ -117,31 +119,26 @@ typedef struct { /* 0x192 */ Color_RGBA8 p2StartColor; /* 0x196 */ Color_RGBA8 p1EndColor; /* 0x19A */ Color_RGBA8 p2EndColor; - /* 0x19E */ u8 numElements; + /* 0x19E */ u8 numElements; // "now_edge_num" /* 0x19F */ u8 elemDuration; /* 0x1A0 */ u8 unkFlag; /* 0x1A1 */ u8 drawMode; // 0: simple; 1: simple with alt colors; 2+: smooth - /* 0x1A2 */ Color_RGBA8 altPrimColor; - /* 0x1A6 */ Color_RGBA8 altEnvColor; + /* 0x1A2 */ Color_RGBA8 altPrimColor; // used with drawMode 1 + /* 0x1A6 */ Color_RGBA8 altEnvColor; // used with drawMode 1 } EffectBlure; // size = 0x1AC typedef struct { - /* 0x000 */ EffCommon base; - /* 0x004 */ EffectBlure params; -} EffBlure; // size = 0x1B0 - -typedef struct { - /* 0x00 */ f32 startSpeed; + /* 0x00 */ f32 initialSpeed; /* 0x04 */ f32 endXChange; /* 0x08 */ f32 endX; /* 0x0C */ f32 startXChange; /* 0x10 */ f32 startX; - /* 0x14 */ s16 rotationY; - /* 0x16 */ s16 rotationZ; -} EffShieldParticleParticle; // size = 0x18 + /* 0x14 */ s16 yaw; + /* 0x16 */ s16 pitch; +} EffectShieldParticleElement; // size = 0x18 typedef struct { - /* 0x00 */ u8 numParticles; + /* 0x00 */ u8 numElements; /* 0x02 */ Vec3s position; /* 0x08 */ Color_RGBA8 primColorStart; /* 0x0C */ Color_RGBA8 envColorStart; @@ -149,18 +146,17 @@ typedef struct { /* 0x14 */ Color_RGBA8 envColorMid; /* 0x18 */ Color_RGBA8 primColorEnd; /* 0x1C */ Color_RGBA8 envColorEnd; - /* 0x20 */ f32 acceleration; + /* 0x20 */ f32 deceleration; /* 0x24 */ f32 maxInitialSpeed; /* 0x28 */ f32 lengthCutoff; /* 0x2C */ u8 duration; /* 0x2E */ LightPoint lightPoint; - /* 0x3C */ s32 hasLight; -} EffShieldParticleInit; // size = 0x40 + /* 0x3C */ s32 lightDecay; // halves light radius every frame when set to 1 +} EffectShieldParticleInit; // size = 0x40 typedef struct { - /* 0x000 */ EffShieldParticleParticle particles[16]; - /* 0x180 */ u8 numParticles; - /* 0x181 */ UNK_TYPE1 pad181[0x1]; + /* 0x000 */ EffectShieldParticleElement elements[16]; + /* 0x180 */ u8 numElements; /* 0x182 */ Vec3s position; /* 0x188 */ Color_RGBA8 primColorStart; /* 0x18C */ Color_RGBA8 envColorStart; @@ -168,66 +164,75 @@ typedef struct { /* 0x194 */ Color_RGBA8 envColorMid; /* 0x198 */ Color_RGBA8 primColorEnd; /* 0x19C */ Color_RGBA8 envColorEnd; - /* 0x1A0 */ f32 acceleration; - /* 0x1A4 */ UNK_TYPE1 pad1A4[0x4]; + /* 0x1A0 */ f32 deceleration; + /* 0x1A4 */ char unk_1A4[0x04]; /* 0x1A8 */ f32 maxInitialSpeed; /* 0x1AC */ f32 lengthCutoff; /* 0x1B0 */ u8 duration; - /* 0x1B1 */ u8 age; + /* 0x1B1 */ u8 timer; /* 0x1B2 */ LightInfo lightInfo; - /* 0x1C0 */ LightNode* light; - /* 0x1C4 */ s32 hasLight; -} EffShieldParticleParams; // size = 0x1C8 + /* 0x1C0 */ LightNode* lightNode; + /* 0x1C4 */ s32 lightDecay; // halves light radius every frame when set to 1 +} EffectShieldParticle; // size = 0x1C8 typedef struct { - /* 0x000 */ EffCommon base; - /* 0x004 */ EffShieldParticleParams params; -} EffShieldParticle; // size = 0x1CC - -typedef struct { - /* 0x00 */ UNK_TYPE2 active; - /* 0x02 */ Vec3s position1; - /* 0x08 */ Vec3s position2; + /* 0x00 */ u16 flags; + /* 0x02 */ Vec3s p1; + /* 0x08 */ Vec3s p2; /* 0x0E */ s16 life; /* 0x10 */ UNK_TYPE1 pad10[0x4]; - /* 0x14 */ UNK_TYPE4 unk14; -} EffTireMarkParticle; // size = 0x18 + /* 0x14 */ CollisionPoly* colPoly; +} EffectTireMarkElement; // size = 0x18 typedef struct { /* 0x0 */ s16 unk0; - /* 0x2 */ s16 maxLife; + /* 0x2 */ s16 elemDuration; /* 0x4 */ Color_RGBA8 color; -} EffTireMarkInit; // size = 0x8 +} EffectTireMarkInit; // size = 0x8 typedef struct { - /* 0x000 */ EffTireMarkParticle particles[64]; + /* 0x000 */ EffectTireMarkElement elements[64]; /* 0x600 */ s16 unk600; - /* 0x602 */ s16 numParticles; - /* 0x604 */ s16 maxLife; + /* 0x602 */ s16 numElements; + /* 0x604 */ s16 elemDuration; /* 0x606 */ Color_RGBA8 color; - /* 0x60A */ UNK_TYPE1 pad60A[0x2]; -} EffTireMarkParams; // size = 0x60C - -typedef struct { - /* 0x000 */ EffCommon base; - /* 0x004 */ EffTireMarkParams params; -} EffTireMark; // size = 0x610 - -typedef struct { - /* 0x00 */ u32 paramsSize; - /* 0x04 */ eff_init_func init; - /* 0x08 */ eff_destroy_func destroy; - /* 0x0C */ eff_update_func update; - /* 0x10 */ eff_draw_func draw; -} EffInfo; // size = 0x14 +} EffectTireMark; // size = 0x60C typedef struct { /* 0x0000 */ struct GlobalContext* globalCtx; - /* 0x0004 */ EffSpark sparks[SPARK_COUNT]; - /* 0x0E5C */ EffBlure blures[BLURE_COUNT]; - /* 0x388C */ EffShieldParticle shieldParticles[SHIELD_PARTICLE_COUNT]; - /* 0x3DF0 */ EffTireMark tireMarks[TIRE_MARK_COUNT]; -} EffTables; // size = 0x98E0 + struct { + EffectStatus status; + EffectSpark effect; + } /* 0x0004 */ sparks[SPARK_COUNT]; + struct { + EffectStatus status; + EffectBlure effect; + } /* 0x0E5C */ blures[BLURE_COUNT]; + struct { + EffectStatus status; + EffectShieldParticle effect; + } /* 0x388C */ shieldParticles[SHIELD_PARTICLE_COUNT]; + struct { + EffectStatus status; + EffectTireMark effect; + } /* 0x3DF0 */ tireMarks[TIRE_MARK_COUNT]; +} EffectContext; // size = 0x98E0 + +typedef struct { + /* 0x00 */ u32 size; + /* 0x04 */ void (*init)(void* effect, void* initParams); + /* 0x08 */ void (*destroy)(void* effect); + /* 0x0C */ s32 (*update)(void* effect); + /* 0x10 */ void (*draw)(void* effect, struct GraphicsContext* gfxCtx); +} EffectInfo; // size = 0x14 + +typedef enum { + /* 0x00 */ EFFECT_SPARK, + /* 0x01 */ EFFECT_BLURE1, + /* 0x02 */ EFFECT_BLURE2, + /* 0x03 */ EFFECT_SHIELD_PARTICLE, + /* 0x04 */ EFFECT_TIRE_MARK +} EffectType; /* Effect Soft Sprites */ @@ -249,7 +254,7 @@ typedef struct { /* 0x0C */ void* vramEnd; /* 0x10 */ void* loadedRamAddr; /* 0x14 */ EffectSsInit* initInfo; - /* 0x18 */ u32 unk18; // Always 0x01000000? + /* 0x18 */ u8 unk18; // Always 1? } EffectSsOverlay; // size = 0x1C typedef struct EffectSs { @@ -274,27 +279,6 @@ typedef struct { /* 0x8 */ s32 size; } EffectSsInfo; // size = 0xC -typedef struct { - /* 0x0 */ EffectSs* data_table; // Name from debug assert - /* 0x4 */ s32 searchIndex; - /* 0x8 */ s32 size; -} EffectTableInfo; // size = 0xC - -typedef struct { - /* 0x0 */ UNK_TYPE4 unk0; - /* 0x4 */ EffectSsInitFunc init; -} ParticleOverlayInfo; // size = 0x8 - -typedef struct { - /* 0x00 */ u32 vromStart; - /* 0x04 */ u32 vromEnd; - /* 0x08 */ void* vramStart; - /* 0x0C */ void* vramEnd; - /* 0x10 */ void* loadedRamAddr; - /* 0x14 */ ParticleOverlayInfo* overlayInfo; - /* 0x18 */ u32 unk18; // Always 0x01000000? -} ParticleOverlay; // size = 0x1C - typedef enum { /* 0x00 */ EFFECT_SS_DUST, /* 0x01 */ EFFECT_SS_KIRAKIRA, diff --git a/include/z64item.h b/include/z64item.h index a312e6961..af9c94233 100644 --- a/include/z64item.h +++ b/include/z64item.h @@ -57,7 +57,7 @@ typedef enum { /* 0x07 */ SLOT_BOMBCHU, /* 0x08 */ SLOT_STICK, /* 0x09 */ SLOT_NUT, - /* 0x0A */ SLOT_BEAN, + /* 0x0A */ SLOT_MAGIC_BEANS, /* 0x0B */ SLOT_TRADE_KEY_MAMA, /* 0x0C */ SLOT_POWDER_KEG, /* 0x0D */ SLOT_PICTO_BOX, @@ -85,7 +85,7 @@ typedef enum { /* 0x23 */ SLOT_MASK_GORON, /* 0x24 */ SLOT_MASK_ROMANI, /* 0x25 */ SLOT_MASK_CIRCUS_LEADER, - /* 0x26 */ SLOT_MASK_KAFEI, + /* 0x26 */ SLOT_MASK_KAFEIS_MASK, /* 0x27 */ SLOT_MASK_COUPLE, /* 0x28 */ SLOT_MASK_TRUTH, /* 0x29 */ SLOT_MASK_ZORA, @@ -109,7 +109,7 @@ typedef enum { /* 0x07 */ ITEM_BOMBCHU, /* 0x08 */ ITEM_STICK, /* 0x09 */ ITEM_NUT, - /* 0x0A */ ITEM_BEAN, + /* 0x0A */ ITEM_MAGIC_BEANS, /* 0x0B */ ITEM_SLINGSHOT, /* 0x0C */ ITEM_POWDER_KEG, /* 0x0D */ ITEM_PICTO_BOX, @@ -146,7 +146,7 @@ typedef enum { /* 0x2C */ ITEM_DEED_OCEAN, /* 0x2D */ ITEM_ROOM_KEY, /* 0x2E */ ITEM_LETTER_MAMA, - /* 0x2F */ ITEM_LETTER_KAFEI, + /* 0x2F */ ITEM_LETTER_TO_KAFEI, /* 0x30 */ ITEM_PENDANT_MEMORIES, /* 0x31 */ ITEM_TINGLE_MAP, /* 0x32 */ ITEM_MASK_DEKU, @@ -154,7 +154,7 @@ typedef enum { /* 0x34 */ ITEM_MASK_ZORA, /* 0x35 */ ITEM_MASK_FIERCE_DEITY, /* 0x36 */ ITEM_MASK_TRUTH, - /* 0x37 */ ITEM_MASK_KAFEI, + /* 0x37 */ ITEM_MASK_KAFEIS_MASK, /* 0x38 */ ITEM_MASK_ALL_NIGHT, /* 0x39 */ ITEM_MASK_BUNNY, /* 0x3A */ ITEM_MASK_KEATON, @@ -275,6 +275,7 @@ typedef enum { /* 0x07 */ GI_RUPEE_HUGE, /* 0x08 */ GI_WALLET_ADULT, /* 0x09 */ GI_WALLET_GIANT, + /* 0x0A */ GI_RECOVERY_HEART, /* 0x0C */ GI_HEART_PIECE = 0x0C, /* 0x0D */ GI_HEART_CONTAINER, /* 0x16 */ GI_BOMBS_10 = 0x16, @@ -294,9 +295,11 @@ typedef enum { /* 0x2A */ GI_NUTS_10 = 0x2A, /* 0x32 */ GI_SHIELD_HERO = 0x32, /* 0x33 */ GI_SHIELD_MIRROR, + /* 0x35 */ GI_MAGIC_BEANS = 0x35, /* 0x3C */ GI_KEY_SMALL = 0x3C, /* 0x3E */ GI_MAP = 0x3E, /* 0x3F */ GI_COMPASS, + /* 0x52 */ GI_SCALE_GOLD = 0x52, // Assumed, used in En_Fishing /* 0x59 */ GI_BOTTLE_POTION_RED = 0x59, /* 0x5B */ GI_POTION_RED = 0x5B, /* 0x5C */ GI_POTION_GREEN, @@ -308,7 +311,7 @@ typedef enum { /* 0x7A */ GI_MASK_ZORA, /* 0x7B */ GI_MASK_FIERCE_DEITY, /* 0x7C */ GI_MASK_TRUTH, - /* 0x7D */ GI_MASK_KAFEI, + /* 0x7D */ GI_MASK_KAFEIS_MASK, /* 0x7E */ GI_MASK_ALL_NIGHT, /* 0x7F */ GI_MASK_BUNNY, /* 0x80 */ GI_MASK_KEATON, @@ -327,6 +330,7 @@ typedef enum { /* 0x8D */ GI_MASK_BLAST, /* 0x8E */ GI_MASK_SCENTS, /* 0x8F */ GI_MASK_GIANT, + /* 0x92 */ GI_MILK = 0x92, /* 0x96 */ GI_MOON_TEAR = 0x96, /* 0x97 */ GI_DEED_LAND, /* 0x98 */ GI_DEED_SWAMP, diff --git a/include/z64math.h b/include/z64math.h index 3caad9108..dff669976 100644 --- a/include/z64math.h +++ b/include/z64math.h @@ -85,9 +85,10 @@ typedef struct { /* 0x06 */ s16 yaw; // azimuthal angle } VecSph; // size = 0x08 -#define F32_LERP(v0,v1,t) ((1.0f - (t)) * (v0) + (t) * (v1)) -#define F32_LERPIMP(v0, v1, t) (v0 + ((v1 - v0) * t)) -#define F32_LERPIMPINV(v0, v1, t) ((v0) + (((v1) - (v0)) / (t))) +#define LERPIMP(v0, v1, t) ((v0) + (((v1) - (v0)) * (t))) +#define F32_LERP(v0, v1, t) ((1.0f - (t)) * (f32)(v0) + (t) * (f32)(v1)) +#define F32_LERPIMP(v0, v1, t) ((f32)(v0) + (((f32)(v1) - (f32)(v0)) * (t))) +#define F32_LERPIMPINV(v0, v1, t) ((f32)(v0) + (((f32)(v1) - (f32)(v0)) / (t))) #define BINANG_LERPIMP(v0, v1, t) ((v0) + (s16)(BINANG_SUB((v1), (v0)) * (t))) #define BINANG_LERPIMPINV(v0, v1, t) ((v0) + BINANG_SUB((v1), (v0)) / (t)) diff --git a/include/z64object.h b/include/z64object.h index 920a9e5dd..08423ab6c 100644 --- a/include/z64object.h +++ b/include/z64object.h @@ -207,7 +207,7 @@ typedef enum { /* 0x0C3 */ OBJECT_GI_SHIELD_3, /* 0x0C4 */ OBJECT_UNSET_C4, /* 0x0C5 */ OBJECT_UNSET_C5, - /* 0x0C6 */ OBJECT_GI_BEAN, + /* 0x0C6 */ OBJECT_GI_MAGIC_BEANS, /* 0x0C7 */ OBJECT_GI_FISH, /* 0x0C8 */ OBJECT_UNSET_C8, /* 0x0C9 */ OBJECT_UNSET_C9, diff --git a/include/z64player.h b/include/z64player.h index e20b26ca7..6b156372e 100644 --- a/include/z64player.h +++ b/include/z64player.h @@ -36,7 +36,7 @@ typedef enum { typedef enum { /* 0x00 */ PLAYER_MASK_NONE, /* 0x01 */ PLAYER_MASK_TRUTH, - /* 0x02 */ PLAYER_MASK_KAFEI, + /* 0x02 */ PLAYER_MASK_KAFEIS_MASK, /* 0x03 */ PLAYER_MASK_ALL_NIGHT, /* 0x04 */ PLAYER_MASK_BUNNY, /* 0x05 */ PLAYER_MASK_KEATON, @@ -106,15 +106,15 @@ typedef enum { /* 0x2A */ PLAYER_AP_MOON_TEAR, /* 0x2B */ PLAYER_AP_DEED_LAND, /* 0x2C */ PLAYER_AP_ROOM_KEY, - /* 0x2D */ PLAYER_AP_LETTER_KAFEI, - /* 0x2E */ PLAYER_AP_BEAN, + /* 0x2D */ PLAYER_AP_LETTER_TO_KAFEI, + /* 0x2E */ PLAYER_AP_MAGIC_BEANS, /* 0x2F */ PLAYER_AP_DEED_SWAMP, /* 0x30 */ PLAYER_AP_DEED_MOUNTAIN, /* 0x31 */ PLAYER_AP_DEED_OCEAN, /* 0x33 */ PLAYER_AP_LETTER_MAMA = 0x33, /* 0x36 */ PLAYER_AP_PENDANT_MEMORIES = 0x36, /* 0x3A */ PLAYER_AP_MASK_TRUTH = 0x3A, - /* 0x3B */ PLAYER_AP_MASK_KAFEI, + /* 0x3B */ PLAYER_AP_MASK_KAFEIS_MASK, /* 0x3C */ PLAYER_AP_MASK_ALL_NIGHT, /* 0x3D */ PLAYER_AP_MASK_BUNNY, /* 0x3E */ PLAYER_AP_MASK_KEATON, diff --git a/include/z64save.h b/include/z64save.h index a1ec72ab9..63d0372dc 100644 --- a/include/z64save.h +++ b/include/z64save.h @@ -67,7 +67,7 @@ typedef struct { /* 0x0039 */ s8 magic; // "magic_now" /* 0x003A */ s16 rupees; // "lupy_count" /* 0x003C */ u16 swordHealth; // "long_sword_hp" - /* 0x003E */ u16 naviTimer; // "navi_timer" + /* 0x003E */ u16 tatlTimer; // "navi_timer" /* 0x0040 */ u8 magicAcquired; // "magic_mode" /* 0x0041 */ u8 doubleMagic; // "magic_ability" /* 0x0042 */ u8 doubleDefense; // "life_ability" diff --git a/spec b/spec index c23e832ba..8eadc3594 100644 --- a/spec +++ b/spec @@ -27,7 +27,6 @@ beginseg include "build/src/boot_O2_g3/fault.o" include "build/data/boot/fault.bss.o" include "build/src/boot_O2_g3/fault_drawer.o" - include "build/data/boot/fault_drawer.bss.o" include "build/src/boot_O2/boot_80084940.o" include "build/src/boot_O2/loadfragment.o" include "build/data/boot/loadfragment.data.o" @@ -121,8 +120,6 @@ beginseg include "build/src/libultra/io/devmgr.o" include "build/src/libultra/io/pirawdma.o" include "build/src/libultra/io/contpfs.o" - include "build/data/boot/contpfs.data.o" - include "build/data/boot/contpfs.bss.o" include "build/asm/boot/getcount.text.o" pad_text include "build/asm/boot/guMtxL2F.text.o" @@ -313,7 +310,7 @@ beginseg name "icon_item_gameover_static" compress romalign 0x1000 - include "build/assets/static/icon_item_gameover_static/icon_item_gameover_static.o" + include "build/assets/interface/icon_item_gameover_static/icon_item_gameover_static.o" number 12 endseg @@ -431,19 +428,16 @@ beginseg include "build/data/code/code_801E3FA0.bss.o" include "build/src/code/z_en_item00.o" include "build/src/code/z_eff_blure.o" - include "build/data/code/z_eff_blure.data.o" include "build/src/code/z_eff_shield_particle.o" - include "build/data/code/z_eff_shield_particle.data.o" include "build/src/code/z_eff_spark.o" include "build/src/code/z_eff_ss_dead.o" include "build/src/code/z_eff_tire_mark.o" include "build/src/code/z_effect.o" - include "build/data/code/z_effect.bss.o" include "build/src/code/z_effect_soft_sprite.o" - include "build/data/code/z_effect_soft_sprite.data.o" include "build/src/code/z_effect_soft_sprite_old_init.o" - include "build/data/code/z_effect_soft_sprite_old_init.data.o" + include "build/src/code/z_effect_soft_sprite_dlftbls.o" include "build/src/code/flg_set.o" + include "build/data/code/flg_set.bss.o" include "build/src/code/pad_801DC9C0.o" include "build/src/code/z_DLF.o" include "build/src/code/z_actor.o" @@ -474,8 +468,7 @@ beginseg include "build/data/code/z_eff_footmark.data.o" include "build/src/code/code_800F0390.o" include "build/src/code/z_elf_message.o" - include "build/src/code/code_800F07C0.o" - include "build/data/code/code_801BC2A0.data.o" + include "build/src/code/z_en_hy.o" include "build/src/code/z_face_reaction.o" include "build/src/code/z_env_flags.o" include "build/src/code/z_eventmgr.o" @@ -554,8 +547,6 @@ beginseg include "build/src/code/code_801420C0.o" include "build/src/code/z_vr_box.o" include "build/src/code/z_vr_box_draw.o" - include "build/data/code/z_vr_box_draw.data.o" - include "build/data/code/z_vr_box_draw.bss.o" include "build/src/code/z_sram_NES.o" include "build/data/code/z_sram_NES.data.o" include "build/data/code/z_sram_NES.bss.o" @@ -571,10 +562,7 @@ beginseg include "build/data/code/db_camera.bss.o" include "build/data/code/code_801D0B50.data.o" include "build/src/code/z_kaleido_manager.o" - include "build/data/code/z_kaleido_manager.data.o" - include "build/data/code/z_kaleido_manager.bss.o" include "build/src/code/z_kaleido_scope_call.o" - include "build/data/code/z_kaleido_scope_call.bss.o" include "build/src/code/z_fbdemo_dlftbls.o" include "build/data/code/code_801D0BB0.data.o" include "build/src/code/z_fbdemo.o" @@ -645,7 +633,7 @@ beginseg include "build/data/code/audio_load.bss.o" include "build/src/code/audio/code_80192BE0.o" include "build/data/code/code_80192BE0.data.o" - include "build/src/code/audio/code_80194710.o" + include "build/src/code/audio/audio_dcache.o" include "build/src/code/audio/code_80194790.o" include "build/data/code/code_80194790.data.o" include "build/src/code/audio/audio_playback.o" @@ -663,26 +651,27 @@ beginseg include "build/src/code/audio/code_801A4EB0.o" include "build/src/code/audio/code_801A51F0.o" pad_text - include "build/data/code/audio_sound_params.data.o" + include "build/src/code/audio/audio_sfx_params.o" include "build/src/code/audio/code_801A5BD0.o" include "build/data/code/code_801A5BD0.data.o" include "build/data/code/code_801A5BD0.bss.o" include "build/src/code/audio/code_801A7B10.o" include "build/data/code/code_801A7B10.data.o" include "build/data/code/code_801A7B10.bss.o" - include "build/data/code/audio_init_params.rodata.o" + include "build/src/code/audio/audio_init_params.o" include "build/src/code/jpegutils.o" include "build/src/code/jpegdecoder.o" include_readonly "build/src/code/z_game_over.o" include "build/src/code/z_construct.o" - include "build/data/code/audio_sound_params.data.o" include "build/data/code/rsp.rodata.o" endseg beginseg name "buffers" flags NOLOAD - include "build/src/buffers/gfxbuffers.o" + include "build/src/buffers/gfxyield.o" + include "build/src/buffers/gfxstack.o" + include "build/src/buffers/gfxpools.o" include "build/data/code/buffers.bss.o" endseg @@ -741,12 +730,12 @@ beginseg endseg beginseg - name "ovl_Player_Actor" + name "ovl_player_actor" compress - include "build/src/overlays/actors/ovl_Player_Actor/z_player.o" - include "build/data/ovl_Player_Actor/ovl_Player_Actor.data.o" - include "build/data/ovl_Player_Actor/ovl_Player_Actor.bss.o" - include "build/data/ovl_Player_Actor/ovl_Player_Actor.reloc.o" + include "build/src/overlays/actors/ovl_player_actor/z_player.o" + include "build/data/ovl_player_actor/ovl_player_actor.data.o" + include "build/data/ovl_player_actor/ovl_player_actor.bss.o" + include "build/data/ovl_player_actor/ovl_player_actor.reloc.o" endseg beginseg @@ -863,8 +852,7 @@ beginseg name "ovl_En_Elf" compress include "build/src/overlays/actors/ovl_En_Elf/z_en_elf.o" - include "build/data/ovl_En_Elf/ovl_En_Elf.data.o" - include "build/data/ovl_En_Elf/ovl_En_Elf.reloc.o" + include "build/src/overlays/actors/ovl_En_Elf/ovl_En_Elf_reloc.o" endseg beginseg @@ -885,8 +873,7 @@ beginseg name "ovl_En_Peehat" compress include "build/src/overlays/actors/ovl_En_Peehat/z_en_peehat.o" - include "build/data/ovl_En_Peehat/ovl_En_Peehat.data.o" - include "build/data/ovl_En_Peehat/ovl_En_Peehat.reloc.o" + include "build/src/overlays/actors/ovl_En_Peehat/ovl_En_Peehat_reloc.o" endseg beginseg @@ -969,8 +956,7 @@ beginseg name "ovl_En_St" compress include "build/src/overlays/actors/ovl_En_St/z_en_st.o" - include "build/data/ovl_En_St/ovl_En_St.data.o" - include "build/data/ovl_En_St/ovl_En_St.reloc.o" + include "build/src/overlays/actors/ovl_En_St/ovl_En_St_reloc.o" endseg beginseg @@ -1055,9 +1041,11 @@ beginseg name "ovl_Door_Warp1" compress include "build/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.o" - include "build/data/ovl_Door_Warp1/ovl_Door_Warp1.data.o" - include "build/data/ovl_Door_Warp1/ovl_Door_Warp1.bss.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_Door_Warp1/ovl_Door_Warp1_reloc.o" +#else include "build/data/ovl_Door_Warp1/ovl_Door_Warp1.reloc.o" +#endif endseg beginseg @@ -1186,8 +1174,7 @@ beginseg name "ovl_Obj_Mure" compress include "build/src/overlays/actors/ovl_Obj_Mure/z_obj_mure.o" - include "build/data/ovl_Obj_Mure/ovl_Obj_Mure.data.o" - include "build/data/ovl_Obj_Mure/ovl_Obj_Mure.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Mure/ovl_Obj_Mure_reloc.o" endseg beginseg @@ -1205,9 +1192,11 @@ beginseg name "ovl_Object_Kankyo" compress include "build/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.o" - include "build/data/ovl_Object_Kankyo/ovl_Object_Kankyo.data.o" - include "build/data/ovl_Object_Kankyo/ovl_Object_Kankyo.bss.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_Object_Kankyo/ovl_Object_Kankyo_reloc.o" +#else include "build/data/ovl_Object_Kankyo/ovl_Object_Kankyo.reloc.o" +#endif endseg beginseg @@ -1281,8 +1270,7 @@ beginseg name "ovl_En_Bigslime" compress include "build/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.o" - include "build/data/ovl_En_Bigslime/ovl_En_Bigslime.data.o" - include "build/data/ovl_En_Bigslime/ovl_En_Bigslime.reloc.o" + include "build/src/overlays/actors/ovl_En_Bigslime/ovl_En_Bigslime_reloc.o" endseg beginseg @@ -1320,25 +1308,25 @@ beginseg name "ovl_En_Rr" compress include "build/src/overlays/actors/ovl_En_Rr/z_en_rr.o" - include "build/data/ovl_En_Rr/ovl_En_Rr.data.o" - include "build/data/ovl_En_Rr/ovl_En_Rr.reloc.o" + include "build/src/overlays/actors/ovl_En_Rr/ovl_En_Rr_reloc.o" endseg beginseg name "ovl_En_Fr" compress include "build/src/overlays/actors/ovl_En_Fr/z_en_fr.o" - include "build/data/ovl_En_Fr/ovl_En_Fr.data.o" - include "build/data/ovl_En_Fr/ovl_En_Fr.reloc.o" + include "build/src/overlays/actors/ovl_En_Fr/ovl_En_Fr_reloc.o" endseg beginseg name "ovl_En_Fishing" compress include "build/src/overlays/actors/ovl_En_Fishing/z_en_fishing.o" - include "build/data/ovl_En_Fishing/ovl_En_Fishing.data.o" - include "build/data/ovl_En_Fishing/ovl_En_Fishing.bss.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_En_Fishing/ovl_En_Fishing_reloc.o" +#else include "build/data/ovl_En_Fishing/ovl_En_Fishing.reloc.o" +#endif endseg beginseg @@ -1384,8 +1372,7 @@ beginseg name "ovl_En_Fish" compress include "build/src/overlays/actors/ovl_En_Fish/z_en_fish.o" - include "build/data/ovl_En_Fish/ovl_En_Fish.data.o" - include "build/data/ovl_En_Fish/ovl_En_Fish.reloc.o" + include "build/src/overlays/actors/ovl_En_Fish/ovl_En_Fish_reloc.o" endseg beginseg @@ -1493,8 +1480,7 @@ beginseg name "ovl_En_Fz" compress include "build/src/overlays/actors/ovl_En_Fz/z_en_fz.o" - include "build/data/ovl_En_Fz/ovl_En_Fz.data.o" - include "build/data/ovl_En_Fz/ovl_En_Fz.reloc.o" + include "build/src/overlays/actors/ovl_En_Fz/ovl_En_Fz_reloc.o" endseg beginseg @@ -1624,16 +1610,14 @@ beginseg name "ovl_En_Gm" compress include "build/src/overlays/actors/ovl_En_Gm/z_en_gm.o" - include "build/data/ovl_En_Gm/ovl_En_Gm.data.o" - include "build/data/ovl_En_Gm/ovl_En_Gm.reloc.o" + include "build/src/overlays/actors/ovl_En_Gm/ovl_En_Gm_reloc.o" endseg beginseg name "ovl_En_Ms" compress include "build/src/overlays/actors/ovl_En_Ms/z_en_ms.o" - include "build/data/ovl_En_Ms/ovl_En_Ms.data.o" - include "build/data/ovl_En_Ms/ovl_En_Ms.reloc.o" + include "build/src/overlays/actors/ovl_En_Ms/ovl_En_Ms_reloc.o" endseg beginseg @@ -1687,8 +1671,7 @@ beginseg name "ovl_En_Ishi" compress include "build/src/overlays/actors/ovl_En_Ishi/z_en_ishi.o" - include "build/data/ovl_En_Ishi/ovl_En_Ishi.data.o" - include "build/data/ovl_En_Ishi/ovl_En_Ishi.reloc.o" + include "build/src/overlays/actors/ovl_En_Ishi/ovl_En_Ishi_reloc.o" endseg beginseg @@ -1724,8 +1707,7 @@ beginseg name "ovl_En_Stream" compress include "build/src/overlays/actors/ovl_En_Stream/z_en_stream.o" - include "build/data/ovl_En_Stream/ovl_En_Stream.data.o" - include "build/data/ovl_En_Stream/ovl_En_Stream.reloc.o" + include "build/src/overlays/actors/ovl_En_Stream/ovl_En_Stream_reloc.o" endseg beginseg @@ -1831,16 +1813,14 @@ beginseg name "ovl_Obj_Roomtimer" compress include "build/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.o" - include "build/data/ovl_Obj_Roomtimer/ovl_Obj_Roomtimer.data.o" - include "build/data/ovl_Obj_Roomtimer/ovl_Obj_Roomtimer.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Roomtimer/ovl_Obj_Roomtimer_reloc.o" endseg beginseg name "ovl_En_Ssh" compress include "build/src/overlays/actors/ovl_En_Ssh/z_en_ssh.o" - include "build/data/ovl_En_Ssh/ovl_En_Ssh.data.o" - include "build/data/ovl_En_Ssh/ovl_En_Ssh.reloc.o" + include "build/src/overlays/actors/ovl_En_Ssh/ovl_En_Ssh_reloc.o" endseg beginseg @@ -1960,8 +1940,7 @@ beginseg name "ovl_Effect_Ss_Stick" compress include "build/src/overlays/effects/ovl_Effect_Ss_Stick/z_eff_ss_stick.o" - include "build/data/ovl_Effect_Ss_Stick/ovl_Effect_Ss_Stick.data.o" - include "build/data/ovl_Effect_Ss_Stick/ovl_Effect_Ss_Stick.reloc.o" + include "build/src/overlays/effects/ovl_Effect_Ss_Stick/ovl_Effect_Ss_Stick_reloc.o" endseg beginseg @@ -2016,8 +1995,7 @@ beginseg name "ovl_Effect_Ss_Kakera" compress include "build/src/overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.o" - include "build/data/ovl_Effect_Ss_Kakera/ovl_Effect_Ss_Kakera.data.o" - include "build/data/ovl_Effect_Ss_Kakera/ovl_Effect_Ss_Kakera.reloc.o" + include "build/src/overlays/effects/ovl_Effect_Ss_Kakera/ovl_Effect_Ss_Kakera_reloc.o" endseg beginseg @@ -2203,8 +2181,7 @@ beginseg name "ovl_En_Gs" compress include "build/src/overlays/actors/ovl_En_Gs/z_en_gs.o" - include "build/data/ovl_En_Gs/ovl_En_Gs.data.o" - include "build/data/ovl_En_Gs/ovl_En_Gs.reloc.o" + include "build/src/overlays/actors/ovl_En_Gs/ovl_En_Gs_reloc.o" endseg beginseg @@ -2227,8 +2204,7 @@ beginseg name "ovl_En_Cow" compress include "build/src/overlays/actors/ovl_En_Cow/z_en_cow.o" - include "build/data/ovl_En_Cow/ovl_En_Cow.data.o" - include "build/data/ovl_En_Cow/ovl_En_Cow.reloc.o" + include "build/src/overlays/actors/ovl_En_Cow/ovl_En_Cow_reloc.o" endseg beginseg @@ -2292,8 +2268,7 @@ beginseg name "ovl_En_Mm2" compress include "build/src/overlays/actors/ovl_En_Mm2/z_en_mm2.o" - include "build/data/ovl_En_Mm2/ovl_En_Mm2.data.o" - include "build/data/ovl_En_Mm2/ovl_En_Mm2.reloc.o" + include "build/src/overlays/actors/ovl_En_Mm2/ovl_En_Mm2_reloc.o" endseg beginseg @@ -2427,8 +2402,7 @@ beginseg name "ovl_En_Aob_01" compress include "build/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.o" - include "build/data/ovl_En_Aob_01/ovl_En_Aob_01.data.o" - include "build/data/ovl_En_Aob_01/ovl_En_Aob_01.reloc.o" + include "build/src/overlays/actors/ovl_En_Aob_01/ovl_En_Aob_01_reloc.o" endseg beginseg @@ -2569,9 +2543,7 @@ beginseg name "ovl_Boss_04" compress include "build/src/overlays/actors/ovl_Boss_04/z_boss_04.o" - include "build/data/ovl_Boss_04/ovl_Boss_04.data.o" - include "build/data/ovl_Boss_04/ovl_Boss_04.bss.o" - include "build/data/ovl_Boss_04/ovl_Boss_04.reloc.o" + include "build/src/overlays/actors/ovl_Boss_04/ovl_Boss_04_reloc.o" endseg beginseg @@ -2627,8 +2599,11 @@ beginseg name "ovl_En_Go" compress include "build/src/overlays/actors/ovl_En_Go/z_en_go.o" - include "build/data/ovl_En_Go/ovl_En_Go.data.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_En_Go/ovl_En_Go_reloc.o" +#else include "build/data/ovl_En_Go/ovl_En_Go.reloc.o" +#endif endseg beginseg @@ -2665,9 +2640,7 @@ beginseg name "ovl_Obj_Flowerpot" compress include "build/src/overlays/actors/ovl_Obj_Flowerpot/z_obj_flowerpot.o" - include "build/data/ovl_Obj_Flowerpot/ovl_Obj_Flowerpot.data.o" - include "build/data/ovl_Obj_Flowerpot/ovl_Obj_Flowerpot.bss.o" - include "build/data/ovl_Obj_Flowerpot/ovl_Obj_Flowerpot.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Flowerpot/ovl_Obj_Flowerpot_reloc.o" endseg beginseg @@ -2714,8 +2687,11 @@ beginseg name "ovl_Obj_Iceblock" compress include "build/src/overlays/actors/ovl_Obj_Iceblock/z_obj_iceblock.o" - include "build/data/ovl_Obj_Iceblock/ovl_Obj_Iceblock.data.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_Obj_Iceblock/ovl_Obj_Iceblock_reloc.o" +#else include "build/data/ovl_Obj_Iceblock/ovl_Obj_Iceblock.reloc.o" +#endif endseg beginseg @@ -2944,8 +2920,7 @@ beginseg name "ovl_En_Wiz_Fire" compress include "build/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.o" - include "build/data/ovl_En_Wiz_Fire/ovl_En_Wiz_Fire.data.o" - include "build/data/ovl_En_Wiz_Fire/ovl_En_Wiz_Fire.reloc.o" + include "build/src/overlays/actors/ovl_En_Wiz_Fire/ovl_En_Wiz_Fire_reloc.o" endseg beginseg @@ -3035,8 +3010,7 @@ beginseg name "ovl_Obj_Hugebombiwa" compress include "build/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.o" - include "build/data/ovl_Obj_Hugebombiwa/ovl_Obj_Hugebombiwa.data.o" - include "build/data/ovl_Obj_Hugebombiwa/ovl_Obj_Hugebombiwa.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Hugebombiwa/ovl_Obj_Hugebombiwa_reloc.o" endseg beginseg @@ -3058,17 +3032,14 @@ beginseg name "ovl_En_Water_Effect" compress include "build/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.o" - include "build/data/ovl_En_Water_Effect/ovl_En_Water_Effect.data.o" - include "build/data/ovl_En_Water_Effect/ovl_En_Water_Effect.reloc.o" + include "build/src/overlays/actors/ovl_En_Water_Effect/ovl_En_Water_Effect_reloc.o" endseg beginseg name "ovl_En_Kusa2" compress include "build/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.o" - include "build/data/ovl_En_Kusa2/ovl_En_Kusa2.data.o" - include "build/data/ovl_En_Kusa2/ovl_En_Kusa2.bss.o" - include "build/data/ovl_En_Kusa2/ovl_En_Kusa2.reloc.o" + include "build/src/overlays/actors/ovl_En_Kusa2/ovl_En_Kusa2_reloc.o" endseg beginseg @@ -3135,9 +3106,7 @@ beginseg name "ovl_En_Fall" compress include "build/src/overlays/actors/ovl_En_Fall/z_en_fall.o" - include "build/data/ovl_En_Fall/ovl_En_Fall.data.o" - include "build/data/ovl_En_Fall/ovl_En_Fall.bss.o" - include "build/data/ovl_En_Fall/ovl_En_Fall.reloc.o" + include "build/src/overlays/actors/ovl_En_Fall/ovl_En_Fall_reloc.o" endseg beginseg @@ -3224,8 +3193,11 @@ beginseg name "ovl_En_Tru" compress include "build/src/overlays/actors/ovl_En_Tru/z_en_tru.o" - include "build/data/ovl_En_Tru/ovl_En_Tru.data.o" - include "build/data/ovl_En_Tru/ovl_En_Tru.reloc.o" + #ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_En_Tru/ovl_En_Tru_reloc.o" + #else + include "build/data/ovl_En_Tru/ovl_En_Tru.reloc.o" + #endif endseg beginseg @@ -3239,8 +3211,7 @@ beginseg name "ovl_En_Test5" compress include "build/src/overlays/actors/ovl_En_Test5/z_en_test5.o" - include "build/data/ovl_En_Test5/ovl_En_Test5.data.o" - include "build/data/ovl_En_Test5/ovl_En_Test5.reloc.o" + include "build/src/overlays/actors/ovl_En_Test5/ovl_En_Test5_reloc.o" endseg beginseg @@ -3288,8 +3259,7 @@ beginseg name "ovl_Dm_Stk" compress include "build/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.o" - include "build/data/ovl_Dm_Stk/ovl_Dm_Stk.data.o" - include "build/data/ovl_Dm_Stk/ovl_Dm_Stk.reloc.o" + include "build/src/overlays/actors/ovl_Dm_Stk/ovl_Dm_Stk_reloc.o" endseg beginseg @@ -3376,8 +3346,7 @@ beginseg name "ovl_Obj_Tokeidai" compress include "build/src/overlays/actors/ovl_Obj_Tokeidai/z_obj_tokeidai.o" - include "build/data/ovl_Obj_Tokeidai/ovl_Obj_Tokeidai.data.o" - include "build/data/ovl_Obj_Tokeidai/ovl_Obj_Tokeidai.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Tokeidai/ovl_Obj_Tokeidai_reloc.o" endseg beginseg @@ -3641,8 +3610,7 @@ beginseg name "ovl_En_Kame" compress include "build/src/overlays/actors/ovl_En_Kame/z_en_kame.o" - include "build/data/ovl_En_Kame/ovl_En_Kame.data.o" - include "build/data/ovl_En_Kame/ovl_En_Kame.reloc.o" + include "build/src/overlays/actors/ovl_En_Kame/ovl_En_Kame_reloc.o" endseg beginseg @@ -3860,16 +3828,14 @@ beginseg name "ovl_En_Col_Man" compress include "build/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.o" - include "build/data/ovl_En_Col_Man/ovl_En_Col_Man.data.o" - include "build/data/ovl_En_Col_Man/ovl_En_Col_Man.reloc.o" + include "build/src/overlays/actors/ovl_En_Col_Man/ovl_En_Col_Man_reloc.o" endseg beginseg name "ovl_En_Talk_Gibud" compress include "build/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.o" - include "build/data/ovl_En_Talk_Gibud/ovl_En_Talk_Gibud.data.o" - include "build/data/ovl_En_Talk_Gibud/ovl_En_Talk_Gibud.reloc.o" + include "build/src/overlays/actors/ovl_En_Talk_Gibud/ovl_En_Talk_Gibud_reloc.o" endseg beginseg @@ -3883,8 +3849,11 @@ beginseg name "ovl_Obj_Snowball" compress include "build/src/overlays/actors/ovl_Obj_Snowball/z_obj_snowball.o" - include "build/data/ovl_Obj_Snowball/ovl_Obj_Snowball.data.o" +#ifdef NON_MATCHING + include "build/src/overlays/actors/ovl_Obj_Snowball/ovl_obj_Snowball_reloc.o" +#else include "build/data/ovl_Obj_Snowball/ovl_Obj_Snowball.reloc.o" +#endif endseg beginseg @@ -3899,8 +3868,7 @@ beginseg name "ovl_En_Gb2" compress include "build/src/overlays/actors/ovl_En_Gb2/z_en_gb2.o" - include "build/data/ovl_En_Gb2/ovl_En_Gb2.data.o" - include "build/data/ovl_En_Gb2/ovl_En_Gb2.reloc.o" + include "build/src/overlays/actors/ovl_En_Gb2/ovl_En_Gb2_reloc.o" endseg beginseg @@ -3999,8 +3967,7 @@ beginseg name "ovl_Obj_Dowsing" compress include "build/src/overlays/actors/ovl_Obj_Dowsing/z_obj_dowsing.o" - include "build/data/ovl_Obj_Dowsing/ovl_Obj_Dowsing.data.o" - include "build/data/ovl_Obj_Dowsing/ovl_Obj_Dowsing.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Dowsing/ovl_Obj_Dowsing_reloc.o" endseg beginseg @@ -4138,8 +4105,7 @@ beginseg name "ovl_Bg_Goron_Oyu" compress include "build/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.o" - include "build/data/ovl_Bg_Goron_Oyu/ovl_Bg_Goron_Oyu.data.o" - include "build/data/ovl_Bg_Goron_Oyu/ovl_Bg_Goron_Oyu.reloc.o" + include "build/src/overlays/actors/ovl_Bg_Goron_Oyu/ovl_Bg_Goron_Oyu_reloc.o" endseg beginseg @@ -4284,8 +4250,7 @@ beginseg name "ovl_En_Rail_Skb" compress include "build/src/overlays/actors/ovl_En_Rail_Skb/z_en_rail_skb.o" - include "build/data/ovl_En_Rail_Skb/ovl_En_Rail_Skb.data.o" - include "build/data/ovl_En_Rail_Skb/ovl_En_Rail_Skb.reloc.o" + include "build/src/overlays/actors/ovl_En_Rail_Skb/ovl_En_Rail_Skb_reloc.o" endseg beginseg @@ -4425,9 +4390,7 @@ beginseg name "ovl_En_Zog" compress include "build/src/overlays/actors/ovl_En_Zog/z_en_zog.o" - include "build/data/ovl_En_Zog/ovl_En_Zog.data.o" - include "build/data/ovl_En_Zog/ovl_En_Zog.bss.o" - include "build/data/ovl_En_Zog/ovl_En_Zog.reloc.o" + include "build/src/overlays/actors/ovl_En_Zog/ovl_En_Zog_reloc.o" endseg beginseg @@ -4442,16 +4405,14 @@ beginseg name "ovl_Obj_Jg_Gakki" compress include "build/src/overlays/actors/ovl_Obj_Jg_Gakki/z_obj_jg_gakki.o" - include "build/data/ovl_Obj_Jg_Gakki/ovl_Obj_Jg_Gakki.data.o" - include "build/data/ovl_Obj_Jg_Gakki/ovl_Obj_Jg_Gakki.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Jg_Gakki/ovl_Obj_Jg_Gakki_reloc.o" endseg beginseg name "ovl_Bg_Inibs_Movebg" compress include "build/src/overlays/actors/ovl_Bg_Inibs_Movebg/z_bg_inibs_movebg.o" - include "build/data/ovl_Bg_Inibs_Movebg/ovl_Bg_Inibs_Movebg.data.o" - include "build/data/ovl_Bg_Inibs_Movebg/ovl_Bg_Inibs_Movebg.reloc.o" + include "build/src/overlays/actors/ovl_Bg_Inibs_Movebg/ovl_Bg_Inibs_Movebg_reloc.o" endseg beginseg @@ -4465,8 +4426,7 @@ beginseg name "ovl_Obj_Tree" compress include "build/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.o" - include "build/data/ovl_Obj_Tree/ovl_Obj_Tree.data.o" - include "build/data/ovl_Obj_Tree/ovl_Obj_Tree.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Tree/ovl_Obj_Tree_reloc.o" endseg beginseg @@ -4599,8 +4559,7 @@ beginseg name "ovl_En_Geg" compress include "build/src/overlays/actors/ovl_En_Geg/z_en_geg.o" - include "build/data/ovl_En_Geg/ovl_En_Geg.data.o" - include "build/data/ovl_En_Geg/ovl_En_Geg.reloc.o" + include "build/src/overlays/actors/ovl_En_Geg/ovl_En_Geg_reloc.o" endseg beginseg @@ -4640,8 +4599,7 @@ beginseg name "ovl_En_Tanron3" compress include "build/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.o" - include "build/data/ovl_En_Tanron3/ovl_En_Tanron3.data.o" - include "build/data/ovl_En_Tanron3/ovl_En_Tanron3.reloc.o" + include "build/src/overlays/actors/ovl_En_Tanron3/ovl_En_Tanron3_reloc.o" endseg beginseg @@ -4908,8 +4866,7 @@ beginseg name "ovl_En_Talk" compress include "build/src/overlays/actors/ovl_En_Talk/z_en_talk.o" - include "build/data/ovl_En_Talk/ovl_En_Talk.data.o" - include "build/data/ovl_En_Talk/ovl_En_Talk.reloc.o" + include "build/src/overlays/actors/ovl_En_Talk/ovl_En_Talk_reloc.o" endseg beginseg @@ -4940,16 +4897,14 @@ beginseg name "ovl_En_Hit_Tag" compress include "build/src/overlays/actors/ovl_En_Hit_Tag/z_en_hit_tag.o" - include "build/data/ovl_En_Hit_Tag/ovl_En_Hit_Tag.data.o" - include "build/data/ovl_En_Hit_Tag/ovl_En_Hit_Tag.reloc.o" + include "build/src/overlays/actors/ovl_En_Hit_Tag/ovl_En_Hit_Tag_reloc.o" endseg beginseg name "ovl_En_Ruppecrow" compress include "build/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.o" - include "build/data/ovl_En_Ruppecrow/ovl_En_Ruppecrow.data.o" - include "build/data/ovl_En_Ruppecrow/ovl_En_Ruppecrow.reloc.o" + include "build/src/overlays/actors/ovl_En_Ruppecrow/ovl_En_Ruppecrow_reloc.o" endseg beginseg @@ -5055,8 +5010,7 @@ beginseg name "ovl_En_Akindonuts" compress include "build/src/overlays/actors/ovl_En_Akindonuts/z_en_akindonuts.o" - include "build/data/ovl_En_Akindonuts/ovl_En_Akindonuts.data.o" - include "build/data/ovl_En_Akindonuts/ovl_En_Akindonuts.reloc.o" + include "build/src/overlays/actors/ovl_En_Akindonuts/ovl_En_Akindonuts_reloc.o" endseg beginseg @@ -5135,7 +5089,6 @@ beginseg name "ovl_En_Bomjima" compress include "build/src/overlays/actors/ovl_En_Bomjima/z_en_bomjima.o" - include "build/data/ovl_En_Bomjima/ovl_En_Bomjima.data.o" include "build/data/ovl_En_Bomjima/ovl_En_Bomjima.reloc.o" endseg @@ -5143,8 +5096,7 @@ beginseg name "ovl_En_Bomjimb" compress include "build/src/overlays/actors/ovl_En_Bomjimb/z_en_bomjimb.o" - include "build/data/ovl_En_Bomjimb/ovl_En_Bomjimb.data.o" - include "build/data/ovl_En_Bomjimb/ovl_En_Bomjimb.reloc.o" + include "build/src/overlays/actors/ovl_En_Bomjimb/ovl_En_Bomjimb_reloc.o" endseg beginseg @@ -5273,8 +5225,7 @@ beginseg name "ovl_En_Recepgirl" compress include "build/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.o" - include "build/data/ovl_En_Recepgirl/ovl_En_Recepgirl.data.o" - include "build/data/ovl_En_Recepgirl/ovl_En_Recepgirl.reloc.o" + include "build/src/overlays/actors/ovl_En_Recepgirl/ovl_En_Recepgirl_reloc.o" endseg beginseg @@ -5304,9 +5255,7 @@ beginseg name "ovl_Obj_Yado" compress include "build/src/overlays/actors/ovl_Obj_Yado/z_obj_yado.o" - include "build/data/ovl_Obj_Yado/ovl_Obj_Yado.data.o" - include "build/data/ovl_Obj_Yado/ovl_Obj_Yado.bss.o" - include "build/data/ovl_Obj_Yado/ovl_Obj_Yado.reloc.o" + include "build/src/overlays/actors/ovl_Obj_Yado/ovl_Obj_Yado_reloc.o" endseg beginseg @@ -5514,8 +5463,7 @@ beginseg name "ovl_En_Invisible_Ruppe" compress include "build/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.o" - include "build/data/ovl_En_Invisible_Ruppe/ovl_En_Invisible_Ruppe.data.o" - include "build/data/ovl_En_Invisible_Ruppe/ovl_En_Invisible_Ruppe.reloc.o" + include "build/src/overlays/actors/ovl_En_Invisible_Ruppe/ovl_En_Invisible_Ruppe_reloc.o" endseg beginseg @@ -5536,21 +5484,24 @@ beginseg name "gameplay_keep" compress romalign 0x1000 - include "build/baserom/gameplay_keep.o" + number 4 + include "build/assets/objects/gameplay_keep/gameplay_keep.o" endseg beginseg name "gameplay_field_keep" compress romalign 0x1000 - include "build/baserom/gameplay_field_keep.o" + number 5 + include "build/assets/objects/gameplay_field_keep/gameplay_field_keep.o" endseg beginseg name "gameplay_dangeon_keep" compress romalign 0x1000 - include "build/baserom/gameplay_dangeon_keep.o" + number 5 + include "build/assets/objects/gameplay_dangeon_keep/gameplay_dangeon_keep.o" endseg beginseg @@ -5564,3227 +5515,3688 @@ beginseg name "object_link_boy" compress romalign 0x1000 - include "build/baserom/object_link_boy.o" + number 6 + include "build/assets/objects/object_link_boy/object_link_boy.o" endseg beginseg name "object_link_child" compress romalign 0x1000 - include "build/baserom/object_link_child.o" + number 6 + include "build/assets/objects/object_link_child/object_link_child.o" endseg beginseg name "object_link_goron" compress romalign 0x1000 - include "build/baserom/object_link_goron.o" + number 6 + include "build/assets/objects/object_link_goron/object_link_goron.o" endseg beginseg name "object_link_zora" compress romalign 0x1000 - include "build/baserom/object_link_zora.o" + number 6 + include "build/assets/objects/object_link_zora/object_link_zora.o" endseg beginseg name "object_link_nuts" compress romalign 0x1000 - include "build/baserom/object_link_nuts.o" + number 6 + include "build/assets/objects/object_link_nuts/object_link_nuts.o" endseg beginseg name "object_mask_ki_tan" compress romalign 0x1000 - include "build/baserom/object_mask_ki_tan.o" + number 10 + include "build/assets/objects/object_mask_ki_tan/object_mask_ki_tan.o" endseg beginseg name "object_mask_rabit" compress romalign 0x1000 - include "build/baserom/object_mask_rabit.o" + number 10 + include "build/assets/objects/object_mask_rabit/object_mask_rabit.o" endseg beginseg name "object_mask_skj" compress romalign 0x1000 - include "build/baserom/object_mask_skj.o" + number 10 + include "build/assets/objects/object_mask_skj/object_mask_skj.o" endseg beginseg name "object_mask_truth" compress romalign 0x1000 - include "build/baserom/object_mask_truth.o" + number 10 + include "build/assets/objects/object_mask_truth/object_mask_truth.o" endseg beginseg name "object_mask_gibudo" compress romalign 0x1000 - include "build/baserom/object_mask_gibudo.o" + number 10 + include "build/assets/objects/object_mask_gibudo/object_mask_gibudo.o" endseg beginseg name "object_mask_json" compress romalign 0x1000 - include "build/baserom/object_mask_json.o" + number 10 + include "build/assets/objects/object_mask_json/object_mask_json.o" endseg beginseg name "object_mask_kerfay" compress romalign 0x1000 - include "build/baserom/object_mask_kerfay.o" + number 10 + include "build/assets/objects/object_mask_kerfay/object_mask_kerfay.o" endseg beginseg name "object_mask_bigelf" compress romalign 0x1000 - include "build/baserom/object_mask_bigelf.o" + number 10 + include "build/assets/objects/object_mask_bigelf/object_mask_bigelf.o" endseg beginseg name "object_mask_kyojin" compress romalign 0x1000 - include "build/baserom/object_mask_kyojin.o" + number 10 + include "build/assets/objects/object_mask_kyojin/object_mask_kyojin.o" endseg beginseg name "object_mask_romerny" compress romalign 0x1000 - include "build/baserom/object_mask_romerny.o" + number 10 + include "build/assets/objects/object_mask_romerny/object_mask_romerny.o" endseg beginseg name "object_mask_posthat" compress romalign 0x1000 - include "build/baserom/object_mask_posthat.o" + number 10 + include "build/assets/objects/object_mask_posthat/object_mask_posthat.o" endseg beginseg name "object_mask_zacho" compress romalign 0x1000 - include "build/baserom/object_mask_zacho.o" + number 10 + include "build/assets/objects/object_mask_zacho/object_mask_zacho.o" endseg beginseg name "object_mask_stone" compress romalign 0x1000 - include "build/baserom/object_mask_stone.o" + number 10 + include "build/assets/objects/object_mask_stone/object_mask_stone.o" endseg beginseg name "object_mask_bree" compress romalign 0x1000 - include "build/baserom/object_mask_bree.o" + number 10 + include "build/assets/objects/object_mask_bree/object_mask_bree.o" endseg beginseg name "object_mask_gero" compress romalign 0x1000 - include "build/baserom/object_mask_gero.o" + number 10 + include "build/assets/objects/object_mask_gero/object_mask_gero.o" endseg beginseg name "object_mask_yofukasi" compress romalign 0x1000 - include "build/baserom/object_mask_yofukasi.o" + number 10 + include "build/assets/objects/object_mask_yofukasi/object_mask_yofukasi.o" endseg beginseg name "object_mask_meoto" compress romalign 0x1000 - include "build/baserom/object_mask_meoto.o" + number 10 + include "build/assets/objects/object_mask_meoto/object_mask_meoto.o" endseg beginseg name "object_mask_dancer" compress romalign 0x1000 - include "build/baserom/object_mask_dancer.o" + number 10 + include "build/assets/objects/object_mask_dancer/object_mask_dancer.o" endseg beginseg name "object_mask_bakuretu" compress romalign 0x1000 - include "build/baserom/object_mask_bakuretu.o" + number 10 + include "build/assets/objects/object_mask_bakuretu/object_mask_bakuretu.o" endseg beginseg name "object_mask_bu_san" compress romalign 0x1000 - include "build/baserom/object_mask_bu_san.o" + number 10 + include "build/assets/objects/object_mask_bu_san/object_mask_bu_san.o" endseg beginseg name "object_mask_goron" compress romalign 0x1000 - include "build/baserom/object_mask_goron.o" + number 10 + include "build/assets/objects/object_mask_goron/object_mask_goron.o" endseg beginseg name "object_mask_zora" compress romalign 0x1000 - include "build/baserom/object_mask_zora.o" + number 10 + include "build/assets/objects/object_mask_zora/object_mask_zora.o" endseg beginseg name "object_mask_nuts" compress romalign 0x1000 - include "build/baserom/object_mask_nuts.o" + number 10 + include "build/assets/objects/object_mask_nuts/object_mask_nuts.o" endseg beginseg name "object_mask_boy" compress romalign 0x1000 - include "build/baserom/object_mask_boy.o" + number 10 + include "build/assets/objects/object_mask_boy/object_mask_boy.o" endseg beginseg name "object_box" compress romalign 0x1000 - include "build/baserom/object_box.o" + number 6 + include "build/assets/objects/object_box/object_box.o" endseg beginseg name "object_okuta" compress romalign 0x1000 - include "build/baserom/object_okuta.o" + number 6 + include "build/assets/objects/object_okuta/object_okuta.o" endseg beginseg name "object_wallmaster" compress romalign 0x1000 - include "build/baserom/object_wallmaster.o" + number 6 + include "build/assets/objects/object_wallmaster/object_wallmaster.o" endseg beginseg name "object_dy_obj" compress romalign 0x1000 - include "build/baserom/object_dy_obj.o" + number 6 + include "build/assets/objects/object_dy_obj/object_dy_obj.o" endseg beginseg name "object_firefly" compress romalign 0x1000 - include "build/baserom/object_firefly.o" + number 6 + include "build/assets/objects/object_firefly/object_firefly.o" endseg beginseg name "object_dodongo" compress romalign 0x1000 - include "build/baserom/object_dodongo.o" + number 6 + include "build/assets/objects/object_dodongo/object_dodongo.o" endseg beginseg name "object_niw" compress romalign 0x1000 - include "build/baserom/object_niw.o" + number 6 + include "build/assets/objects/object_niw/object_niw.o" endseg beginseg name "object_tite" compress romalign 0x1000 - include "build/baserom/object_tite.o" + number 6 + include "build/assets/objects/object_tite/object_tite.o" endseg beginseg name "object_ph" compress romalign 0x1000 - include "build/baserom/object_ph.o" + number 6 + include "build/assets/objects/object_ph/object_ph.o" endseg beginseg name "object_dinofos" compress romalign 0x1000 - include "build/baserom/object_dinofos.o" + number 6 + include "build/assets/objects/object_dinofos/object_dinofos.o" endseg beginseg name "object_zl1" compress romalign 0x1000 - include "build/baserom/object_zl1.o" + number 6 + include "build/assets/objects/object_zl1/object_zl1.o" endseg beginseg name "object_bubble" compress romalign 0x1000 - include "build/baserom/object_bubble.o" + number 6 + include "build/assets/objects/object_bubble/object_bubble.o" endseg beginseg name "object_test3" compress romalign 0x1000 - include "build/baserom/object_test3.o" + number 6 + include "build/assets/objects/object_test3/object_test3.o" endseg beginseg name "object_famos" compress romalign 0x1000 - include "build/baserom/object_famos.o" + number 6 + include "build/assets/objects/object_famos/object_famos.o" endseg beginseg name "object_st" compress romalign 0x1000 - include "build/baserom/object_st.o" + number 6 + include "build/assets/objects/object_st/object_st.o" endseg beginseg name "object_thiefbird" compress romalign 0x1000 - include "build/baserom/object_thiefbird.o" + number 6 + include "build/assets/objects/object_thiefbird/object_thiefbird.o" endseg beginseg name "object_bombf" compress romalign 0x1000 - include "build/baserom/object_bombf.o" + number 6 + include "build/assets/objects/object_bombf/object_bombf.o" endseg beginseg name "object_am" compress romalign 0x1000 - include "build/baserom/object_am.o" + number 6 + include "build/assets/objects/object_am/object_am.o" endseg beginseg name "object_dekubaba" compress romalign 0x1000 - include "build/baserom/object_dekubaba.o" + number 6 + include "build/assets/objects/object_dekubaba/object_dekubaba.o" endseg beginseg name "object_warp1" compress romalign 0x1000 - include "build/baserom/object_warp1.o" + number 6 + include "build/assets/objects/object_warp1/object_warp1.o" endseg beginseg name "object_b_heart" compress romalign 0x1000 - include "build/baserom/object_b_heart.o" + number 6 + include "build/assets/objects/object_b_heart/object_b_heart.o" endseg beginseg name "object_dekunuts" compress romalign 0x1000 - include "build/baserom/object_dekunuts.o" + number 6 + include "build/assets/objects/object_dekunuts/object_dekunuts.o" endseg beginseg name "object_bb" compress romalign 0x1000 - include "build/baserom/object_bb.o" + number 6 + include "build/assets/objects/object_bb/object_bb.o" endseg beginseg name "object_death" compress romalign 0x1000 - include "build/baserom/object_death.o" + number 6 + include "build/assets/objects/object_death/object_death.o" endseg beginseg name "object_hata" compress romalign 0x1000 - include "build/baserom/object_hata.o" + number 6 + include "build/assets/objects/object_hata/object_hata.o" endseg beginseg name "object_wood02" compress romalign 0x1000 - include "build/baserom/object_wood02.o" + number 6 + include "build/assets/objects/object_wood02/object_wood02.o" endseg beginseg name "object_trap" compress romalign 0x1000 - include "build/baserom/object_trap.o" + number 6 + include "build/assets/objects/object_trap/object_trap.o" endseg beginseg name "object_vm" compress romalign 0x1000 - include "build/baserom/object_vm.o" + number 6 + include "build/assets/objects/object_vm/object_vm.o" endseg beginseg name "object_efc_star_field" compress romalign 0x1000 - include "build/baserom/object_efc_star_field.o" + number 6 + include "build/assets/objects/object_efc_star_field/object_efc_star_field.o" endseg beginseg name "object_rd" compress romalign 0x1000 - include "build/baserom/object_rd.o" + number 6 + include "build/assets/objects/object_rd/object_rd.o" endseg beginseg name "object_yukimura_obj" compress romalign 0x1000 - include "build/baserom/object_yukimura_obj.o" + number 6 + include "build/assets/objects/object_yukimura_obj/object_yukimura_obj.o" endseg beginseg name "object_horse_link_child" compress romalign 0x1000 - include "build/baserom/object_horse_link_child.o" + number 6 + include "build/assets/objects/object_horse_link_child/object_horse_link_child.o" endseg beginseg name "object_syokudai" compress romalign 0x1000 - include "build/baserom/object_syokudai.o" + number 6 + include "build/assets/objects/object_syokudai/object_syokudai.o" endseg beginseg name "object_efc_tw" compress romalign 0x1000 - include "build/baserom/object_efc_tw.o" + number 6 + include "build/assets/objects/object_efc_tw/object_efc_tw.o" endseg beginseg name "object_gi_key" compress romalign 0x1000 - include "build/baserom/object_gi_key.o" + number 6 + include "build/assets/objects/object_gi_key/object_gi_key.o" endseg beginseg name "object_mir_ray" compress romalign 0x1000 - include "build/baserom/object_mir_ray.o" + number 6 + include "build/assets/objects/object_mir_ray/object_mir_ray.o" endseg beginseg name "object_ctower_rot" compress romalign 0x1000 - include "build/baserom/object_ctower_rot.o" + number 6 + include "build/assets/objects/object_ctower_rot/object_ctower_rot.o" endseg beginseg name "object_bdoor" compress romalign 0x1000 - include "build/baserom/object_bdoor.o" + number 6 + include "build/assets/objects/object_bdoor/object_bdoor.o" endseg beginseg name "object_sb" compress romalign 0x1000 - include "build/baserom/object_sb.o" + number 6 + include "build/assets/objects/object_sb/object_sb.o" endseg beginseg name "object_gi_melody" compress romalign 0x1000 - include "build/baserom/object_gi_melody.o" + number 6 + include "build/assets/objects/object_gi_melody/object_gi_melody.o" endseg beginseg name "object_gi_heart" compress romalign 0x1000 - include "build/baserom/object_gi_heart.o" + number 6 + include "build/assets/objects/object_gi_heart/object_gi_heart.o" endseg beginseg name "object_gi_compass" compress romalign 0x1000 - include "build/baserom/object_gi_compass.o" + number 6 + include "build/assets/objects/object_gi_compass/object_gi_compass.o" endseg beginseg name "object_gi_bosskey" compress romalign 0x1000 - include "build/baserom/object_gi_bosskey.o" + number 6 + include "build/assets/objects/object_gi_bosskey/object_gi_bosskey.o" endseg beginseg name "object_gi_nuts" compress romalign 0x1000 - include "build/baserom/object_gi_nuts.o" + number 6 + include "build/assets/objects/object_gi_nuts/object_gi_nuts.o" endseg beginseg name "object_gi_hearts" compress romalign 0x1000 - include "build/baserom/object_gi_hearts.o" + number 6 + include "build/assets/objects/object_gi_hearts/object_gi_hearts.o" endseg beginseg name "object_gi_arrowcase" compress romalign 0x1000 - include "build/baserom/object_gi_arrowcase.o" + number 6 + include "build/assets/objects/object_gi_arrowcase/object_gi_arrowcase.o" endseg beginseg name "object_gi_bombpouch" compress romalign 0x1000 - include "build/baserom/object_gi_bombpouch.o" + number 6 + include "build/assets/objects/object_gi_bombpouch/object_gi_bombpouch.o" endseg beginseg name "object_in" compress romalign 0x1000 - include "build/baserom/object_in.o" + number 6 + include "build/assets/objects/object_in/object_in.o" endseg beginseg name "object_os_anime" compress romalign 0x1000 - include "build/baserom/object_os_anime.o" + number 6 + include "build/assets/objects/object_os_anime/object_os_anime.o" endseg beginseg name "object_gi_bottle" compress romalign 0x1000 - include "build/baserom/object_gi_bottle.o" + number 6 + include "build/assets/objects/object_gi_bottle/object_gi_bottle.o" endseg beginseg name "object_gi_stick" compress romalign 0x1000 - include "build/baserom/object_gi_stick.o" + number 6 + include "build/assets/objects/object_gi_stick/object_gi_stick.o" endseg beginseg name "object_gi_map" compress romalign 0x1000 - include "build/baserom/object_gi_map.o" + number 6 + include "build/assets/objects/object_gi_map/object_gi_map.o" endseg beginseg name "object_oF1d_map" compress romalign 0x1000 - include "build/baserom/object_oF1d_map.o" + number 6 + include "build/assets/objects/object_oF1d_map/object_oF1d_map.o" endseg beginseg name "object_ru2" compress romalign 0x1000 - include "build/baserom/object_ru2.o" + number 6 + include "build/assets/objects/object_ru2/object_ru2.o" endseg beginseg name "object_gi_magicpot" compress romalign 0x1000 - include "build/baserom/object_gi_magicpot.o" + number 6 + include "build/assets/objects/object_gi_magicpot/object_gi_magicpot.o" endseg beginseg name "object_gi_bomb_1" compress romalign 0x1000 - include "build/baserom/object_gi_bomb_1.o" + number 6 + include "build/assets/objects/object_gi_bomb_1/object_gi_bomb_1.o" endseg beginseg name "object_ma2" compress romalign 0x1000 - include "build/baserom/object_ma2.o" + number 6 + include "build/assets/objects/object_ma2/object_ma2.o" endseg beginseg name "object_gi_purse" compress romalign 0x1000 - include "build/baserom/object_gi_purse.o" + number 6 + include "build/assets/objects/object_gi_purse/object_gi_purse.o" endseg beginseg name "object_rr" compress romalign 0x1000 - include "build/baserom/object_rr.o" + number 6 + include "build/assets/objects/object_rr/object_rr.o" endseg beginseg name "object_gi_arrow" compress romalign 0x1000 - include "build/baserom/object_gi_arrow.o" + number 6 + include "build/assets/objects/object_gi_arrow/object_gi_arrow.o" endseg beginseg name "object_gi_bomb_2" compress romalign 0x1000 - include "build/baserom/object_gi_bomb_2.o" + number 6 + include "build/assets/objects/object_gi_bomb_2/object_gi_bomb_2.o" endseg beginseg name "object_gi_shield_2" compress romalign 0x1000 - include "build/baserom/object_gi_shield_2.o" + number 6 + include "build/assets/objects/object_gi_shield_2/object_gi_shield_2.o" endseg beginseg name "object_gi_hookshot" compress romalign 0x1000 - include "build/baserom/object_gi_hookshot.o" + number 6 + include "build/assets/objects/object_gi_hookshot/object_gi_hookshot.o" endseg beginseg name "object_gi_ocarina" compress romalign 0x1000 - include "build/baserom/object_gi_ocarina.o" + number 6 + include "build/assets/objects/object_gi_ocarina/object_gi_ocarina.o" endseg beginseg name "object_gi_milk" compress romalign 0x1000 - include "build/baserom/object_gi_milk.o" + number 6 + include "build/assets/objects/object_gi_milk/object_gi_milk.o" endseg beginseg name "object_ma1" compress romalign 0x1000 - include "build/baserom/object_ma1.o" + number 6 + include "build/assets/objects/object_ma1/object_ma1.o" endseg beginseg name "object_ny" compress romalign 0x1000 - include "build/baserom/object_ny.o" + number 6 + include "build/assets/objects/object_ny/object_ny.o" endseg beginseg name "object_fr" compress romalign 0x1000 - include "build/baserom/object_fr.o" + number 6 + include "build/assets/objects/object_fr/object_fr.o" endseg beginseg name "object_gi_bow" compress romalign 0x1000 - include "build/baserom/object_gi_bow.o" + number 6 + include "build/assets/objects/object_gi_bow/object_gi_bow.o" endseg beginseg name "object_gi_glasses" compress romalign 0x1000 - include "build/baserom/object_gi_glasses.o" + number 6 + include "build/assets/objects/object_gi_glasses/object_gi_glasses.o" endseg beginseg name "object_gi_liquid" compress romalign 0x1000 - include "build/baserom/object_gi_liquid.o" + number 6 + include "build/assets/objects/object_gi_liquid/object_gi_liquid.o" endseg beginseg name "object_ani" compress romalign 0x1000 - include "build/baserom/object_ani.o" + number 6 + include "build/assets/objects/object_ani/object_ani.o" endseg beginseg name "object_gi_shield_3" compress romalign 0x1000 - include "build/baserom/object_gi_shield_3.o" + number 6 + include "build/assets/objects/object_gi_shield_3/object_gi_shield_3.o" endseg beginseg name "object_gi_bean" compress romalign 0x1000 - include "build/baserom/object_gi_bean.o" + number 6 + include "build/assets/objects/object_gi_bean/object_gi_bean.o" endseg beginseg name "object_gi_fish" compress romalign 0x1000 - include "build/baserom/object_gi_fish.o" + number 6 + include "build/assets/objects/object_gi_fish/object_gi_fish.o" endseg beginseg name "object_gi_longsword" compress romalign 0x1000 - include "build/baserom/object_gi_longsword.o" + number 6 + include "build/assets/objects/object_gi_longsword/object_gi_longsword.o" endseg beginseg name "object_zo" compress romalign 0x1000 - include "build/baserom/object_zo.o" + number 6 + include "build/assets/objects/object_zo/object_zo.o" endseg beginseg name "object_umajump" compress romalign 0x1000 - include "build/baserom/object_umajump.o" + number 6 + include "build/assets/objects/object_umajump/object_umajump.o" endseg beginseg name "object_mastergolon" compress romalign 0x1000 - include "build/baserom/object_mastergolon.o" + number 6 + include "build/assets/objects/object_mastergolon/object_mastergolon.o" endseg beginseg name "object_masterzoora" compress romalign 0x1000 - include "build/baserom/object_masterzoora.o" + number 6 + include "build/assets/objects/object_masterzoora/object_masterzoora.o" endseg beginseg name "object_aob" compress romalign 0x1000 - include "build/baserom/object_aob.o" + number 6 + include "build/assets/objects/object_aob/object_aob.o" endseg beginseg name "object_ik" compress romalign 0x1000 - include "build/baserom/object_ik.o" + number 6 + include "build/assets/objects/object_ik/object_ik.o" endseg beginseg name "object_ahg" compress romalign 0x1000 - include "build/baserom/object_ahg.o" + number 6 + include "build/assets/objects/object_ahg/object_ahg.o" endseg beginseg name "object_cne" compress romalign 0x1000 - include "build/baserom/object_cne.o" + number 6 + include "build/assets/objects/object_cne/object_cne.o" endseg beginseg name "object_bji" compress romalign 0x1000 - include "build/baserom/object_bji.o" + number 6 + include "build/assets/objects/object_bji/object_bji.o" endseg beginseg name "object_bba" compress romalign 0x1000 - include "build/baserom/object_bba.o" + number 6 + include "build/assets/objects/object_bba/object_bba.o" endseg beginseg name "object_an1" compress romalign 0x1000 - include "build/baserom/object_an1.o" + number 6 + include "build/assets/objects/object_an1/object_an1.o" endseg beginseg name "object_boj" compress romalign 0x1000 - include "build/baserom/object_boj.o" + number 6 + include "build/assets/objects/object_boj/object_boj.o" endseg beginseg name "object_fz" compress romalign 0x1000 - include "build/baserom/object_fz.o" + number 6 + include "build/assets/objects/object_fz/object_fz.o" endseg beginseg name "object_bob" compress romalign 0x1000 - include "build/baserom/object_bob.o" + number 6 + include "build/assets/objects/object_bob/object_bob.o" endseg beginseg name "object_ge1" compress romalign 0x1000 - include "build/baserom/object_ge1.o" + number 6 + include "build/assets/objects/object_ge1/object_ge1.o" endseg beginseg name "object_yabusame_point" compress romalign 0x1000 - include "build/baserom/object_yabusame_point.o" + number 6 + include "build/assets/objects/object_yabusame_point/object_yabusame_point.o" endseg beginseg name "object_d_hsblock" compress romalign 0x1000 - include "build/baserom/object_d_hsblock.o" + number 6 + include "build/assets/objects/object_d_hsblock/object_d_hsblock.o" endseg beginseg name "object_d_lift" compress romalign 0x1000 - include "build/baserom/object_d_lift.o" + number 6 + include "build/assets/objects/object_d_lift/object_d_lift.o" endseg beginseg name "object_mamenoki" compress romalign 0x1000 - include "build/baserom/object_mamenoki.o" + number 6 + include "build/assets/objects/object_mamenoki/object_mamenoki.o" endseg beginseg name "object_goroiwa" compress romalign 0x1000 - include "build/baserom/object_goroiwa.o" + number 6 + include "build/assets/objects/object_goroiwa/object_goroiwa.o" endseg beginseg name "object_toryo" compress romalign 0x1000 - include "build/baserom/object_toryo.o" + number 6 + include "build/assets/objects/object_toryo/object_toryo.o" endseg beginseg name "object_daiku" compress romalign 0x1000 - include "build/baserom/object_daiku.o" + number 6 + include "build/assets/objects/object_daiku/object_daiku.o" endseg beginseg name "object_nwc" compress romalign 0x1000 - include "build/baserom/object_nwc.o" + number 6 + include "build/assets/objects/object_nwc/object_nwc.o" endseg beginseg name "object_gm" compress romalign 0x1000 - include "build/baserom/object_gm.o" + number 6 + include "build/assets/objects/object_gm/object_gm.o" endseg beginseg name "object_ms" compress romalign 0x1000 - include "build/baserom/object_ms.o" + number 6 + include "build/assets/objects/object_ms/object_ms.o" endseg beginseg name "object_hs" compress romalign 0x1000 - include "build/baserom/object_hs.o" + number 6 + include "build/assets/objects/object_hs/object_hs.o" endseg beginseg name "object_lightswitch" compress romalign 0x1000 - include "build/baserom/object_lightswitch.o" + number 6 + include "build/assets/objects/object_lightswitch/object_lightswitch.o" endseg beginseg name "object_kusa" compress romalign 0x1000 - include "build/baserom/object_kusa.o" + number 6 + include "build/assets/objects/object_kusa/object_kusa.o" endseg beginseg name "object_tsubo" compress romalign 0x1000 - include "build/baserom/object_tsubo.o" + number 6 + include "build/assets/objects/object_tsubo/object_tsubo.o" endseg beginseg name "object_kanban" compress romalign 0x1000 - include "build/baserom/object_kanban.o" + number 6 + include "build/assets/objects/object_kanban/object_kanban.o" endseg beginseg name "object_owl" compress romalign 0x1000 - include "build/baserom/object_owl.o" + number 6 + include "build/assets/objects/object_owl/object_owl.o" endseg beginseg name "object_mk" compress romalign 0x1000 - include "build/baserom/object_mk.o" + number 6 + include "build/assets/objects/object_mk/object_mk.o" endseg beginseg name "object_fu" compress romalign 0x1000 - include "build/baserom/object_fu.o" + number 6 + include "build/assets/objects/object_fu/object_fu.o" endseg beginseg name "object_gi_ki_tan_mask" compress romalign 0x1000 - include "build/baserom/object_gi_ki_tan_mask.o" + number 6 + include "build/assets/objects/object_gi_ki_tan_mask/object_gi_ki_tan_mask.o" endseg beginseg name "object_gi_mask18" compress romalign 0x1000 - include "build/baserom/object_gi_mask18.o" + number 6 + include "build/assets/objects/object_gi_mask18/object_gi_mask18.o" endseg beginseg name "object_gi_rabit_mask" compress romalign 0x1000 - include "build/baserom/object_gi_rabit_mask.o" + number 6 + include "build/assets/objects/object_gi_rabit_mask/object_gi_rabit_mask.o" endseg beginseg name "object_gi_truth_mask" compress romalign 0x1000 - include "build/baserom/object_gi_truth_mask.o" + number 6 + include "build/assets/objects/object_gi_truth_mask/object_gi_truth_mask.o" endseg beginseg name "object_stream" compress romalign 0x1000 - include "build/baserom/object_stream.o" + number 6 + include "build/assets/objects/object_stream/object_stream.o" endseg beginseg name "object_mm" compress romalign 0x1000 - include "build/baserom/object_mm.o" + number 6 + include "build/assets/objects/object_mm/object_mm.o" endseg beginseg name "object_js" compress romalign 0x1000 - include "build/baserom/object_js.o" + number 6 + include "build/assets/objects/object_js/object_js.o" endseg beginseg name "object_cs" compress romalign 0x1000 - include "build/baserom/object_cs.o" + number 6 + include "build/assets/objects/object_cs/object_cs.o" endseg beginseg name "object_gi_soldout" compress romalign 0x1000 - include "build/baserom/object_gi_soldout.o" + number 6 + include "build/assets/objects/object_gi_soldout/object_gi_soldout.o" endseg beginseg name "object_mag" compress romalign 0x1000 - include "build/baserom/object_mag.o" + number 6 + include "build/assets/objects/object_mag/object_mag.o" endseg beginseg name "object_gi_golonmask" compress romalign 0x1000 - include "build/baserom/object_gi_golonmask.o" + number 6 + include "build/assets/objects/object_gi_golonmask/object_gi_golonmask.o" endseg beginseg name "object_gi_zoramask" compress romalign 0x1000 - include "build/baserom/object_gi_zoramask.o" + number 6 + include "build/assets/objects/object_gi_zoramask/object_gi_zoramask.o" endseg beginseg name "object_ka" compress romalign 0x1000 - include "build/baserom/object_ka.o" + number 6 + include "build/assets/objects/object_ka/object_ka.o" endseg beginseg name "object_zg" compress romalign 0x1000 - include "build/baserom/object_zg.o" + number 6 + include "build/assets/objects/object_zg/object_zg.o" endseg beginseg name "object_gi_m_arrow" compress romalign 0x1000 - include "build/baserom/object_gi_m_arrow.o" + number 6 + include "build/assets/objects/object_gi_m_arrow/object_gi_m_arrow.o" endseg beginseg name "object_ds2" compress romalign 0x1000 - include "build/baserom/object_ds2.o" + number 6 + include "build/assets/objects/object_ds2/object_ds2.o" endseg beginseg name "object_fish" compress romalign 0x1000 - include "build/baserom/object_fish.o" + number 6 + include "build/assets/objects/object_fish/object_fish.o" endseg beginseg name "object_gi_sutaru" compress romalign 0x1000 - include "build/baserom/object_gi_sutaru.o" + number 6 + include "build/assets/objects/object_gi_sutaru/object_gi_sutaru.o" endseg beginseg name "object_ssh" compress romalign 0x1000 - include "build/baserom/object_ssh.o" + number 6 + include "build/assets/objects/object_ssh/object_ssh.o" endseg beginseg name "object_bigslime" compress romalign 0x1000 - include "build/baserom/object_bigslime.o" + number 6 + include "build/assets/objects/object_bigslime/object_bigslime.o" endseg beginseg name "object_bg" compress romalign 0x1000 - include "build/baserom/object_bg.o" + number 6 + include "build/assets/objects/object_bg/object_bg.o" endseg beginseg name "object_bombiwa" compress romalign 0x1000 - include "build/baserom/object_bombiwa.o" + number 6 + include "build/assets/objects/object_bombiwa/object_bombiwa.o" endseg beginseg name "object_hintnuts" compress romalign 0x1000 - include "build/baserom/object_hintnuts.o" + number 6 + include "build/assets/objects/object_hintnuts/object_hintnuts.o" endseg beginseg name "object_rs" compress romalign 0x1000 - include "build/baserom/object_rs.o" + number 6 + include "build/assets/objects/object_rs/object_rs.o" endseg beginseg name "object_gla" compress romalign 0x1000 - include "build/baserom/object_gla.o" + number 6 + include "build/assets/objects/object_gla/object_gla.o" endseg beginseg name "object_geldb" compress romalign 0x1000 - include "build/baserom/object_geldb.o" + number 6 + include "build/assets/objects/object_geldb/object_geldb.o" endseg beginseg name "object_dog" compress romalign 0x1000 - include "build/baserom/object_dog.o" + number 6 + include "build/assets/objects/object_dog/object_dog.o" endseg beginseg name "object_kibako2" compress romalign 0x1000 - include "build/baserom/object_kibako2.o" + number 6 + include "build/assets/objects/object_kibako2/object_kibako2.o" endseg beginseg name "object_dns" compress romalign 0x1000 - include "build/baserom/object_dns.o" + number 6 + include "build/assets/objects/object_dns/object_dns.o" endseg beginseg name "object_dnk" compress romalign 0x1000 - include "build/baserom/object_dnk.o" + number 6 + include "build/assets/objects/object_dnk/object_dnk.o" endseg beginseg name "object_gi_insect" compress romalign 0x1000 - include "build/baserom/object_gi_insect.o" + number 6 + include "build/assets/objects/object_gi_insect/object_gi_insect.o" endseg beginseg name "object_gi_ghost" compress romalign 0x1000 - include "build/baserom/object_gi_ghost.o" + number 6 + include "build/assets/objects/object_gi_ghost/object_gi_ghost.o" endseg beginseg name "object_gi_soul" compress romalign 0x1000 - include "build/baserom/object_gi_soul.o" + number 6 + include "build/assets/objects/object_gi_soul/object_gi_soul.o" endseg beginseg name "object_f40_obj" compress romalign 0x1000 - include "build/baserom/object_f40_obj.o" + number 6 + include "build/assets/objects/object_f40_obj/object_f40_obj.o" endseg beginseg name "object_gi_rupy" compress romalign 0x1000 - include "build/baserom/object_gi_rupy.o" + number 6 + include "build/assets/objects/object_gi_rupy/object_gi_rupy.o" endseg beginseg name "object_po_composer" compress romalign 0x1000 - include "build/baserom/object_po_composer.o" + number 6 + include "build/assets/objects/object_po_composer/object_po_composer.o" endseg beginseg name "object_mu" compress romalign 0x1000 - include "build/baserom/object_mu.o" + number 6 + include "build/assets/objects/object_mu/object_mu.o" endseg beginseg name "object_wf" compress romalign 0x1000 - include "build/baserom/object_wf.o" + number 6 + include "build/assets/objects/object_wf/object_wf.o" endseg beginseg name "object_skb" compress romalign 0x1000 - include "build/baserom/object_skb.o" + number 6 + include "build/assets/objects/object_skb/object_skb.o" endseg beginseg name "object_gs" compress romalign 0x1000 - include "build/baserom/object_gs.o" + number 6 + include "build/assets/objects/object_gs/object_gs.o" endseg beginseg name "object_ps" compress romalign 0x1000 - include "build/baserom/object_ps.o" + number 6 + include "build/assets/objects/object_ps/object_ps.o" endseg beginseg name "object_omoya_obj" compress romalign 0x1000 - include "build/baserom/object_omoya_obj.o" + number 6 + include "build/assets/objects/object_omoya_obj/object_omoya_obj.o" endseg beginseg name "object_crow" compress romalign 0x1000 - include "build/baserom/object_crow.o" + number 6 + include "build/assets/objects/object_crow/object_crow.o" endseg beginseg name "object_cow" compress romalign 0x1000 - include "build/baserom/object_cow.o" + number 6 + include "build/assets/objects/object_cow/object_cow.o" endseg beginseg name "object_gi_sword_1" compress romalign 0x1000 - include "build/baserom/object_gi_sword_1.o" + number 6 + include "build/assets/objects/object_gi_sword_1/object_gi_sword_1.o" endseg beginseg name "object_zl4" compress romalign 0x1000 - include "build/baserom/object_zl4.o" + number 6 + include "build/assets/objects/object_zl4/object_zl4.o" endseg beginseg name "object_grasshopper" compress romalign 0x1000 - include "build/baserom/object_grasshopper.o" + number 6 + include "build/assets/objects/object_grasshopper/object_grasshopper.o" endseg beginseg name "object_boyo" compress romalign 0x1000 - include "build/baserom/object_boyo.o" + number 6 + include "build/assets/objects/object_boyo/object_boyo.o" endseg beginseg name "object_fwall" compress romalign 0x1000 - include "build/baserom/object_fwall.o" + number 6 + include "build/assets/objects/object_fwall/object_fwall.o" endseg beginseg name "object_jso" compress romalign 0x1000 - include "build/baserom/object_jso.o" + number 6 + include "build/assets/objects/object_jso/object_jso.o" endseg beginseg name "object_knight" compress romalign 0x1000 - include "build/baserom/object_knight.o" + number 6 + include "build/assets/objects/object_knight/object_knight.o" endseg beginseg name "object_icicle" compress romalign 0x1000 - include "build/baserom/object_icicle.o" + number 6 + include "build/assets/objects/object_icicle/object_icicle.o" endseg beginseg name "object_spdweb" compress romalign 0x1000 - include "build/baserom/object_spdweb.o" + number 6 + include "build/assets/objects/object_spdweb/object_spdweb.o" endseg beginseg name "object_boss01" compress romalign 0x1000 - include "build/baserom/object_boss01.o" + number 6 + include "build/assets/objects/object_boss01/object_boss01.o" endseg beginseg name "object_boss02" compress romalign 0x1000 - include "build/baserom/object_boss02.o" + number 6 + include "build/assets/objects/object_boss02/object_boss02.o" endseg beginseg name "object_boss03" compress romalign 0x1000 - include "build/baserom/object_boss03.o" + number 6 + include "build/assets/objects/object_boss03/object_boss03.o" endseg beginseg name "object_boss04" compress romalign 0x1000 - include "build/baserom/object_boss04.o" + number 6 + include "build/assets/objects/object_boss04/object_boss04.o" endseg beginseg name "object_boss05" compress romalign 0x1000 - include "build/baserom/object_boss05.o" + number 6 + include "build/assets/objects/object_boss05/object_boss05.o" endseg beginseg name "object_boss07" compress romalign 0x1000 - include "build/baserom/object_boss07.o" + number 6 + include "build/assets/objects/object_boss07/object_boss07.o" endseg beginseg name "object_raf" compress romalign 0x1000 - include "build/baserom/object_raf.o" + number 6 + include "build/assets/objects/object_raf/object_raf.o" endseg beginseg name "object_funen" compress romalign 0x1000 - include "build/baserom/object_funen.o" + number 6 + include "build/assets/objects/object_funen/object_funen.o" endseg beginseg name "object_raillift" compress romalign 0x1000 - include "build/baserom/object_raillift.o" + number 6 + include "build/assets/objects/object_raillift/object_raillift.o" endseg beginseg name "object_numa_obj" compress romalign 0x1000 - include "build/baserom/object_numa_obj.o" + number 6 + include "build/assets/objects/object_numa_obj/object_numa_obj.o" endseg beginseg name "object_flowerpot" compress romalign 0x1000 - include "build/baserom/object_flowerpot.o" + number 6 + include "build/assets/objects/object_flowerpot/object_flowerpot.o" endseg beginseg name "object_spinyroll" compress romalign 0x1000 - include "build/baserom/object_spinyroll.o" + number 6 + include "build/assets/objects/object_spinyroll/object_spinyroll.o" endseg beginseg name "object_ice_block" compress romalign 0x1000 - include "build/baserom/object_ice_block.o" + number 6 + include "build/assets/objects/object_ice_block/object_ice_block.o" endseg beginseg name "object_keikoku_demo" compress romalign 0x1000 - include "build/baserom/object_keikoku_demo.o" + number 6 + include "build/assets/objects/object_keikoku_demo/object_keikoku_demo.o" endseg beginseg name "object_slime" compress romalign 0x1000 - include "build/baserom/object_slime.o" + number 6 + include "build/assets/objects/object_slime/object_slime.o" endseg beginseg name "object_pr" compress romalign 0x1000 - include "build/baserom/object_pr.o" + number 6 + include "build/assets/objects/object_pr/object_pr.o" endseg beginseg name "object_f52_obj" compress romalign 0x1000 - include "build/baserom/object_f52_obj.o" + number 6 + include "build/assets/objects/object_f52_obj/object_f52_obj.o" endseg beginseg name "object_f53_obj" compress romalign 0x1000 - include "build/baserom/object_f53_obj.o" + number 6 + include "build/assets/objects/object_f53_obj/object_f53_obj.o" endseg beginseg name "object_kibako" compress romalign 0x1000 - include "build/baserom/object_kibako.o" + number 6 + include "build/assets/objects/object_kibako/object_kibako.o" endseg beginseg name "object_sek" compress romalign 0x1000 - include "build/baserom/object_sek.o" + number 6 + include "build/assets/objects/object_sek/object_sek.o" endseg beginseg name "object_gmo" compress romalign 0x1000 - include "build/baserom/object_gmo.o" + number 6 + include "build/assets/objects/object_gmo/object_gmo.o" endseg beginseg name "object_bat" compress romalign 0x1000 - include "build/baserom/object_bat.o" + number 6 + include "build/assets/objects/object_bat/object_bat.o" endseg beginseg name "object_sekihil" compress romalign 0x1000 - include "build/baserom/object_sekihil.o" + number 6 + include "build/assets/objects/object_sekihil/object_sekihil.o" endseg beginseg name "object_sekihig" compress romalign 0x1000 - include "build/baserom/object_sekihig.o" + number 6 + include "build/assets/objects/object_sekihig/object_sekihig.o" endseg beginseg name "object_sekihin" compress romalign 0x1000 - include "build/baserom/object_sekihin.o" + number 6 + include "build/assets/objects/object_sekihin/object_sekihin.o" endseg beginseg name "object_sekihiz" compress romalign 0x1000 - include "build/baserom/object_sekihiz.o" + number 6 + include "build/assets/objects/object_sekihiz/object_sekihiz.o" endseg beginseg name "object_wiz" compress romalign 0x1000 - include "build/baserom/object_wiz.o" + number 6 + include "build/assets/objects/object_wiz/object_wiz.o" endseg beginseg name "object_ladder" compress romalign 0x1000 - include "build/baserom/object_ladder.o" + number 6 + include "build/assets/objects/object_ladder/object_ladder.o" endseg beginseg name "object_mkk" compress romalign 0x1000 - include "build/baserom/object_mkk.o" + number 6 + include "build/assets/objects/object_mkk/object_mkk.o" endseg beginseg name "object_keikoku_obj" compress romalign 0x1000 - include "build/baserom/object_keikoku_obj.o" + number 6 + include "build/assets/objects/object_keikoku_obj/object_keikoku_obj.o" endseg beginseg name "object_sichitai_obj" compress romalign 0x1000 - include "build/baserom/object_sichitai_obj.o" + number 6 + include "build/assets/objects/object_sichitai_obj/object_sichitai_obj.o" endseg beginseg name "object_dekucity_ana_obj" compress romalign 0x1000 - include "build/baserom/object_dekucity_ana_obj.o" + number 6 + include "build/assets/objects/object_dekucity_ana_obj/object_dekucity_ana_obj.o" endseg beginseg name "object_rat" compress romalign 0x1000 - include "build/baserom/object_rat.o" + number 6 + include "build/assets/objects/object_rat/object_rat.o" endseg beginseg name "object_water_effect" compress romalign 0x1000 - include "build/baserom/object_water_effect.o" + number 6 + include "build/assets/objects/object_water_effect/object_water_effect.o" endseg beginseg name "object_dblue_object" compress romalign 0x1000 - include "build/baserom/object_dblue_object.o" + number 6 + include "build/assets/objects/object_dblue_object/object_dblue_object.o" endseg beginseg name "object_bal" compress romalign 0x1000 - include "build/baserom/object_bal.o" + number 6 + include "build/assets/objects/object_bal/object_bal.o" endseg beginseg name "object_warp_uzu" compress romalign 0x1000 - include "build/baserom/object_warp_uzu.o" + number 6 + include "build/assets/objects/object_warp_uzu/object_warp_uzu.o" endseg beginseg name "object_driftice" compress romalign 0x1000 - include "build/baserom/object_driftice.o" + number 6 + include "build/assets/objects/object_driftice/object_driftice.o" endseg beginseg name "object_fall" compress romalign 0x1000 - include "build/baserom/object_fall.o" + number 6 + include "build/assets/objects/object_fall/object_fall.o" endseg beginseg name "object_hanareyama_obj" compress romalign 0x1000 - include "build/baserom/object_hanareyama_obj.o" + number 6 + include "build/assets/objects/object_hanareyama_obj/object_hanareyama_obj.o" endseg beginseg name "object_crace_object" compress romalign 0x1000 - include "build/baserom/object_crace_object.o" + number 6 + include "build/assets/objects/object_crace_object/object_crace_object.o" endseg beginseg name "object_dnq" compress romalign 0x1000 - include "build/baserom/object_dnq.o" + number 6 + include "build/assets/objects/object_dnq/object_dnq.o" endseg beginseg name "object_obj_tokeidai" compress romalign 0x1000 - include "build/baserom/object_obj_tokeidai.o" + number 6 + include "build/assets/objects/object_obj_tokeidai/object_obj_tokeidai.o" endseg beginseg name "object_eg" compress romalign 0x1000 - include "build/baserom/object_eg.o" + number 6 + include "build/assets/objects/object_eg/object_eg.o" endseg beginseg name "object_tru" compress romalign 0x1000 - include "build/baserom/object_tru.o" + number 6 + include "build/assets/objects/object_tru/object_tru.o" endseg beginseg name "object_trt" compress romalign 0x1000 - include "build/baserom/object_trt.o" + number 6 + include "build/assets/objects/object_trt/object_trt.o" endseg beginseg name "object_hakugin_obj" compress romalign 0x1000 - include "build/baserom/object_hakugin_obj.o" + number 6 + include "build/assets/objects/object_hakugin_obj/object_hakugin_obj.o" endseg beginseg name "object_horse_game_check" compress romalign 0x1000 - include "build/baserom/object_horse_game_check.o" + number 6 + include "build/assets/objects/object_horse_game_check/object_horse_game_check.o" endseg beginseg name "object_stk" compress romalign 0x1000 - include "build/baserom/object_stk.o" + number 6 + include "build/assets/objects/object_stk/object_stk.o" endseg beginseg name "object_mnk" compress romalign 0x1000 - include "build/baserom/object_mnk.o" + number 6 + include "build/assets/objects/object_mnk/object_mnk.o" endseg beginseg name "object_gi_bottle_red" compress romalign 0x1000 - include "build/baserom/object_gi_bottle_red.o" + number 6 + include "build/assets/objects/object_gi_bottle_red/object_gi_bottle_red.o" endseg beginseg name "object_tokei_tobira" compress romalign 0x1000 - include "build/baserom/object_tokei_tobira.o" + number 6 + include "build/assets/objects/object_tokei_tobira/object_tokei_tobira.o" endseg beginseg name "object_az" compress romalign 0x1000 - include "build/baserom/object_az.o" + number 6 + include "build/assets/objects/object_az/object_az.o" endseg beginseg name "object_twig" compress romalign 0x1000 - include "build/baserom/object_twig.o" + number 6 + include "build/assets/objects/object_twig/object_twig.o" endseg beginseg name "object_dekucity_obj" compress romalign 0x1000 - include "build/baserom/object_dekucity_obj.o" + number 6 + include "build/assets/objects/object_dekucity_obj/object_dekucity_obj.o" endseg beginseg name "object_po_fusen" compress romalign 0x1000 - include "build/baserom/object_po_fusen.o" + number 6 + include "build/assets/objects/object_po_fusen/object_po_fusen.o" endseg beginseg name "object_racetsubo" compress romalign 0x1000 - include "build/baserom/object_racetsubo.o" + number 6 + include "build/assets/objects/object_racetsubo/object_racetsubo.o" endseg beginseg name "object_ha" compress romalign 0x1000 - include "build/baserom/object_ha.o" + number 6 + include "build/assets/objects/object_ha/object_ha.o" endseg beginseg name "object_bigokuta" compress romalign 0x1000 - include "build/baserom/object_bigokuta.o" + number 6 + include "build/assets/objects/object_bigokuta/object_bigokuta.o" endseg beginseg name "object_open_obj" compress romalign 0x1000 - include "build/baserom/object_open_obj.o" + number 6 + include "build/assets/objects/object_open_obj/object_open_obj.o" endseg beginseg name "object_fu_kaiten" compress romalign 0x1000 - include "build/baserom/object_fu_kaiten.o" + number 6 + include "build/assets/objects/object_fu_kaiten/object_fu_kaiten.o" endseg beginseg name "object_fu_mato" compress romalign 0x1000 - include "build/baserom/object_fu_mato.o" + number 6 + include "build/assets/objects/object_fu_mato/object_fu_mato.o" endseg beginseg name "object_mtoride" compress romalign 0x1000 - include "build/baserom/object_mtoride.o" + number 6 + include "build/assets/objects/object_mtoride/object_mtoride.o" endseg beginseg name "object_osn" compress romalign 0x1000 - include "build/baserom/object_osn.o" + number 6 + include "build/assets/objects/object_osn/object_osn.o" endseg beginseg name "object_tokei_step" compress romalign 0x1000 - include "build/baserom/object_tokei_step.o" + number 6 + include "build/assets/objects/object_tokei_step/object_tokei_step.o" endseg beginseg name "object_lotus" compress romalign 0x1000 - include "build/baserom/object_lotus.o" + number 6 + include "build/assets/objects/object_lotus/object_lotus.o" endseg beginseg name "object_tl" compress romalign 0x1000 - include "build/baserom/object_tl.o" + number 6 + include "build/assets/objects/object_tl/object_tl.o" endseg beginseg name "object_dkjail_obj" compress romalign 0x1000 - include "build/baserom/object_dkjail_obj.o" + number 6 + include "build/assets/objects/object_dkjail_obj/object_dkjail_obj.o" endseg beginseg name "object_visiblock" compress romalign 0x1000 - include "build/baserom/object_visiblock.o" + number 6 + include "build/assets/objects/object_visiblock/object_visiblock.o" endseg beginseg name "object_tsn" compress romalign 0x1000 - include "build/baserom/object_tsn.o" + number 6 + include "build/assets/objects/object_tsn/object_tsn.o" endseg beginseg name "object_ds2n" compress romalign 0x1000 - include "build/baserom/object_ds2n.o" + number 6 + include "build/assets/objects/object_ds2n/object_ds2n.o" endseg beginseg name "object_fsn" compress romalign 0x1000 - include "build/baserom/object_fsn.o" + number 6 + include "build/assets/objects/object_fsn/object_fsn.o" endseg beginseg name "object_shn" compress romalign 0x1000 - include "build/baserom/object_shn.o" + number 6 + include "build/assets/objects/object_shn/object_shn.o" endseg beginseg name "object_bigicicle" compress romalign 0x1000 - include "build/baserom/object_bigicicle.o" + number 6 + include "build/assets/objects/object_bigicicle/object_bigicicle.o" endseg beginseg name "object_gi_bottle_15" compress romalign 0x1000 - include "build/baserom/object_gi_bottle_15.o" + number 6 + include "build/assets/objects/object_gi_bottle_15/object_gi_bottle_15.o" endseg beginseg name "object_tk" compress romalign 0x1000 - include "build/baserom/object_tk.o" + number 6 + include "build/assets/objects/object_tk/object_tk.o" endseg beginseg name "object_market_obj" compress romalign 0x1000 - include "build/baserom/object_market_obj.o" + number 6 + include "build/assets/objects/object_market_obj/object_market_obj.o" endseg beginseg name "object_gi_reserve00" compress romalign 0x1000 - include "build/baserom/object_gi_reserve00.o" + number 6 + include "build/assets/objects/object_gi_reserve00/object_gi_reserve00.o" endseg beginseg name "object_gi_reserve01" compress romalign 0x1000 - include "build/baserom/object_gi_reserve01.o" + number 6 + include "build/assets/objects/object_gi_reserve01/object_gi_reserve01.o" endseg beginseg name "object_lightblock" compress romalign 0x1000 - include "build/baserom/object_lightblock.o" + number 6 + include "build/assets/objects/object_lightblock/object_lightblock.o" endseg beginseg name "object_takaraya_objects" compress romalign 0x1000 - include "build/baserom/object_takaraya_objects.o" + number 6 + include "build/assets/objects/object_takaraya_objects/object_takaraya_objects.o" endseg beginseg name "object_wdhand" compress romalign 0x1000 - include "build/baserom/object_wdhand.o" + number 6 + include "build/assets/objects/object_wdhand/object_wdhand.o" endseg beginseg name "object_sdn" compress romalign 0x1000 - include "build/baserom/object_sdn.o" + number 6 + include "build/assets/objects/object_sdn/object_sdn.o" endseg beginseg name "object_snowwd" compress romalign 0x1000 - include "build/baserom/object_snowwd.o" + number 6 + include "build/assets/objects/object_snowwd/object_snowwd.o" endseg beginseg name "object_giant" compress romalign 0x1000 - include "build/baserom/object_giant.o" + number 6 + include "build/assets/objects/object_giant/object_giant.o" endseg beginseg name "object_comb" compress romalign 0x1000 - include "build/baserom/object_comb.o" + number 6 + include "build/assets/objects/object_comb/object_comb.o" endseg beginseg name "object_hana" compress romalign 0x1000 - include "build/baserom/object_hana.o" + number 6 + include "build/assets/objects/object_hana/object_hana.o" endseg beginseg name "object_boss_hakugin" compress romalign 0x1000 - include "build/baserom/object_boss_hakugin.o" + number 6 + include "build/assets/objects/object_boss_hakugin/object_boss_hakugin.o" endseg beginseg name "object_meganeana_obj" compress romalign 0x1000 - include "build/baserom/object_meganeana_obj.o" + number 6 + include "build/assets/objects/object_meganeana_obj/object_meganeana_obj.o" endseg beginseg name "object_gi_nutsmask" compress romalign 0x1000 - include "build/baserom/object_gi_nutsmask.o" + number 6 + include "build/assets/objects/object_gi_nutsmask/object_gi_nutsmask.o" endseg beginseg name "object_stk2" compress romalign 0x1000 - include "build/baserom/object_stk2.o" + number 6 + include "build/assets/objects/object_stk2/object_stk2.o" endseg beginseg name "object_spot11_obj" compress romalign 0x1000 - include "build/baserom/object_spot11_obj.o" + number 6 + include "build/assets/objects/object_spot11_obj/object_spot11_obj.o" endseg beginseg name "object_danpei_object" compress romalign 0x1000 - include "build/baserom/object_danpei_object.o" + number 6 + include "build/assets/objects/object_danpei_object/object_danpei_object.o" endseg beginseg name "object_dhouse" compress romalign 0x1000 - include "build/baserom/object_dhouse.o" + number 6 + include "build/assets/objects/object_dhouse/object_dhouse.o" endseg beginseg name "object_hakaisi" compress romalign 0x1000 - include "build/baserom/object_hakaisi.o" + number 6 + include "build/assets/objects/object_hakaisi/object_hakaisi.o" endseg beginseg name "object_po" compress romalign 0x1000 - include "build/baserom/object_po.o" + number 6 + include "build/assets/objects/object_po/object_po.o" endseg beginseg name "object_snowman" compress romalign 0x1000 - include "build/baserom/object_snowman.o" + number 6 + include "build/assets/objects/object_snowman/object_snowman.o" endseg beginseg name "object_po_sisters" compress romalign 0x1000 - include "build/baserom/object_po_sisters.o" + number 6 + include "build/assets/objects/object_po_sisters/object_po_sisters.o" endseg beginseg name "object_pp" compress romalign 0x1000 - include "build/baserom/object_pp.o" + number 6 + include "build/assets/objects/object_pp/object_pp.o" endseg beginseg name "object_goronswitch" compress romalign 0x1000 - include "build/baserom/object_goronswitch.o" + number 6 + include "build/assets/objects/object_goronswitch/object_goronswitch.o" endseg beginseg name "object_delf" compress romalign 0x1000 - include "build/baserom/object_delf.o" + number 6 + include "build/assets/objects/object_delf/object_delf.o" endseg beginseg name "object_botihasira" compress romalign 0x1000 - include "build/baserom/object_botihasira.o" + number 6 + include "build/assets/objects/object_botihasira/object_botihasira.o" endseg beginseg name "object_gi_bigbomb" compress romalign 0x1000 - include "build/baserom/object_gi_bigbomb.o" + number 6 + include "build/assets/objects/object_gi_bigbomb/object_gi_bigbomb.o" endseg beginseg name "object_pst" compress romalign 0x1000 - include "build/baserom/object_pst.o" + number 6 + include "build/assets/objects/object_pst/object_pst.o" endseg beginseg name "object_bsmask" compress romalign 0x1000 - include "build/baserom/object_bsmask.o" + number 6 + include "build/assets/objects/object_bsmask/object_bsmask.o" endseg beginseg name "object_spidertent" compress romalign 0x1000 - include "build/baserom/object_spidertent.o" + number 6 + include "build/assets/objects/object_spidertent/object_spidertent.o" endseg beginseg name "object_zoraegg" compress romalign 0x1000 - include "build/baserom/object_zoraegg.o" + number 6 + include "build/assets/objects/object_zoraegg/object_zoraegg.o" endseg beginseg name "object_kbt" compress romalign 0x1000 - include "build/baserom/object_kbt.o" + number 6 + include "build/assets/objects/object_kbt/object_kbt.o" endseg beginseg name "object_gg" compress romalign 0x1000 - include "build/baserom/object_gg.o" + number 6 + include "build/assets/objects/object_gg/object_gg.o" endseg beginseg name "object_maruta" compress romalign 0x1000 - include "build/baserom/object_maruta.o" + number 6 + include "build/assets/objects/object_maruta/object_maruta.o" endseg beginseg name "object_ghaka" compress romalign 0x1000 - include "build/baserom/object_ghaka.o" + number 6 + include "build/assets/objects/object_ghaka/object_ghaka.o" endseg beginseg name "object_oyu" compress romalign 0x1000 - include "build/baserom/object_oyu.o" + number 6 + include "build/assets/objects/object_oyu/object_oyu.o" endseg beginseg name "object_dnp" compress romalign 0x1000 - include "build/baserom/object_dnp.o" + number 6 + include "build/assets/objects/object_dnp/object_dnp.o" endseg beginseg name "object_dai" compress romalign 0x1000 - include "build/baserom/object_dai.o" + number 6 + include "build/assets/objects/object_dai/object_dai.o" endseg beginseg name "object_kgy" compress romalign 0x1000 - include "build/baserom/object_kgy.o" + number 6 + include "build/assets/objects/object_kgy/object_kgy.o" endseg beginseg name "object_fb" compress romalign 0x1000 - include "build/baserom/object_fb.o" + number 6 + include "build/assets/objects/object_fb/object_fb.o" endseg beginseg name "object_taisou" compress romalign 0x1000 - include "build/baserom/object_taisou.o" + number 6 + include "build/assets/objects/object_taisou/object_taisou.o" endseg beginseg name "object_gk" compress romalign 0x1000 - include "build/baserom/object_gk.o" + number 6 + include "build/assets/objects/object_gk/object_gk.o" endseg beginseg name "object_haka_obj" compress romalign 0x1000 - include "build/baserom/object_haka_obj.o" + number 6 + include "build/assets/objects/object_haka_obj/object_haka_obj.o" endseg beginseg name "object_dnt" compress romalign 0x1000 - include "build/baserom/object_dnt.o" + number 6 + include "build/assets/objects/object_dnt/object_dnt.o" endseg beginseg name "object_yukiyama" compress romalign 0x1000 - include "build/baserom/object_yukiyama.o" + number 6 + include "build/assets/objects/object_yukiyama/object_yukiyama.o" endseg beginseg name "object_icefloe" compress romalign 0x1000 - include "build/baserom/object_icefloe.o" + number 6 + include "build/assets/objects/object_icefloe/object_icefloe.o" endseg beginseg name "object_gi_gold_dust" compress romalign 0x1000 - include "build/baserom/object_gi_gold_dust.o" + number 6 + include "build/assets/objects/object_gi_gold_dust/object_gi_gold_dust.o" endseg beginseg name "object_gi_bottle_16" compress romalign 0x1000 - include "build/baserom/object_gi_bottle_16.o" + number 6 + include "build/assets/objects/object_gi_bottle_16/object_gi_bottle_16.o" endseg beginseg name "object_gi_bottle_22" compress romalign 0x1000 - include "build/baserom/object_gi_bottle_22.o" + number 6 + include "build/assets/objects/object_gi_bottle_22/object_gi_bottle_22.o" endseg beginseg name "object_bee" compress romalign 0x1000 - include "build/baserom/object_bee.o" + number 6 + include "build/assets/objects/object_bee/object_bee.o" endseg beginseg name "object_ot" compress romalign 0x1000 - include "build/baserom/object_ot.o" + number 6 + include "build/assets/objects/object_ot/object_ot.o" endseg beginseg name "object_utubo" compress romalign 0x1000 - include "build/baserom/object_utubo.o" + number 6 + include "build/assets/objects/object_utubo/object_utubo.o" endseg beginseg name "object_dora" compress romalign 0x1000 - include "build/baserom/object_dora.o" + number 6 + include "build/assets/objects/object_dora/object_dora.o" endseg beginseg name "object_gi_loach" compress romalign 0x1000 - include "build/baserom/object_gi_loach.o" + number 6 + include "build/assets/objects/object_gi_loach/object_gi_loach.o" endseg beginseg name "object_gi_seahorse" compress romalign 0x1000 - include "build/baserom/object_gi_seahorse.o" + number 6 + include "build/assets/objects/object_gi_seahorse/object_gi_seahorse.o" endseg beginseg name "object_bigpo" compress romalign 0x1000 - include "build/baserom/object_bigpo.o" + number 6 + include "build/assets/objects/object_bigpo/object_bigpo.o" endseg beginseg name "object_hariko" compress romalign 0x1000 - include "build/baserom/object_hariko.o" + number 6 + include "build/assets/objects/object_hariko/object_hariko.o" endseg beginseg name "object_dno" compress romalign 0x1000 - include "build/baserom/object_dno.o" + number 6 + include "build/assets/objects/object_dno/object_dno.o" endseg beginseg name "object_sinkai_kabe" compress romalign 0x1000 - include "build/baserom/object_sinkai_kabe.o" + number 6 + include "build/assets/objects/object_sinkai_kabe/object_sinkai_kabe.o" endseg beginseg name "object_kin2_obj" compress romalign 0x1000 - include "build/baserom/object_kin2_obj.o" + number 6 + include "build/assets/objects/object_kin2_obj/object_kin2_obj.o" endseg beginseg name "object_ishi" compress romalign 0x1000 - include "build/baserom/object_ishi.o" + number 6 + include "build/assets/objects/object_ishi/object_ishi.o" endseg beginseg name "object_hakugin_demo" compress romalign 0x1000 - include "build/baserom/object_hakugin_demo.o" + number 6 + include "build/assets/objects/object_hakugin_demo/object_hakugin_demo.o" endseg beginseg name "object_jg" compress romalign 0x1000 - include "build/baserom/object_jg.o" + number 6 + include "build/assets/objects/object_jg/object_jg.o" endseg beginseg name "object_gi_sword_2" compress romalign 0x1000 - include "build/baserom/object_gi_sword_2.o" + number 6 + include "build/assets/objects/object_gi_sword_2/object_gi_sword_2.o" endseg beginseg name "object_gi_sword_3" compress romalign 0x1000 - include "build/baserom/object_gi_sword_3.o" + number 6 + include "build/assets/objects/object_gi_sword_3/object_gi_sword_3.o" endseg beginseg name "object_gi_sword_4" compress romalign 0x1000 - include "build/baserom/object_gi_sword_4.o" + number 6 + include "build/assets/objects/object_gi_sword_4/object_gi_sword_4.o" endseg beginseg name "object_um" compress romalign 0x1000 - include "build/baserom/object_um.o" + number 6 + include "build/assets/objects/object_um/object_um.o" endseg beginseg name "object_rb" compress romalign 0x1000 - include "build/baserom/object_rb.o" + number 6 + include "build/assets/objects/object_rb/object_rb.o" endseg beginseg name "object_mbar_obj" compress romalign 0x1000 - include "build/baserom/object_mbar_obj.o" + number 6 + include "build/assets/objects/object_mbar_obj/object_mbar_obj.o" endseg beginseg name "object_ikana_obj" compress romalign 0x1000 - include "build/baserom/object_ikana_obj.o" + number 6 + include "build/assets/objects/object_ikana_obj/object_ikana_obj.o" endseg beginseg name "object_kz" compress romalign 0x1000 - include "build/baserom/object_kz.o" + number 6 + include "build/assets/objects/object_kz/object_kz.o" endseg beginseg name "object_tokei_turret" compress romalign 0x1000 - include "build/baserom/object_tokei_turret.o" + number 6 + include "build/assets/objects/object_tokei_turret/object_tokei_turret.o" endseg beginseg name "object_zog" compress romalign 0x1000 - include "build/baserom/object_zog.o" + number 6 + include "build/assets/objects/object_zog/object_zog.o" endseg beginseg name "object_rotlift" compress romalign 0x1000 - include "build/baserom/object_rotlift.o" + number 6 + include "build/assets/objects/object_rotlift/object_rotlift.o" endseg beginseg name "object_posthouse_obj" compress romalign 0x1000 - include "build/baserom/object_posthouse_obj.o" + number 6 + include "build/assets/objects/object_posthouse_obj/object_posthouse_obj.o" endseg beginseg name "object_gi_mask09" compress romalign 0x1000 - include "build/baserom/object_gi_mask09.o" + number 6 + include "build/assets/objects/object_gi_mask09/object_gi_mask09.o" endseg beginseg name "object_gi_mask14" compress romalign 0x1000 - include "build/baserom/object_gi_mask14.o" + number 6 + include "build/assets/objects/object_gi_mask14/object_gi_mask14.o" endseg beginseg name "object_gi_mask15" compress romalign 0x1000 - include "build/baserom/object_gi_mask15.o" + number 6 + include "build/assets/objects/object_gi_mask15/object_gi_mask15.o" endseg beginseg name "object_inibs_object" compress romalign 0x1000 - include "build/baserom/object_inibs_object.o" + number 6 + include "build/assets/objects/object_inibs_object/object_inibs_object.o" endseg beginseg name "object_tree" compress romalign 0x1000 - include "build/baserom/object_tree.o" + number 6 + include "build/assets/objects/object_tree/object_tree.o" endseg beginseg name "object_kaizoku_obj" compress romalign 0x1000 - include "build/baserom/object_kaizoku_obj.o" + number 6 + include "build/assets/objects/object_kaizoku_obj/object_kaizoku_obj.o" endseg beginseg name "object_gi_reserve_b_00" compress romalign 0x1000 - include "build/baserom/object_gi_reserve_b_00.o" + number 6 + include "build/assets/objects/object_gi_reserve_b_00/object_gi_reserve_b_00.o" endseg beginseg name "object_gi_reserve_c_00" compress romalign 0x1000 - include "build/baserom/object_gi_reserve_c_00.o" + number 6 + include "build/assets/objects/object_gi_reserve_c_00/object_gi_reserve_c_00.o" endseg beginseg name "object_zob" compress romalign 0x1000 - include "build/baserom/object_zob.o" + number 6 + include "build/assets/objects/object_zob/object_zob.o" endseg beginseg name "object_milkbar" compress romalign 0x1000 - include "build/baserom/object_milkbar.o" + number 6 + include "build/assets/objects/object_milkbar/object_milkbar.o" endseg beginseg name "object_dmask" compress romalign 0x1000 - include "build/baserom/object_dmask.o" + number 6 + include "build/assets/objects/object_dmask/object_dmask.o" endseg beginseg name "object_gi_reserve_c_01" compress romalign 0x1000 - include "build/baserom/object_gi_reserve_c_01.o" + number 6 + include "build/assets/objects/object_gi_reserve_c_01/object_gi_reserve_c_01.o" endseg beginseg name "object_zod" compress romalign 0x1000 - include "build/baserom/object_zod.o" + number 6 + include "build/assets/objects/object_zod/object_zod.o" endseg beginseg name "object_kumo30" compress romalign 0x1000 - include "build/baserom/object_kumo30.o" + number 6 + include "build/assets/objects/object_kumo30/object_kumo30.o" endseg beginseg name "object_obj_yasi" compress romalign 0x1000 - include "build/baserom/object_obj_yasi.o" + number 6 + include "build/assets/objects/object_obj_yasi/object_obj_yasi.o" endseg beginseg name "object_tanron1" compress romalign 0x1000 - include "build/baserom/object_tanron1.o" + number 6 + include "build/assets/objects/object_tanron1/object_tanron1.o" endseg beginseg name "object_tanron2" compress romalign 0x1000 - include "build/baserom/object_tanron2.o" + number 6 + include "build/assets/objects/object_tanron2/object_tanron2.o" endseg beginseg name "object_tanron3" compress romalign 0x1000 - include "build/baserom/object_tanron3.o" + number 6 + include "build/assets/objects/object_tanron3/object_tanron3.o" endseg beginseg name "object_gi_magicmushroom" compress romalign 0x1000 - include "build/baserom/object_gi_magicmushroom.o" + number 6 + include "build/assets/objects/object_gi_magicmushroom/object_gi_magicmushroom.o" endseg beginseg name "object_obj_chan" compress romalign 0x1000 - include "build/baserom/object_obj_chan.o" + number 6 + include "build/assets/objects/object_obj_chan/object_obj_chan.o" endseg beginseg name "object_gi_mask10" compress romalign 0x1000 - include "build/baserom/object_gi_mask10.o" + number 6 + include "build/assets/objects/object_gi_mask10/object_gi_mask10.o" endseg beginseg name "object_zos" compress romalign 0x1000 - include "build/baserom/object_zos.o" + number 6 + include "build/assets/objects/object_zos/object_zos.o" endseg beginseg name "object_an2" compress romalign 0x1000 - include "build/baserom/object_an2.o" + number 6 + include "build/assets/objects/object_an2/object_an2.o" endseg beginseg name "object_an3" compress romalign 0x1000 - include "build/baserom/object_an3.o" + number 6 + include "build/assets/objects/object_an3/object_an3.o" endseg beginseg name "object_f40_switch" compress romalign 0x1000 - include "build/baserom/object_f40_switch.o" + number 6 + include "build/assets/objects/object_f40_switch/object_f40_switch.o" endseg beginseg name "object_lodmoon" compress romalign 0x1000 - include "build/baserom/object_lodmoon.o" + number 6 + include "build/assets/objects/object_lodmoon/object_lodmoon.o" endseg beginseg name "object_tro" compress romalign 0x1000 - include "build/baserom/object_tro.o" + number 6 + include "build/assets/objects/object_tro/object_tro.o" endseg beginseg name "object_gi_mask12" compress romalign 0x1000 - include "build/baserom/object_gi_mask12.o" + number 6 + include "build/assets/objects/object_gi_mask12/object_gi_mask12.o" endseg beginseg name "object_gi_mask23" compress romalign 0x1000 - include "build/baserom/object_gi_mask23.o" + number 6 + include "build/assets/objects/object_gi_mask23/object_gi_mask23.o" endseg beginseg name "object_gi_bottle_21" compress romalign 0x1000 - include "build/baserom/object_gi_bottle_21.o" + number 6 + include "build/assets/objects/object_gi_bottle_21/object_gi_bottle_21.o" endseg beginseg name "object_gi_camera" compress romalign 0x1000 - include "build/baserom/object_gi_camera.o" + number 6 + include "build/assets/objects/object_gi_camera/object_gi_camera.o" endseg beginseg name "object_kamejima" compress romalign 0x1000 - include "build/baserom/object_kamejima.o" + number 6 + include "build/assets/objects/object_kamejima/object_kamejima.o" endseg beginseg name "object_nb" compress romalign 0x1000 - include "build/baserom/object_nb.o" + number 6 + include "build/assets/objects/object_nb/object_nb.o" endseg beginseg name "object_harfgibud" compress romalign 0x1000 - include "build/baserom/object_harfgibud.o" + number 6 + include "build/assets/objects/object_harfgibud/object_harfgibud.o" endseg beginseg name "object_zov" compress romalign 0x1000 - include "build/baserom/object_zov.o" + number 6 + include "build/assets/objects/object_zov/object_zov.o" endseg beginseg name "object_ah" compress romalign 0x1000 - include "build/baserom/object_ah.o" + number 6 + include "build/assets/objects/object_ah/object_ah.o" endseg beginseg name "object_hgdoor" compress romalign 0x1000 - include "build/baserom/object_hgdoor.o" + number 6 + include "build/assets/objects/object_hgdoor/object_hgdoor.o" endseg beginseg name "object_dor01" compress romalign 0x1000 - include "build/baserom/object_dor01.o" + number 6 + include "build/assets/objects/object_dor01/object_dor01.o" endseg beginseg name "object_dor02" compress romalign 0x1000 - include "build/baserom/object_dor02.o" + number 6 + include "build/assets/objects/object_dor02/object_dor02.o" endseg beginseg name "object_dor03" compress romalign 0x1000 - include "build/baserom/object_dor03.o" + number 6 + include "build/assets/objects/object_dor03/object_dor03.o" endseg beginseg name "object_dor04" compress romalign 0x1000 - include "build/baserom/object_dor04.o" + number 6 + include "build/assets/objects/object_dor04/object_dor04.o" endseg beginseg name "object_last_obj" compress romalign 0x1000 - include "build/baserom/object_last_obj.o" + number 6 + include "build/assets/objects/object_last_obj/object_last_obj.o" endseg beginseg name "object_redead_obj" compress romalign 0x1000 - include "build/baserom/object_redead_obj.o" + number 6 + include "build/assets/objects/object_redead_obj/object_redead_obj.o" endseg beginseg name "object_ikninside_obj" compress romalign 0x1000 - include "build/baserom/object_ikninside_obj.o" + number 6 + include "build/assets/objects/object_ikninside_obj/object_ikninside_obj.o" endseg beginseg name "object_iknv_obj" compress romalign 0x1000 - include "build/baserom/object_iknv_obj.o" + number 6 + include "build/assets/objects/object_iknv_obj/object_iknv_obj.o" endseg beginseg name "object_pamera" compress romalign 0x1000 - include "build/baserom/object_pamera.o" + number 6 + include "build/assets/objects/object_pamera/object_pamera.o" endseg beginseg name "object_hsstump" compress romalign 0x1000 - include "build/baserom/object_hsstump.o" + number 6 + include "build/assets/objects/object_hsstump/object_hsstump.o" endseg beginseg name "object_zm" compress romalign 0x1000 - include "build/baserom/object_zm.o" + number 6 + include "build/assets/objects/object_zm/object_zm.o" endseg beginseg name "object_al" compress romalign 0x1000 - include "build/baserom/object_al.o" + number 6 + include "build/assets/objects/object_al/object_al.o" endseg beginseg name "object_tab" compress romalign 0x1000 - include "build/baserom/object_tab.o" + number 6 + include "build/assets/objects/object_tab/object_tab.o" endseg beginseg name "object_secom_obj" compress romalign 0x1000 - include "build/baserom/object_secom_obj.o" + number 6 + include "build/assets/objects/object_secom_obj/object_secom_obj.o" endseg beginseg name "object_dt" compress romalign 0x1000 - include "build/baserom/object_dt.o" + number 6 + include "build/assets/objects/object_dt/object_dt.o" endseg beginseg name "object_gi_mask03" compress romalign 0x1000 - include "build/baserom/object_gi_mask03.o" + number 6 + include "build/assets/objects/object_gi_mask03/object_gi_mask03.o" endseg beginseg name "object_cha" compress romalign 0x1000 - include "build/baserom/object_cha.o" + number 6 + include "build/assets/objects/object_cha/object_cha.o" endseg beginseg name "object_obj_dinner" compress romalign 0x1000 - include "build/baserom/object_obj_dinner.o" + number 6 + include "build/assets/objects/object_obj_dinner/object_obj_dinner.o" endseg beginseg name "object_gi_reserve_b_01" compress romalign 0x1000 - include "build/baserom/object_gi_reserve_b_01.o" + number 6 + include "build/assets/objects/object_gi_reserve_b_01/object_gi_reserve_b_01.o" endseg beginseg name "object_lastday" compress romalign 0x1000 - include "build/baserom/object_lastday.o" + number 6 + include "build/assets/objects/object_lastday/object_lastday.o" endseg beginseg name "object_bai" compress romalign 0x1000 - include "build/baserom/object_bai.o" + number 6 + include "build/assets/objects/object_bai/object_bai.o" endseg beginseg name "object_ikn_demo" compress romalign 0x1000 - include "build/baserom/object_ikn_demo.o" + number 6 + include "build/assets/objects/object_ikn_demo/object_ikn_demo.o" endseg beginseg name "object_gi_fieldmap" compress romalign 0x1000 - include "build/baserom/object_gi_fieldmap.o" + number 6 + include "build/assets/objects/object_gi_fieldmap/object_gi_fieldmap.o" endseg beginseg name "object_big_fwall" compress romalign 0x1000 - include "build/baserom/object_big_fwall.o" + number 6 + include "build/assets/objects/object_big_fwall/object_big_fwall.o" endseg beginseg name "object_hunsui" compress romalign 0x1000 - include "build/baserom/object_hunsui.o" + number 6 + include "build/assets/objects/object_hunsui/object_hunsui.o" endseg beginseg name "object_uch" compress romalign 0x1000 - include "build/baserom/object_uch.o" + number 6 + include "build/assets/objects/object_uch/object_uch.o" endseg beginseg name "object_tanron4" compress romalign 0x1000 - include "build/baserom/object_tanron4.o" + number 6 + include "build/assets/objects/object_tanron4/object_tanron4.o" endseg beginseg name "object_tanron5" compress romalign 0x1000 - include "build/baserom/object_tanron5.o" + number 6 + include "build/assets/objects/object_tanron5/object_tanron5.o" endseg beginseg name "object_in2" compress romalign 0x1000 - include "build/baserom/object_in2.o" + number 6 + include "build/assets/objects/object_in2/object_in2.o" endseg beginseg name "object_yb" compress romalign 0x1000 - include "build/baserom/object_yb.o" + number 6 + include "build/assets/objects/object_yb/object_yb.o" endseg beginseg name "object_rz" compress romalign 0x1000 - include "build/baserom/object_rz.o" + number 6 + include "build/assets/objects/object_rz/object_rz.o" endseg beginseg name "object_bjt" compress romalign 0x1000 - include "build/baserom/object_bjt.o" + number 6 + include "build/assets/objects/object_bjt/object_bjt.o" endseg beginseg name "object_taru" compress romalign 0x1000 - include "build/baserom/object_taru.o" + number 6 + include "build/assets/objects/object_taru/object_taru.o" endseg beginseg name "object_moonston" compress romalign 0x1000 - include "build/baserom/object_moonston.o" + number 6 + include "build/assets/objects/object_moonston/object_moonston.o" endseg beginseg name "object_gi_schedule" compress romalign 0x1000 - include "build/baserom/object_gi_schedule.o" + number 6 + include "build/assets/objects/object_gi_schedule/object_gi_schedule.o" endseg beginseg name "object_gi_stonemask" compress romalign 0x1000 - include "build/baserom/object_gi_stonemask.o" + number 6 + include "build/assets/objects/object_gi_stonemask/object_gi_stonemask.o" endseg beginseg name "object_zoraband" compress romalign 0x1000 - include "build/baserom/object_zoraband.o" + number 6 + include "build/assets/objects/object_zoraband/object_zoraband.o" endseg beginseg name "object_kepn_koya" compress romalign 0x1000 - include "build/baserom/object_kepn_koya.o" + number 6 + include "build/assets/objects/object_kepn_koya/object_kepn_koya.o" endseg beginseg name "object_obj_usiyane" compress romalign 0x1000 - include "build/baserom/object_obj_usiyane.o" + number 6 + include "build/assets/objects/object_obj_usiyane/object_obj_usiyane.o" endseg beginseg name "object_gi_mask05" compress romalign 0x1000 - include "build/baserom/object_gi_mask05.o" + number 6 + include "build/assets/objects/object_gi_mask05/object_gi_mask05.o" endseg beginseg name "object_gi_mask11" compress romalign 0x1000 - include "build/baserom/object_gi_mask11.o" + number 6 + include "build/assets/objects/object_gi_mask11/object_gi_mask11.o" endseg beginseg name "object_gi_mask20" compress romalign 0x1000 - include "build/baserom/object_gi_mask20.o" + number 6 + include "build/assets/objects/object_gi_mask20/object_gi_mask20.o" endseg beginseg name "object_nnh" compress romalign 0x1000 - include "build/baserom/object_nnh.o" + number 6 + include "build/assets/objects/object_nnh/object_nnh.o" endseg beginseg name "object_kzsaku" compress romalign 0x1000 - include "build/baserom/object_kzsaku.o" + number 6 + include "build/assets/objects/object_kzsaku/object_kzsaku.o" endseg beginseg name "object_obj_milk_bin" compress romalign 0x1000 - include "build/baserom/object_obj_milk_bin.o" + number 6 + include "build/assets/objects/object_obj_milk_bin/object_obj_milk_bin.o" endseg beginseg name "object_random_obj" compress romalign 0x1000 - include "build/baserom/object_random_obj.o" + number 6 + include "build/assets/objects/object_random_obj/object_random_obj.o" endseg beginseg name "object_kujiya" compress romalign 0x1000 - include "build/baserom/object_kujiya.o" + number 6 + include "build/assets/objects/object_kujiya/object_kujiya.o" endseg beginseg name "object_kitan" compress romalign 0x1000 - include "build/baserom/object_kitan.o" + number 6 + include "build/assets/objects/object_kitan/object_kitan.o" endseg beginseg name "object_gi_mask06" compress romalign 0x1000 - include "build/baserom/object_gi_mask06.o" + number 6 + include "build/assets/objects/object_gi_mask06/object_gi_mask06.o" endseg beginseg name "object_gi_mask16" compress romalign 0x1000 - include "build/baserom/object_gi_mask16.o" + number 6 + include "build/assets/objects/object_gi_mask16/object_gi_mask16.o" endseg beginseg name "object_astr_obj" compress romalign 0x1000 - include "build/baserom/object_astr_obj.o" + number 6 + include "build/assets/objects/object_astr_obj/object_astr_obj.o" endseg beginseg name "object_bsb" compress romalign 0x1000 - include "build/baserom/object_bsb.o" + number 6 + include "build/assets/objects/object_bsb/object_bsb.o" endseg beginseg name "object_fall2" compress romalign 0x1000 - include "build/baserom/object_fall2.o" + number 6 + include "build/assets/objects/object_fall2/object_fall2.o" endseg beginseg name "object_sth" compress romalign 0x1000 - include "build/baserom/object_sth.o" + number 6 + include "build/assets/objects/object_sth/object_sth.o" endseg beginseg name "object_gi_mssa" compress romalign 0x1000 - include "build/baserom/object_gi_mssa.o" + number 6 + include "build/assets/objects/object_gi_mssa/object_gi_mssa.o" endseg beginseg name "object_smtower" compress romalign 0x1000 - include "build/baserom/object_smtower.o" + number 6 + include "build/assets/objects/object_smtower/object_smtower.o" endseg beginseg name "object_gi_mask21" compress romalign 0x1000 - include "build/baserom/object_gi_mask21.o" + number 6 + include "build/assets/objects/object_gi_mask21/object_gi_mask21.o" endseg beginseg name "object_yado_obj" compress romalign 0x1000 - include "build/baserom/object_yado_obj.o" + number 6 + include "build/assets/objects/object_yado_obj/object_yado_obj.o" endseg beginseg name "object_syoten" compress romalign 0x1000 - include "build/baserom/object_syoten.o" + number 6 + include "build/assets/objects/object_syoten/object_syoten.o" endseg beginseg name "object_moonend" compress romalign 0x1000 - include "build/baserom/object_moonend.o" + number 6 + include "build/assets/objects/object_moonend/object_moonend.o" endseg beginseg name "object_ob" compress romalign 0x1000 - include "build/baserom/object_ob.o" + number 6 + include "build/assets/objects/object_ob/object_ob.o" endseg beginseg name "object_gi_bottle_04" compress romalign 0x1000 - include "build/baserom/object_gi_bottle_04.o" + number 6 + include "build/assets/objects/object_gi_bottle_04/object_gi_bottle_04.o" endseg beginseg name "object_and" compress romalign 0x1000 - include "build/baserom/object_and.o" + number 6 + include "build/assets/objects/object_and/object_and.o" endseg beginseg name "object_obj_danpeilift" compress romalign 0x1000 - include "build/baserom/object_obj_danpeilift.o" + number 6 + include "build/assets/objects/object_obj_danpeilift/object_obj_danpeilift.o" endseg beginseg name "object_drs" compress romalign 0x1000 - include "build/baserom/object_drs.o" + number 6 + include "build/assets/objects/object_drs/object_drs.o" endseg beginseg name "object_msmo" compress romalign 0x1000 - include "build/baserom/object_msmo.o" + number 6 + include "build/assets/objects/object_msmo/object_msmo.o" endseg beginseg name "object_an4" compress romalign 0x1000 - include "build/baserom/object_an4.o" + number 6 + include "build/assets/objects/object_an4/object_an4.o" endseg beginseg name "object_wdor01" compress romalign 0x1000 - include "build/baserom/object_wdor01.o" + number 6 + include "build/assets/objects/object_wdor01/object_wdor01.o" endseg beginseg name "object_wdor02" compress romalign 0x1000 - include "build/baserom/object_wdor02.o" + number 6 + include "build/assets/objects/object_wdor02/object_wdor02.o" endseg beginseg name "object_wdor03" compress romalign 0x1000 - include "build/baserom/object_wdor03.o" + number 6 + include "build/assets/objects/object_wdor03/object_wdor03.o" endseg beginseg name "object_wdor04" compress romalign 0x1000 - include "build/baserom/object_wdor04.o" + number 6 + include "build/assets/objects/object_wdor04/object_wdor04.o" endseg beginseg name "object_wdor05" compress romalign 0x1000 - include "build/baserom/object_wdor05.o" + number 6 + include "build/assets/objects/object_wdor05/object_wdor05.o" endseg beginseg name "object_stk3" compress romalign 0x1000 - include "build/baserom/object_stk3.o" + number 6 + include "build/assets/objects/object_stk3/object_stk3.o" endseg beginseg name "object_kinsta1_obj" compress romalign 0x1000 - include "build/baserom/object_kinsta1_obj.o" + number 6 + include "build/assets/objects/object_kinsta1_obj/object_kinsta1_obj.o" endseg beginseg name "object_kinsta2_obj" compress romalign 0x1000 - include "build/baserom/object_kinsta2_obj.o" + number 6 + include "build/assets/objects/object_kinsta2_obj/object_kinsta2_obj.o" endseg beginseg name "object_bh" compress romalign 0x1000 - include "build/baserom/object_bh.o" + number 6 + include "build/assets/objects/object_bh/object_bh.o" endseg beginseg name "object_gi_mask17" compress romalign 0x1000 - include "build/baserom/object_gi_mask17.o" + number 6 + include "build/assets/objects/object_gi_mask17/object_gi_mask17.o" endseg beginseg name "object_gi_mask22" compress romalign 0x1000 - include "build/baserom/object_gi_mask22.o" + number 6 + include "build/assets/objects/object_gi_mask22/object_gi_mask22.o" endseg beginseg name "object_lbfshot" compress romalign 0x1000 - include "build/baserom/object_lbfshot.o" + number 6 + include "build/assets/objects/object_lbfshot/object_lbfshot.o" endseg beginseg name "object_fusen" compress romalign 0x1000 - include "build/baserom/object_fusen.o" + number 6 + include "build/assets/objects/object_fusen/object_fusen.o" endseg beginseg name "object_ending_obj" compress romalign 0x1000 - include "build/baserom/object_ending_obj.o" + number 6 + include "build/assets/objects/object_ending_obj/object_ending_obj.o" endseg beginseg name "object_gi_mask13" compress romalign 0x1000 - include "build/baserom/object_gi_mask13.o" + number 6 + include "build/assets/objects/object_gi_mask13/object_gi_mask13.o" endseg beginseg @@ -8847,7 +9259,7 @@ beginseg name "nintendo_rogo_static" compress romalign 0x1000 - include "build/assets/static/nintendo_rogo_static/nintendo_rogo_static.o" + include "build/assets/misc/nintendo_rogo_static/nintendo_rogo_static.o" number 1 endseg @@ -8891,7 +9303,7 @@ beginseg name "daytelop_static" compress romalign 0x1000 - include "build/assets/static/daytelop_static/daytelop_static.o" + include "build/assets/misc/daytelop_static/daytelop_static.o" number 9 endseg @@ -8899,7 +9311,7 @@ beginseg name "ger_daytelop_static" compress romalign 0x1000 - include "build/assets/static/ger_daytelop_static/ger_daytelop_static.o" + include "build/assets/misc/ger_daytelop_static/ger_daytelop_static.o" number 9 endseg @@ -8907,7 +9319,7 @@ beginseg name "fra_daytelop_static" compress romalign 0x1000 - include "build/assets/static/fra_daytelop_static/fra_daytelop_static.o" + include "build/assets/misc/fra_daytelop_static/fra_daytelop_static.o" number 9 endseg @@ -8915,7 +9327,7 @@ beginseg name "esp_daytelop_static" compress romalign 0x1000 - include "build/assets/static/esp_daytelop_static/esp_daytelop_static.o" + include "build/assets/misc/esp_daytelop_static/esp_daytelop_static.o" number 9 endseg diff --git a/src/boot_O2/boot_80086760.c b/src/boot_O2/boot_80086760.c index 1a9b37453..3c75bcd3f 100644 --- a/src/boot_O2/boot_80086760.c +++ b/src/boot_O2/boot_80086760.c @@ -24,30 +24,30 @@ f32 func_80086760(f32 x) { // Unused // Math_FFloorF f32 func_80086794(f32 x) { - func_80086C70(x); + return func_80086C70(x); } // Unused // Math_FCeilF f32 func_800867B4(f32 x) { - func_80086CA8(x); + return func_80086CA8(x); } // Unused // Math_FRoundF f32 func_800867D4(f32 x) { - func_80086D50(x); + return func_80086D50(x); } // Unused // Math_FTruncF f32 func_800867F4(f32 x) { - func_80086CE0(x); + return func_80086CE0(x); } // Math_FNearbyIntF f32 func_80086814(f32 x) { - func_80086D18(x); + return func_80086D18(x); } /** diff --git a/src/boot_O2_g3/fault.c b/src/boot_O2_g3/fault.c index 4dea209db..1f5503445 100644 --- a/src/boot_O2_g3/fault.c +++ b/src/boot_O2_g3/fault.c @@ -575,66 +575,59 @@ void Fault_DrawMemDump(u32 pc, u32 sp, u32 unk0, u32 unk1) { sFaultContext->faultActive = 1; } -#ifdef NON_MATCHING -// This function still needs a bit of work -void Fault_FindNextStackCall(u32** sp, u32** pc, u32** ra) { - u32* currentSp; - u32* currentPc; - u32* currentRa; - u32 lastInst; - u32 currInst; +void Fault_FindNextStackCall(uintptr_t* spPtr, uintptr_t* pcPtr, uintptr_t* raPtr) { + uintptr_t sp = *spPtr; + uintptr_t pc = *pcPtr; + uintptr_t ra = *raPtr; + u32 lastOpc; + u16 opcHi; + s16 opcLo; + u32 imm; - currentSp = *sp; - currentPc = *pc; - currentRa = *ra; - - if ((((u32)currentSp & 3) != 0) || (currentSp < (u32*)0x80000000) || (currentSp >= (u32*)0xC0000000) || - (((u32)currentRa & 3) != 0) || (currentRa < (u32*)0x80000000) || (currentRa >= (u32*)0xC0000000)) { - *sp = NULL; - *pc = NULL; - *ra = NULL; + if (sp & 3 || sp < 0x80000000 || sp >= 0xC0000000 || ra & 3 || ra < 0x80000000 || ra >= 0xC0000000) { + *spPtr = 0; + *pcPtr = 0; + *raPtr = 0; return; } - if ((((u32)currentPc & 3) != 0) || (currentPc < (u32*)0x80000000) || (currentPc >= (u32*)0xC0000000)) { - *pc = currentRa; + if (pc & 3 || pc < 0x80000000 || pc >= 0xC0000000) { + *pcPtr = ra; return; } - lastInst = 0; - while (1) { - currInst = *currentPc; - if (((currInst >> 0x10) & 0xFFFF) == 0x8FBF) { - currentRa = *(u32**)((u32)currentSp + (s16)currInst); - } else if (((currInst >> 0x10) & 0xFFFF) == 0x27BD) { - currentSp = (u32*)((u32)currentSp + (s16)currInst); - } else if (currInst == 0x42000018) { - currentSp = NULL; - currentPc = NULL; - currentRa = NULL; - break; - } + lastOpc = 0; + while (true) { + opcHi = *(uintptr_t*)pc >> 16; + opcLo = *(uintptr_t*)pc & 0xFFFF; + imm = opcLo; - if (lastInst == 0x03E00008) { - break; + if (opcHi == 0x8FBF) { + ra = *(uintptr_t*)(sp + imm); + } else if (opcHi == 0x27BD) { + sp += imm; + } else if (*(uintptr_t*)pc == 0x42000018) { + sp = 0; + pc = 0; + ra = 0; + goto end; } - - if ((lastInst >> 0x1A) == 2) { - currentPc = (u32*)((((u32)currentPc >> 0x1C) << 0x1C) | ((lastInst << 6) >> 4)); - break; + if (lastOpc == 0x3E00008) { + pc = ra; + goto end; + } else if ((lastOpc >> 26) == 2) { + pc = pc >> 28 << 28 | lastOpc << 6 >> 4; + goto end; } - - lastInst = currInst; - currentPc++; + lastOpc = *(uintptr_t*)pc; + pc += 4; } - *sp = currentSp; - *pc = currentPc; - *ra = currentRa; +end: + *spPtr = sp; + *pcPtr = pc; + *raPtr = ra; } -#else -#pragma GLOBAL_ASM("asm/non_matchings/boot/fault/Fault_FindNextStackCall.s") -#endif void Fault_DrawStackTrace(OSThread* t, u32 flags) { s32 y; @@ -664,7 +657,7 @@ void Fault_DrawStackTrace(OSThread* t, u32 flags) { FaultDrawer_Printf(" -> ????????"); } - Fault_FindNextStackCall((u32**)&sp, (u32**)&pc, (u32**)&ra); + Fault_FindNextStackCall(&sp, &pc, &ra); } } @@ -695,7 +688,7 @@ void osSyncPrintfStackTrace(OSThread* t, u32 flags) { } osSyncPrintf("\n"); - Fault_FindNextStackCall((u32**)&sp, (u32**)&pc, (u32**)&ra); + Fault_FindNextStackCall(&sp, &pc, &ra); } } @@ -751,32 +744,33 @@ void Fault_ProcessClients(void) { } #ifdef NON_MATCHING -// regalloc and ordering differences around the two bool variables (faultCustomOptions and faultCopyToLog) +// needs in-function static bss void Fault_SetOptionsFromController3(void) { - Input* input3; + static u32 faultCustomOptions; + Input* input3 = &sFaultContext->padInput[3]; u32 pad; u32 graphPC; u32 graphRA; u32 graphSP; - input3 = &sFaultContext->padInput[3]; - if (CHECK_BTN_ALL(input3->press.button, 0x80)) { - faultCustomOptions = faultCustomOptions == 0; + faultCustomOptions = !faultCustomOptions; } if (faultCustomOptions) { graphPC = sGraphThread.context.pc; graphRA = sGraphThread.context.ra; graphSP = sGraphThread.context.sp; - if (CHECK_BTN_ALL(input3->press.button, BTN_R)) { + if (CHECK_BTN_ALL(input3->cur.button, BTN_R)) { + static u32 faultCopyToLog; + faultCopyToLog = !faultCopyToLog; FaultDrawer_SetOsSyncPrintfEnabled(faultCopyToLog); } - if (CHECK_BTN_ALL(input3->press.button, BTN_A)) { + if (CHECK_BTN_ALL(input3->cur.button, BTN_A)) { osSyncPrintf("GRAPH PC=%08x RA=%08x STACK=%08x\n", graphPC, graphRA, graphSP); } - if (CHECK_BTN_ALL(input3->press.button, BTN_B)) { + if (CHECK_BTN_ALL(input3->cur.button, BTN_B)) { FaultDrawer_SetDrawerFB(osViGetNextFramebuffer(), 0x140, 0xF0); Fault_DrawRec(0, 0xD7, 0x140, 9, 1); FaultDrawer_SetCharPad(-2, 0); @@ -893,7 +887,7 @@ void Fault_Start(void) { sFaultContext->clients = NULL; sFaultContext->faultActive = 0; gFaultStruct.faultHandlerEnabled = 1; - osCreateMesgQueue(&sFaultContext->queue, sFaultContext->msg, 1); + osCreateMesgQueue(&sFaultContext->queue, sFaultContext->msg, ARRAY_COUNT(sFaultContext->msg)); StackCheck_Init(&sFaultThreadInfo, sFaultStack, sFaultStack + sizeof(sFaultStack), 0, 0x100, "fault"); osCreateThread(&sFaultContext->thread, 2, Fault_ThreadEntry, NULL, sFaultStack + sizeof(sFaultStack), 0x7F); osStartThread(&sFaultContext->thread); diff --git a/src/boot_O2_g3/fault_drawer.c b/src/boot_O2_g3/fault_drawer.c index 41f6c1762..eacfc56d1 100644 --- a/src/boot_O2_g3/fault_drawer.c +++ b/src/boot_O2_g3/fault_drawer.c @@ -3,9 +3,11 @@ extern const u32 sFaultDrawerFont[]; +FaultDrawer sFaultDrawerStruct; + FaultDrawer* sFaultDrawContext = &sFaultDrawerStruct; FaultDrawer sFaultDrawerDefault = { - (u16*)FAULT_FB_ADDRESS, // fb + FAULT_FB_ADDRESS, // fb SCREEN_WIDTH, // w SCREEN_HEIGHT, // h 16, // yStart @@ -16,23 +18,23 @@ FaultDrawer sFaultDrawerDefault = { GPACK_RGBA5551(0, 0, 0, 0), // backColor 22, // cursorX 16, // cursorY - (u32*)sFaultDrawerFont, // font + sFaultDrawerFont, // font 8, // charW 8, // charH 0, // charWPad - 0, // charHPad + 0, // charHPad { // printColors - GPACK_RGBA5551(0, 0, 0, 1), - GPACK_RGBA5551(255, 0, 0, 1), - GPACK_RGBA5551(0, 255, 0, 1), - GPACK_RGBA5551(255, 255, 0, 1), - GPACK_RGBA5551(0, 0, 255, 1), - GPACK_RGBA5551(255, 0, 255, 1), - GPACK_RGBA5551(0, 255, 255, 1), - GPACK_RGBA5551(255, 255, 255, 1), - GPACK_RGBA5551(120, 120, 120, 1), - GPACK_RGBA5551(176, 176, 176, 1), + GPACK_RGBA5551(0, 0, 0, 1), // BLACK + GPACK_RGBA5551(255, 0, 0, 1), // RED + GPACK_RGBA5551(0, 255, 0, 1), // GREEN + GPACK_RGBA5551(255, 255, 0, 1), // YELLOW + GPACK_RGBA5551(0, 0, 255, 1), // BLUE + GPACK_RGBA5551(255, 0, 255, 1), // MAGENTA + GPACK_RGBA5551(0, 255, 255, 1), // CYAN + GPACK_RGBA5551(255, 255, 255, 1), // WHITE + GPACK_RGBA5551(120, 120, 120, 1), // DARK GRAY + GPACK_RGBA5551(176, 176, 176, 1), // LIGHT GRAY }, 0, // escCode 0, // osSyncPrintfEnabled @@ -47,7 +49,8 @@ void FaultDrawer_SetOsSyncPrintfEnabled(u32 enabled) { void FaultDrawer_DrawRecImpl(s32 xStart, s32 yStart, s32 xEnd, s32 yEnd, u16 color) { u16* fb; - s32 x, y; + s32 x; + s32 y; s32 xDiff = sFaultDrawContext->w - xStart; s32 yDiff = sFaultDrawContext->h - yStart; s32 xSize = xEnd - xStart + 1; @@ -74,7 +77,37 @@ void FaultDrawer_DrawRecImpl(s32 xStart, s32 yStart, s32 xEnd, s32 yEnd, u16 col } } -#pragma GLOBAL_ASM("asm/non_matchings/boot/fault_drawer/FaultDrawer_DrawChar.s") +void FaultDrawer_DrawChar(char c) { + s32 x; + s32 y; + u32 data; + s32 cursorX = sFaultDrawContext->cursorX; + s32 cursorY = sFaultDrawContext->cursorY; + s32 shift = c % 4; + const u32* dataPtr = &sFaultDrawContext->font[(((c / 8) * 16) + ((c & 4) >> 2))]; + u16* fb = sFaultDrawContext->fb + (sFaultDrawContext->w * cursorY) + cursorX; + + if ((sFaultDrawContext->xStart <= cursorX) && + ((sFaultDrawContext->charW + cursorX - 1) <= sFaultDrawContext->xEnd) && + (sFaultDrawContext->yStart <= cursorY) && + ((sFaultDrawContext->charH + cursorY - 1) <= sFaultDrawContext->yEnd)) { + for (y = 0; y < sFaultDrawContext->charH; y++) { + u32 mask = 0x10000000 << shift; + + data = *dataPtr; + for (x = 0; x < sFaultDrawContext->charW; x++) { + if (mask & data) { + fb[x] = sFaultDrawContext->foreColor; + } else if (sFaultDrawContext->backColor & 1) { + fb[x] = sFaultDrawContext->backColor; + } + mask >>= 4; + } + fb += sFaultDrawContext->w; + dataPtr += 2; + } + } +} s32 FaultDrawer_ColorToPrintColor(u16 color) { s32 i; @@ -142,12 +175,57 @@ void FaultDrawer_FillScreen() { FaultDrawer_SetCursor(sFaultDrawContext->xStart, sFaultDrawContext->yStart); } -#pragma GLOBAL_ASM("asm/non_matchings/boot/fault_drawer/FaultDrawer_FormatStringFunc.s") +void* FaultDrawer_FormatStringFunc(void* arg, const char* str, size_t count) { + for (; count != 0; count--, str++) { + if (sFaultDrawContext->escCode) { + sFaultDrawContext->escCode = false; + if (*str >= '1' && *str <= '9') { + FaultDrawer_SetForeColor(sFaultDrawContext->printColors[*str - '0']); + } + } else { + switch (*str) { + case '\n': + if (sFaultDrawContext->osSyncPrintfEnabled) { + osSyncPrintf("\n"); + } + + sFaultDrawContext->cursorX = sFaultDrawContext->w; + break; + case '\x1A': + sFaultDrawContext->escCode = true; + break; + default: + if (sFaultDrawContext->osSyncPrintfEnabled) { + osSyncPrintf("%c", *str); + } + + FaultDrawer_DrawChar(*str); + sFaultDrawContext->cursorX += sFaultDrawContext->charW + sFaultDrawContext->charWPad; + } + } + + if (sFaultDrawContext->cursorX >= (sFaultDrawContext->xEnd - sFaultDrawContext->charW)) { + sFaultDrawContext->cursorX = sFaultDrawContext->xStart; + sFaultDrawContext->cursorY += sFaultDrawContext->charH + sFaultDrawContext->charHPad; + if (sFaultDrawContext->yEnd - sFaultDrawContext->charH <= sFaultDrawContext->cursorY) { + if (sFaultDrawContext->inputCallback != NULL) { + sFaultDrawContext->inputCallback(); + FaultDrawer_FillScreen(); + } + sFaultDrawContext->cursorY = sFaultDrawContext->yStart; + } + } + } + + osWritebackDCacheAll(); + + return arg; +} const char D_80099080[] = "(null)"; -void FaultDrawer_VPrintf(const char* str, char* args) { // va_list - _Printf((PrintCallback)FaultDrawer_FormatStringFunc, sFaultDrawContext, str, args); +void FaultDrawer_VPrintf(const char* fmt, va_list ap) { + _Printf(FaultDrawer_FormatStringFunc, sFaultDrawContext, fmt, ap); } void FaultDrawer_Printf(const char* fmt, ...) { @@ -175,7 +253,7 @@ void FaultDrawer_SetDrawerFB(void* fb, u16 w, u16 h) { sFaultDrawContext->h = h; } -void FaultDrawer_SetInputCallback(void* callback) { +void FaultDrawer_SetInputCallback(FaultDrawerCallback callback) { sFaultDrawContext->inputCallback = callback; } diff --git a/src/boot_O2_g3/idle.c b/src/boot_O2_g3/idle.c index da93f13fd..2a52e7dce 100644 --- a/src/boot_O2_g3/idle.c +++ b/src/boot_O2_g3/idle.c @@ -1,5 +1,6 @@ #include "prevent_bss_reordering.h" #include "global.h" +#include "prevent_bss_reordering.h" u8 D_80096B20 = 1; vu8 gViConfigUseDefault = 1; diff --git a/src/boot_O2_g3/irqmgr.c b/src/boot_O2_g3/irqmgr.c index 696d114c4..f605dc327 100644 --- a/src/boot_O2_g3/irqmgr.c +++ b/src/boot_O2_g3/irqmgr.c @@ -159,7 +159,7 @@ void IrqMgr_Init(IrqMgr* irqmgr, void* stack, OSPri pri, u8 retraceCount) { irqmgr->prenmiStage = 0; irqmgr->lastPrenmiTime = 0; - osCreateMesgQueue(&irqmgr->irqQueue, (OSMesg*)irqmgr->irqBuffer, 8); + osCreateMesgQueue(&irqmgr->irqQueue, (OSMesg*)irqmgr->irqBuffer, ARRAY_COUNT(irqmgr->irqBuffer)); osSetEventMesg(0xE, &irqmgr->irqQueue, (OSMesg)0x29D); osViSetEvent(&irqmgr->irqQueue, (OSMesg)0x29A, retraceCount); diff --git a/src/buffers/gfxpools.c b/src/buffers/gfxpools.c new file mode 100644 index 000000000..a91c87bed --- /dev/null +++ b/src/buffers/gfxpools.c @@ -0,0 +1,3 @@ +#include "global.h" + +GfxPool gGfxPools[2]; diff --git a/src/buffers/gfxstack.c b/src/buffers/gfxstack.c new file mode 100644 index 000000000..2b158d141 --- /dev/null +++ b/src/buffers/gfxstack.c @@ -0,0 +1,3 @@ +#include "global.h" + +u8 gGfxSPTaskStack[0x400]; diff --git a/src/buffers/gfxbuffers.c b/src/buffers/gfxyield.c similarity index 56% rename from src/buffers/gfxbuffers.c rename to src/buffers/gfxyield.c index ed0d12b6c..73810d4ac 100644 --- a/src/buffers/gfxbuffers.c +++ b/src/buffers/gfxyield.c @@ -1,7 +1,3 @@ #include "global.h" u8 gGfxSPTaskYieldBuffer[OS_YIELD_DATA_SIZE]; - -u8 gGfxSPTaskStack[0x400]; - -GfxPool gGfxPools[2]; diff --git a/src/code/audio/audio_dcache.c b/src/code/audio/audio_dcache.c new file mode 100644 index 000000000..27f019fef --- /dev/null +++ b/src/code/audio/audio_dcache.c @@ -0,0 +1,15 @@ +#include "global.h" + +void Audio_InvalDCache(void* buf, size_t size) { + OSIntMask prevMask = osSetIntMask(1); + + osInvalDCache(buf, size); + osSetIntMask(prevMask); +} + +void Audio_WritebackDCache(void* buf, size_t size) { + OSIntMask prevMask = osSetIntMask(1); + + osWritebackDCache(buf, size); + osSetIntMask(prevMask); +} diff --git a/src/code/audio/audio_init_params.c b/src/code/audio/audio_init_params.c new file mode 100644 index 000000000..4e6ef9dfb --- /dev/null +++ b/src/code/audio/audio_init_params.c @@ -0,0 +1,12 @@ +#include "global.h" + +const s16 gAudioTatumInit[] = { + 0x1C00, // unused + 0x30, // gTatumsPerBeat +}; + +const AudioContextInitSizes gAudioContextInitSizes = { + 0x137F00, // heapSize + 0x1C480, // initPoolSize + 0x1A000, // permanentPoolSize +}; diff --git a/src/code/audio/audio_sfx_params.c b/src/code/audio/audio_sfx_params.c new file mode 100644 index 000000000..dd23da443 --- /dev/null +++ b/src/code/audio/audio_sfx_params.c @@ -0,0 +1,497 @@ +#include "global.h" + +/** + * TODO: + * the number of #efined sfx's we have for each bank does not seem to line up with the + * number of SfxParam entries for each bank. So at some point either through hacking or + * decompilation/documentation of sequence 0, the sfxs should be verified, especially + * the ones that come at the end of the list (all the earlier sfxs in each bank seem fine). + * + * After that, defines should be paired with sfxparams to make it easier to look up + * specific sfxsparams for a a certain sfx i.e.: + * { 0x18, 0, 0x1 }, // NA_SE_EN_DODO_J_WALK + * { 0x30, 0, 0x1 }, // NA_SE_EN_DODO_J_CRY + * { 0x30, 0, 0x1 }, // NA_SE_EN_DODO_J_FIRE + */ + +SfxParams sEnemyBankParams[] = { + { 0x18, 0, 0x1 }, { 0x30, 0, 0x1 }, { 0x30, 0, 0x1 }, { 0x38, 0, 0x1 }, { 0x40, 0, 0x1 }, + { 0x30, 0, 0x3 }, { 0x36, 0, 0 }, { 0x38, 0, 0 }, { 0x40, 0, 0x3 }, { 0x58, 0, 0x3 }, + { 0x40, 0, 0x3 }, { 0x68, 0, 0x1003 }, { 0x40, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x40, 0, 0x3 }, + { 0x40, 0, 0x3 }, { 0x54, 0, 0xB }, { 0x54, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x40, 0, 0x3 }, + { 0x40, 0, 0x3 }, { 0x54, 0, 0x3 }, { 0x54, 0, 0x3 }, { 0x54, 0, 0x3 }, { 0x30, 0, 0x2003 }, + { 0x50, 0, 0x3 }, { 0x58, 0, 0x3 }, { 0x38, 0, 0x3 }, { 0x50, 0, 0x3 }, { 0x30, 0, 0x3 }, + { 0x38, 0, 0 }, { 0x48, 0, 0 }, { 0x30, 0, 0 }, { 0x40, 0, 0x1 }, { 0x18, 0, 0 }, + { 0x14, 0, 0 }, { 0x14, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x28, 0, 0x4000 }, + { 0x28, 0, 0 }, { 0x30, 0, 0x2 }, { 0x32, 0, 0x2 }, { 0x38, 0, 0x1 }, { 0x20, 0, 0 }, + { 0x40, 0, 0x1 }, { 0x18, 0, 0 }, { 0x28, 0, 0 }, { 0x18, 0, 0x40 }, { 0x30, 0, 0 }, + { 0x38, 0, 0x1 }, { 0x40, 0, 0x1 }, { 0x14, 0, 0 }, { 0x18, 0, 0x80 }, { 0x38, 0, 0x2 }, + { 0x34, 0, 0 }, { 0x28, 0, 0x1 }, { 0x30, 0, 0 }, { 0x38, 0, 0x1 }, { 0x40, 0, 0x1 }, + { 0x30, 0, 0 }, { 0x18, 0, 0 }, { 0x20, 0, 0 }, { 0x30, 0, 0 }, { 0x32, 0, 0 }, + { 0x20, 0, 0x1 }, { 0x37, 0, 0x1 }, { 0x38, 0, 0x1 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x40, 0, 0x2 }, { 0x38, 0, 0x2 }, { 0x20, 0, 0 }, { 0x18, 0, 0 }, { 0x40, 0, 0x4007 }, + { 0x40, 0, 0x1 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, + { 0x30, 0, 0 }, { 0x40, 0, 0 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x34, 0, 0 }, + { 0x34, 0, 0 }, { 0x36, 0, 0 }, { 0x30, 0, 0x3 }, { 0x28, 0, 0 }, { 0x30, 0, 0 }, + { 0x18, 0, 0 }, { 0x30, 0, 0 }, { 0x28, 0, 0xC0 }, { 0x30, 0, 0x40 }, { 0x38, 0, 0x41 }, + { 0x40, 0, 0x41 }, { 0x30, 0, 0 }, { 0x36, 0, 0 }, { 0x40, 0, 0x1 }, { 0x14, 0, 0 }, + { 0x30, 0, 0 }, { 0x20, 0, 0 }, { 0x40, 0, 0x1 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x4 }, + { 0x30, 0, 0x4 }, { 0x20, 0, 0x4 }, { 0x38, 0, 0x4 }, { 0x20, 0, 0x3 }, { 0x38, 0, 0x1 }, + { 0x40, 0, 0x1 }, { 0x14, 0, 0 }, { 0x30, 0, 0x3 }, { 0x20, 0, 0x1 }, { 0x20, 0, 0x1 }, + { 0x30, 0, 0x2 }, { 0x35, 0, 0x2 }, { 0x38, 0, 0x2 }, { 0x48, 0, 0x2 }, { 0x40, 0, 0x2 }, + { 0x45, 0, 0x81 }, { 0x34, 0, 0 }, { 0x40, 0, 0 }, { 0x20, 0, 0x2 }, { 0x28, 0, 0 }, + { 0x28, 0, 0 }, { 0x30, 0, 0 }, { 0x20, 0, 0x84 }, { 0x38, 0, 0x1 }, { 0x40, 0, 0x1 }, + { 0x20, 0, 0 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x4 }, { 0x40, 0, 0x4 }, { 0x40, 0, 0x3 }, + { 0x40, 0, 0x1 }, { 0x28, 0, 0x1 }, { 0x30, 0, 0x3 }, { 0x20, 0, 0 }, { 0x38, 0, 0x1 }, + { 0x30, 0, 0x4 }, { 0x30, 0, 0 }, { 0x20, 0, 0 }, { 0x20, 0, 0 }, { 0x38, 0, 0x2000 }, + { 0x30, 0, 0x3 }, { 0x30, 0, 0x2000 }, { 0x30, 0, 0 }, { 0x14, 0, 0 }, { 0x38, 0, 0x1 }, + { 0x40, 0, 0x1 }, { 0x14, 0, 0 }, { 0x20, 0, 0 }, { 0x20, 0, 0 }, { 0x30, 0, 0 }, + { 0x40, 0, 0x1 }, { 0x30, 0, 0x80 }, { 0x30, 0, 0 }, { 0x37, 0, 0x1 }, { 0x40, 0, 0x1 }, + { 0x28, 0, 0x5 }, { 0x36, 0, 0x5 }, { 0x38, 0, 0x5 }, { 0x48, 0, 0x5 }, { 0x30, 0, 0x3 }, + { 0x28, 0, 0x2 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x34, 0, 0x3 }, { 0x38, 0, 0x3 }, + { 0x40, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x2000 }, { 0x30, 0, 0x3 }, { 0x38, 0, 0x3 }, + { 0x40, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x403 }, { 0x38, 0, 0x1 }, + { 0x30, 0, 0x43 }, { 0x30, 0, 0x3 }, { 0x20, 0, 0 }, { 0x34, 0, 0 }, { 0x18, 0, 0x80 }, + { 0x30, 0, 0 }, { 0x38, 0, 0 }, { 0x30, 0, 0 }, { 0x14, 0, 0 }, { 0x34, 0, 0 }, + { 0x40, 0, 0 }, { 0x30, 0, 0x3 }, { 0x20, 0, 0 }, { 0x30, 0, 0x80 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x28, 0, 0 }, { 0x30, 0, 0x80 }, { 0x40, 0, 0x1 }, { 0x40, 0, 0x1 }, + { 0x20, 0, 0 }, { 0x20, 0, 0 }, { 0x14, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x40, 0, 0x1 }, { 0x30, 0, 0 }, { 0x30, 0, 0x3 }, { 0x38, 0, 0x3 }, + { 0x40, 0, 0x3 }, { 0x48, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x34, 0, 0x3 }, { 0x48, 0, 0x3 }, + { 0x30, 0, 0x3 }, { 0x34, 0, 0x3 }, { 0x30, 0, 0x4083 }, { 0x30, 0, 0x4083 }, { 0x40, 0, 0x3 }, + { 0x38, 0, 0x1 }, { 0x30, 0, 0x1 }, { 0x28, 0, 0x3 }, { 0x28, 0, 0x3 }, { 0x30, 0, 0x3 }, + { 0x30, 0, 0x3 }, { 0x30, 0, 0x2003 }, { 0x38, 0, 0x1 }, { 0x20, 0, 0 }, { 0x34, 0, 0 }, + { 0x38, 0, 0x1 }, { 0x40, 0, 0x1 }, { 0x34, 0, 0x2000 }, { 0x20, 0, 0 }, { 0x38, 0, 0x42 }, + { 0x40, 0, 0x1 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x2 }, { 0x30, 0, 0x2 }, { 0x38, 0, 0x3 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x34, 0, 0 }, { 0x34, 0, 0x3 }, { 0x30, 0, 0x3 }, + { 0x24, 0, 0x40 }, { 0x30, 0, 0x3 }, { 0x28, 0, 0x82 }, { 0x40, 0, 0x3 }, { 0x40, 0, 0x3 }, + { 0x30, 0, 0x3 }, { 0x34, 0, 0x3 }, { 0x20, 0, 0x83 }, { 0x20, 0, 0 }, { 0x30, 0, 0x3 }, + { 0x20, 0, 0x80 }, { 0x30, 0, 0x83 }, { 0x18, 0, 0x83 }, { 0x34, 0, 0x83 }, { 0x30, 0, 0x83 }, + { 0x38, 0, 0x3 }, { 0x18, 0, 0x3 }, { 0x30, 0, 0x2000 }, { 0x38, 0, 0x3 }, { 0x30, 0, 0x3 }, + { 0x40, 0, 0x3 }, { 0x40, 0, 0x2004 }, { 0x38, 0, 0x5 }, { 0x30, 0, 0x2000 }, { 0x30, 0, 0x3 }, + { 0x30, 0, 0x80 }, { 0x30, 0, 0x5 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x82 }, { 0x30, 0, 0x3 }, + { 0x30, 0, 0x5 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x84 }, { 0x38, 0, 0x80 }, { 0x38, 0, 0x6083 }, + { 0x38, 0, 0x6083 }, { 0x38, 0, 0x6083 }, { 0x38, 0, 0x6083 }, { 0x40, 0, 0x4082 }, { 0x18, 0, 0x83 }, + { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x20, 0, 0x3 }, { 0x24, 0, 0x5 }, { 0x28, 0, 0x3 }, + { 0x30, 0, 0x3 }, { 0x30, 0, 0x5 }, { 0x30, 0, 0x5 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0x3 }, { 0x18, 0, 0x1 }, { 0x34, 0, 0x3 }, { 0x30, 0, 0x5 }, { 0x34, 0, 0x3 }, + { 0x34, 0, 0x3 }, { 0x34, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x1 }, + { 0x14, 0, 0 }, { 0x40, 0, 0x1 }, { 0x30, 0, 0x1 }, { 0x30, 0, 0x1 }, { 0x20, 0, 0x1 }, + { 0x38, 0, 0x3 }, { 0x30, 0, 0 }, { 0x40, 0, 0x4003 }, { 0x30, 0, 0x4003 }, { 0x38, 0, 0x3 }, + { 0x38, 0, 0x3 }, { 0x40, 0, 0x3 }, { 0x40, 0, 0x83 }, { 0x40, 0, 0x83 }, { 0x40, 0, 0x3 }, + { 0x21, 0, 0x4003 }, { 0x54, 0, 0x3 }, { 0x54, 0, 0x3 }, { 0x54, 0, 0x3 }, { 0x34, 0, 0x2 }, + { 0x58, 0, 0x3 }, { 0x68, 0, 0x3 }, { 0x50, 0, 0x40C3 }, { 0x14, 0, 0 }, { 0x20, 0, 0x1 }, + { 0x48, 0, 0x4080 }, { 0x30, 0, 0x4080 }, { 0x50, 0, 0x1 }, { 0x50, 0, 0x1 }, { 0x50, 0, 0 }, + { 0x50, 0, 0 }, { 0x68, 0, 0x3 }, { 0x58, 0, 0x3 }, { 0x90, 0, 0x3 }, { 0x48, 0, 0x3 }, + { 0x28, 0, 0x2 }, { 0x30, 0, 0 }, { 0x38, 0, 0x1 }, { 0x28, 0, 0x2 }, { 0x50, 0, 0x3 }, + { 0x50, 0, 0x3 }, { 0x50, 0, 0x3 }, { 0x40, 0, 0x4083 }, { 0x40, 0, 0x3 }, { 0x40, 0, 0x3 }, + { 0x40, 0, 0x3 }, { 0x40, 0, 0x3 }, { 0x54, 0, 0x3 }, { 0x40, 0, 0x3 }, { 0x40, 0, 0x3 }, + { 0x48, 0, 0x3 }, { 0x48, 0, 0x3 }, { 0x48, 0, 0x3 }, { 0x40, 0, 0x3 }, { 0x34, 0, 0x2 }, + { 0x34, 0, 0x2002 }, { 0x28, 0, 0x2 }, { 0x28, 0, 0x2 }, { 0x30, 0, 0x2 }, { 0x30, 0, 0x2 }, + { 0x38, 0, 0x2 }, { 0x38, 0, 0x2 }, { 0x48, 0, 0x2 }, { 0x10, 0, 0 }, { 0x34, 0, 0 }, + { 0x18, 0, 0 }, { 0x30, 0, 0 }, { 0x14, 0, 0 }, { 0x34, 0, 0 }, { 0x28, 0, 0x1 }, + { 0x38, 0, 0x1 }, { 0x40, 0, 0x1 }, { 0x30, 0, 0x1 }, { 0x38, 0, 0x1 }, { 0x36, 0, 0x1 }, + { 0x34, 0, 0x1 }, { 0x38, 0, 0x1 }, { 0x48, 0, 0x1 }, { 0x30, 0, 0x1 }, { 0x38, 0, 0x83 }, + { 0x30, 0, 0x3 }, { 0x20, 0, 0x2000 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0 }, { 0x40, 0, 0x1 }, + { 0x30, 0, 0 }, { 0x20, 0, 0 }, { 0x38, 0, 0x1 }, { 0x40, 0, 0x1 }, { 0x30, 0, 0 }, + { 0x30, 0, 0x2000 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x2 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, + { 0x18, 0, 0 }, { 0x28, 0, 0 }, { 0x34, 0, 0x2 }, { 0x34, 0, 0x2 }, { 0x34, 0, 0 }, + { 0x38, 0, 0x1 }, { 0x40, 0, 0x1 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x2 }, { 0x38, 0, 0 }, + { 0x48, 0, 0 }, { 0x28, 0, 0x4004 }, { 0x48, 0, 0x4 }, { 0x20, 0, 0x4 }, { 0x25, 0, 0x3 }, + { 0x40, 0, 0x2 }, { 0x18, 0, 0x80 }, { 0x44, 0, 0x3 }, { 0x44, 0, 0 }, { 0x18, 0, 0 }, + { 0x30, 0, 0 }, { 0x38, 0, 0x1 }, { 0x40, 0, 0x1 }, { 0x18, 0, 0x3 }, { 0x30, 0, 0x3 }, + { 0x38, 0, 0x43 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x36, 0, 0x3 }, + { 0x34, 0, 0x3 }, { 0x34, 0, 0x82 }, { 0x58, 0, 0x3 }, { 0x68, 0, 0x3 }, { 0x30, 0, 0x3 }, + { 0x30, 0, 0x3 }, { 0x34, 0, 0x2 }, { 0x34, 0, 0x3 }, { 0x40, 0, 0 }, { 0x30, 0, 0x3 }, + { 0x40, 0, 0x2000 }, { 0x30, 0, 0x2000 }, { 0x30, 0, 0xC0 }, { 0x30, 0, 0xC0 }, { 0x40, 0, 0 }, + { 0x30, 0, 0x3 }, { 0x28, 0, 0x3 }, { 0x40, 0, 0x3 }, { 0x40, 0, 0x3 }, { 0x30, 0, 0x3 }, + { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x38, 0, 0x3 }, { 0x48, 0, 0x3 }, + { 0x20, 0, 0x3 }, { 0x48, 0, 0x3 }, { 0x36, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, + { 0x38, 0, 0x3 }, { 0x38, 0, 0x3 }, { 0x20, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x44, 0, 0x3 }, + { 0x30, 0, 0x83 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x34, 0, 0x3 }, { 0x30, 0, 0x3 }, + { 0x30, 0, 0x3 }, { 0x20, 0, 0x2 }, { 0x34, 0, 0x3 }, { 0x20, 0, 0x83 }, { 0x30, 0, 0x4 }, + { 0x30, 0, 0x4042 }, { 0x40, 0, 0x4042 }, { 0x40, 0, 0x83 }, { 0x30, 0, 0x4042 }, { 0x30, 0, 0x4042 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x1 }, { 0x32, 0, 0x4082 }, { 0x32, 0, 0x3 }, + { 0x54, 0, 0x1 }, { 0x52, 0, 0 }, { 0x54, 0, 0x3 }, { 0x30, 0, 0 }, { 0x08, 0, 0x1 }, + { 0x30, 0, 0x1 }, { 0x30, 0, 0x3 }, { 0x54, 0, 0x3 }, { 0x54, 0, 0x2000 }, { 0x34, 0, 0x3 }, + { 0x54, 0, 0x2000 }, { 0x08, 0, 0 }, { 0x54, 0, 0 }, { 0x34, 0, 0 }, { 0x15, 0, 0 }, + { 0x35, 0, 0 }, { 0x48, 0, 0 }, { 0x38, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0xC2 }, + { 0x38, 0, 0x2 }, { 0x38, 0, 0x2 }, { 0x30, 0, 0x80 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0x1, 0x80 }, { 0x30, 0xB4, 0x6 }, { 0x30, 0, 0 }, + { 0x30, 0, 0x6 }, { 0x30, 0, 0x83 }, { 0x30, 0, 0 }, { 0x30, 0, 0x2 }, { 0x30, 0, 0x2 }, + { 0x30, 0, 0x2 }, { 0x48, 0, 0x2 }, { 0x28, 0, 0x1 }, { 0x36, 0, 0 }, { 0x38, 0, 0 }, + { 0x48, 0, 0 }, { 0x68, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x38, 0, 0x3 }, + { 0x48, 0, 0x3 }, { 0x58, 0, 0x3 }, { 0x68, 0, 0x3 }, { 0x29, 0, 0x3 }, { 0x54, 0, 0x3 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x40 }, { 0x30, 0, 0x40 }, { 0x30, 0, 0x40 }, + { 0x30, 0, 0 }, { 0x68, 0, 0x3 }, { 0x30, 0, 0 }, { 0x45, 0, 0x2 }, { 0x40, 0, 0x4043 }, + { 0x40, 0, 0x4043 }, { 0x30, 0, 0x4043 }, { 0x30, 0, 0x4043 }, { 0x30, 0, 0x4043 }, { 0x30, 0, 0x4043 }, + { 0x30, 0, 0x4083 }, { 0x30, 0, 0x4083 }, { 0x30, 0, 0x4083 }, { 0x50, 0, 0x3 }, { 0x30, 0, 0x3 }, + { 0x30, 0, 0x3 }, { 0x10, 0, 0 }, { 0x54, 0, 0x3 }, { 0x50, 0, 0x3 }, { 0x50, 0, 0x3 }, + { 0x54, 0, 0x43 }, { 0x50, 0, 0x43 }, { 0x50, 0, 0x43 }, { 0x50, 0, 0x43 }, { 0x36, 0, 0x43 }, + { 0x34, 0, 0x43 }, { 0x34, 0, 0x83 }, { 0x36, 0, 0x43 }, { 0x35, 0, 0x43 }, { 0x34, 0, 0x83 }, + { 0x58, 0, 0x43 }, { 0x68, 0, 0x43 }, { 0x38, 0, 0x43 }, { 0x48, 0, 0x43 }, { 0x38, 0, 0x43 }, + { 0x48, 0, 0x43 }, { 0x34, 0, 0x83 }, { 0x34, 0, 0x4043 }, { 0x34, 0, 0x4043 }, { 0x34, 0, 0x83 }, + { 0x34, 0, 0x4043 }, { 0x50, 0, 0x43 }, { 0x34, 0, 0x43 }, { 0x50, 0, 0x43 }, { 0x36, 0, 0x43 }, + { 0x36, 0, 0x43 }, { 0x34, 0, 0x43 }, { 0x37, 0, 0x3 }, { 0x54, 0, 0x43 }, { 0x40, 0, 0x3 }, + { 0x40, 0, 0x3 }, { 0x57, 0, 0x3 }, { 0x34, 0, 0x2 }, { 0x40, 0, 0 }, { 0x32, 0, 0 }, + { 0x50, 0, 0x83 }, { 0x50, 0, 0x83 }, { 0x50, 0, 0x83 }, { 0x50, 0, 0x83 }, { 0x50, 0, 0x83 }, + { 0x58, 0, 0x83 }, { 0x58, 0, 0x83 }, { 0x68, 0, 0x3 }, { 0x68, 0, 0x3 }, { 0x48, 0, 0x3 }, + { 0x48, 0, 0x3 }, { 0x50, 0, 0x3 }, { 0x50, 0, 0x3 }, { 0x28, 0, 0x4 }, { 0x34, 0, 0x2 }, + { 0x30, 0, 0x4080 }, { 0x30, 0, 0x4080 }, { 0x30, 0, 0x4080 }, { 0x30, 0, 0x4080 }, { 0x30, 0, 0x1 }, + { 0x30, 0, 0x84 }, { 0x50, 0, 0x3 }, { 0x50, 0, 0x3 }, { 0x50, 0, 0x3 }, { 0x50, 0, 0x3 }, + { 0x58, 0, 0x3 }, { 0x58, 0, 0x3 }, { 0x68, 0, 0x3 }, { 0x50, 0, 0x3 }, { 0x50, 0, 0x3 }, + { 0x30, 0, 0x1 }, { 0x30, 0, 0x1 }, { 0x30, 0, 0x1 }, { 0x30, 0, 0x1 }, { 0x34, 0, 0x80 }, + { 0x34, 0, 0 }, { 0x34, 0, 0 }, { 0x34, 0, 0 }, { 0x34, 0, 0 }, { 0x34, 0, 0 }, + { 0x34, 0, 0 }, { 0x34, 0, 0 }, { 0x34, 0, 0 }, { 0x34, 0, 0 }, { 0x54, 0, 0 }, + { 0x34, 0, 0 }, { 0x34, 0, 0x2000 }, { 0x34, 0, 0x2000 }, { 0x34, 0, 0 }, { 0x30, 0, 0x5 }, + { 0x30, 0, 0x1 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x34, 0, 0x4083 }, { 0x34, 0, 0x4083 }, + { 0x30, 0, 0x4083 }, { 0x30, 0, 0x4083 }, { 0x34, 0, 0 }, { 0x30, 0, 0 }, { 0x34, 0, 0x1083 }, + { 0x30, 0, 0x1005 }, { 0x30, 0, 0x4080 }, { 0x34, 0, 0 }, { 0x34, 0, 0 }, { 0x30, 0, 0x6 }, + { 0x30, 0, 0x6 }, { 0x30, 0, 0x5 }, { 0x30, 0, 0x6 }, { 0x34, 0, 0 }, { 0x38, 0, 0 }, + { 0x48, 0, 0 }, { 0x30, 0, 0x80 }, { 0x30, 0, 0x85 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0x80 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x40, 0, 0x2 }, { 0x32, 0, 0x80 }, + { 0x50, 0, 0x2 }, { 0x50, 0, 0x2 }, { 0x58, 0, 0x2 }, { 0x68, 0, 0x2 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x50, 0, 0x2 }, { 0x50, 0, 0x2 }, { 0x30, 0, 0x3 }, { 0x54, 0, 0x5 }, + { 0x28, 0, 0x5 }, { 0x78, 0, 0x2000 }, { 0x78, 0, 0x2000 }, { 0x50, 0, 0x3 }, { 0x58, 0, 0x3 }, + { 0x68, 0, 0x3 }, { 0x54, 0, 0x3 }, { 0x40, 0, 0x3 }, { 0x78, 0, 0x3 }, { 0x48, 0, 0 }, + { 0x30, 0, 0x83 }, { 0x30, 0, 0x83 }, { 0x30, 0, 0x83 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0xC3 }, { 0x30, 0, 0x80 }, { 0x30, 0, 0x2000 }, { 0x30, 0, 0x2000 }, + { 0x30, 0, 0x2000 }, { 0x30, 0, 0x2000 }, { 0x30, 0, 0x2000 }, { 0x30, 0, 0x45 }, { 0x60, 0, 0x2 }, + { 0x70, 0, 0x2000 }, { 0x30, 0, 0x80 }, { 0x30, 0, 0x80 }, { 0x30, 0, 0x80 }, { 0x30, 0, 0x80 }, + { 0x30, 0, 0x80 }, { 0x30, 0, 0x80 }, { 0x30, 0, 0x80 }, { 0x30, 0, 0x80 }, { 0x30, 0, 0x80 }, + { 0x30, 0, 0x80 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x7 }, { 0x30, 0, 0x44 }, + { 0x30, 0, 0x44 }, { 0x30, 0, 0x83 }, { 0x48, 0, 0x3 }, { 0x58, 0, 0x3 }, { 0x30, 0, 0 }, + { 0x30, 0, 0x3 }, { 0x36, 0, 0 }, { 0x40, 0, 0x2 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, +}; + +SfxParams sPlayerBankParams[] = { + { 0x20, 0, 0x480 }, { 0x20, 0, 0x480 }, { 0x20, 0, 0x480 }, { 0x20, 0, 0x480 }, { 0x20, 0, 0x440 }, + { 0x20, 0, 0x440 }, { 0x20, 0, 0x440 }, { 0x20, 0, 0x440 }, { 0x20, 0, 0x480 }, { 0x20, 0, 0x440 }, + { 0x20, 0, 0x480 }, { 0x20, 0, 0x400 }, { 0x20, 0, 0x400 }, { 0x20, 0, 0x400 }, { 0x20, 0, 0x400 }, + { 0x20, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, + { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, + { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, + { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x30, 0, 0x80 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x40 }, { 0x30, 0, 0x40 }, { 0x30, 0, 0x80 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x40, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x40 }, + { 0x30, 0, 0x40 }, { 0x30, 0, 0x40 }, { 0x30, 0, 0x40 }, { 0x30, 0, 0x40 }, { 0x30, 0, 0x40 }, + { 0x30, 0, 0x40 }, { 0x30, 0, 0x40 }, { 0x30, 0, 0x40 }, { 0x30, 0, 0x40 }, { 0x30, 0, 0x40 }, + { 0x30, 0, 0x40 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x80, 0, 0 }, { 0x80, 0, 0 }, { 0x80, 0, 0 }, { 0x80, 0, 0 }, { 0x80, 0, 0 }, + { 0x80, 0, 0 }, { 0x80, 0, 0 }, { 0x80, 0, 0 }, { 0x80, 0, 0 }, { 0x80, 0, 0 }, + { 0x80, 0, 0 }, { 0x80, 0, 0 }, { 0x80, 0, 0 }, { 0x80, 0, 0 }, { 0x80, 0, 0 }, + { 0x80, 0, 0 }, { 0x30, 0, 0x440 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x80 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x1 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x2000 }, { 0x30, 0, 0xC00 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x20, 0, 0x80 }, { 0x20, 0, 0x80 }, + { 0x20, 0, 0x80 }, { 0x20, 0, 0x80 }, { 0x20, 0, 0x40 }, { 0x20, 0, 0x40 }, { 0x20, 0, 0x40 }, + { 0x20, 0, 0x40 }, { 0x20, 0, 0x80 }, { 0x20, 0, 0x80 }, { 0x20, 0, 0x80 }, { 0x20, 0, 0 }, + { 0x20, 0, 0 }, { 0x20, 0, 0 }, { 0x20, 0, 0 }, { 0x20, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x40, 0, 0 }, { 0x40, 0, 0 }, { 0x40, 0, 0 }, { 0x40, 0, 0 }, { 0x40, 0, 0 }, + { 0x40, 0, 0 }, { 0x40, 0, 0 }, { 0x40, 0, 0 }, { 0x40, 0, 0 }, { 0x40, 0, 0 }, + { 0x40, 0, 0 }, { 0x40, 0, 0 }, { 0x40, 0, 0 }, { 0x40, 0, 0 }, { 0x40, 0, 0 }, + { 0x40, 0, 0 }, { 0x30, 0, 0x440 }, { 0x30, 0, 0x440 }, { 0x30, 0, 0x440 }, { 0x30, 0, 0x440 }, + { 0x30, 0, 0x440 }, { 0x30, 0, 0x440 }, { 0x30, 0, 0x440 }, { 0x30, 0, 0x440 }, { 0x30, 0, 0x440 }, + { 0x30, 0, 0x440 }, { 0x30, 0, 0x440 }, { 0x30, 0, 0x440 }, { 0x30, 0, 0x440 }, { 0x30, 0, 0x440 }, + { 0x30, 0, 0x440 }, { 0x30, 0, 0x440 }, { 0x30, 0, 0xC00 }, { 0x30, 0, 0x4080 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x60, 0, 0x2 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x800 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0x403 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x400 }, + { 0x60, 0, 0x40 }, { 0x40, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x50, 0, 0x43 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x20, 0, 0x480 }, { 0x20, 0, 0x480 }, { 0x20, 0, 0x480 }, { 0x20, 0, 0x480 }, { 0x20, 0, 0x440 }, + { 0x20, 0, 0x440 }, { 0x20, 0, 0x440 }, { 0x20, 0, 0x440 }, { 0x20, 0, 0x480 }, { 0x20, 0, 0x440 }, + { 0x20, 0, 0x480 }, { 0x20, 0, 0x400 }, { 0x20, 0, 0x400 }, { 0x20, 0, 0x400 }, { 0x20, 0, 0x400 }, + { 0x20, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, + { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, + { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, + { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x20, 0, 0x480 }, { 0x20, 0, 0x480 }, + { 0x20, 0, 0x480 }, { 0x20, 0, 0x480 }, { 0x20, 0, 0x440 }, { 0x20, 0, 0x440 }, { 0x20, 0, 0x440 }, + { 0x20, 0, 0x440 }, { 0x20, 0, 0x480 }, { 0x20, 0, 0x440 }, { 0x20, 0, 0x480 }, { 0x20, 0, 0x400 }, + { 0x20, 0, 0x400 }, { 0x20, 0, 0x400 }, { 0x20, 0, 0x400 }, { 0x20, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, + { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, + { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, + { 0x40, 0, 0x440 }, { 0x20, 0, 0x480 }, { 0x20, 0, 0x480 }, { 0x20, 0, 0x480 }, { 0x20, 0, 0x480 }, + { 0x20, 0, 0x440 }, { 0x20, 0, 0x440 }, { 0x20, 0, 0x440 }, { 0x20, 0, 0x440 }, { 0x20, 0, 0x480 }, + { 0x20, 0, 0x440 }, { 0x20, 0, 0x480 }, { 0x20, 0, 0x400 }, { 0x20, 0, 0x400 }, { 0x20, 0, 0x400 }, + { 0x20, 0, 0x400 }, { 0x20, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, + { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, + { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, + { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x40, 0, 0x440 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x50, 0, 0x400 }, { 0x50, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x60, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x4080 }, { 0x40, 0, 0x403 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x2400 }, { 0x30, 0, 0x2400 }, + { 0x30, 0, 0x2400 }, { 0x30, 0, 0x2400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x43 }, + { 0x30, 0, 0x43 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x400 }, +}; + +SfxParams sItemBankParams[] = { + { 0x30, 0, 0x8040 }, { 0x30, 0, 0x40 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x40, 0, 0x440 }, + { 0x30, 0, 0x440 }, { 0x60, 0, 0x83 }, { 0x30, 0, 0x440 }, { 0x80, 0, 0x43 }, { 0x30, 0, 0 }, + { 0x30, 0, 0x40 }, { 0x38, 0, 0x400 }, { 0x30, 0, 0x401 }, { 0x50, 0, 0x100 }, { 0x90, 0, 0x2 }, + { 0x50, 0, 0x2 }, { 0x30, 0, 0x400 }, { 0x40, 0, 0x2 }, { 0x30, 0, 0x40 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x34, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x60, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0x80 }, { 0x30, 0, 0x40 }, { 0x30, 0, 0x400 }, { 0x20, 0, 0x400 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x400 }, + { 0x30, 0, 0x400 }, { 0x60, 0, 0x43 }, { 0x30, 0, 0x1 }, { 0x30, 0, 0x401 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0xA0, 0, 0x2 }, { 0xA0, 0, 0x2 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0x100 }, + { 0x60, 0, 0 }, { 0x60, 0, 0 }, { 0x60, 0, 0 }, { 0x30, 0, 0x400 }, { 0x30, 0, 0 }, + { 0x60, 0, 0x81 }, { 0x30, 0, 0 }, { 0x30, 0, 0x400 }, { 0x60, 0, 0x8003 }, { 0x60, 0, 0x8003 }, + { 0x60, 0, 0x8003 }, { 0x30, 0, 0x4000 }, { 0x30, 0, 0x4000 }, { 0x30, 0, 0x40 }, { 0x80, 0, 0x3 }, + { 0x80, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0 }, { 0x30, 0, 0x40 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x80, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x80, 0, 0 }, { 0x80, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x40, 0, 0 }, + { 0x30, 0, 0 }, { 0x60, 0, 0x100 }, { 0x70, 0, 0 }, { 0x60, 0, 0 }, { 0x30, 0, 0x483 }, + { 0x30, 0, 0x40 }, { 0x30, 0, 0x40 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x60, 0, 0x2000 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, +}; + +SfxParams sEnvBankParams[] = { + { 0x70, 0, 0x640 }, { 0x80, 0, 0x40 }, { 0x30, 0, 0 }, { 0x60, 0, 0x40 }, { 0x60, 0, 0x40 }, + { 0x70, 0, 0x40 }, { 0x30, 0, 0x480 }, { 0x70, 0, 0x2 }, { 0x30, 0, 0x40 }, { 0x30, 0, 0x40 }, + { 0x80, 0, 0x2 }, { 0xA0, 0, 0x3 }, { 0x30, 0, 0x103 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, + { 0x30, 0, 0x3 }, { 0x30, 0, 0x2 }, { 0x30, 0, 0x40 }, { 0x30, 0, 0x40 }, { 0x50, 0, 0 }, + { 0x60, 0, 0x2 }, { 0x30, 0, 0x3 }, { 0x60, 0, 0 }, { 0x30, 0, 0x82 }, { 0x30, 0, 0 }, + { 0x40, 0, 0 }, { 0x68, 0, 0 }, { 0x58, 0, 0x40 }, { 0x60, 0, 0 }, { 0x70, 0, 0x3 }, + { 0x30, 0, 0x43 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0xA0, 0, 0x2008 }, { 0x20, 0, 0x2 }, + { 0x30, 0, 0 }, { 0x30, 0, 0x800 }, { 0x30, 0, 0x8800 }, { 0x30, 0, 0x8000 }, { 0x30, 0, 0x2 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x60, 0, 0 }, { 0x60, 0, 0x400 }, + { 0x30, 0, 0 }, { 0x80, 0, 0 }, { 0x30, 0, 0x80 }, { 0x30, 0, 0x40 }, { 0x10, 0, 0 }, + { 0xA0, 0, 0x3 }, { 0x30, 0, 0x100 }, { 0x30, 0, 0x10 }, { 0x30, 0, 0x3 }, { 0x60, 0x40, 0x3 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x2 }, { 0x30, 0, 0 }, { 0xA0, 0, 0x3 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x3 }, { 0x70, 0, 0 }, { 0x60, 0, 0x8000 }, + { 0x30, 0, 0x8000 }, { 0x60, 0, 0 }, { 0x60, 0, 0 }, { 0x60, 0, 0 }, { 0x60, 0, 0 }, + { 0x30, 0, 0x2003 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x2010 }, { 0x30, 0, 0x40 }, + { 0x60, 0, 0 }, { 0x60, 0, 0x3 }, { 0x30, 0, 0 }, { 0x58, 0, 0x1 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x40, 0, 0 }, { 0x30, 0, 0xC3 }, { 0x70, 0, 0x2 }, { 0x60, 0, 0x2 }, + { 0x30, 0, 0 }, { 0x60, 0, 0x41 }, { 0x30, 0, 0x2 }, { 0x30, 0, 0 }, { 0x90, 0, 0x3 }, + { 0x90, 0, 0x3 }, { 0x30, 0, 0 }, { 0x30, 0, 0x2 }, { 0x30, 0, 0x3800 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x3 }, + { 0x30, 0, 0x40 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x803 }, + { 0x30, 0, 0 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x80 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x2 }, { 0x60, 0, 0 }, + { 0x30, 0, 0x640 }, { 0x30, 0, 0x2 }, { 0x30, 0, 0x2 }, { 0x80, 0, 0x2 }, { 0x40, 0, 0 }, + { 0x1C, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x60, 0, 0x4 }, { 0x30, 0, 0x800 }, + { 0x30, 0, 0x40 }, { 0x30, 0, 0 }, { 0x60, 0, 0 }, { 0x60, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x60, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, + { 0x80, 0, 0 }, { 0x30, 0, 0x2000 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0x80 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0x800 }, { 0x30, 0, 0x800 }, { 0x30, 0, 0x2 }, { 0x30, 0, 0x3 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x20, 0, 0x3 }, + { 0x30, 0, 0 }, { 0x30, 0, 0x8000 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x70, 0, 0x2 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x50, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x2003 }, { 0x20, 0, 0 }, + { 0x30, 0, 0xC0 }, { 0x30, 0, 0x2000 }, { 0x30, 0, 0 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0x2 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x2 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x6 }, { 0xA0, 0, 0x3 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0xC0 }, { 0x30, 0, 0x2 }, { 0x30, 0, 0x2 }, + { 0x30, 0, 0 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0 }, { 0x30, 0, 0x4083 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x60, 0, 0x83 }, + { 0x80, 0, 0x2000 }, { 0x50, 0, 0 }, { 0x60, 0, 0 }, { 0x90, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x60, 0, 0x2000 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0xA0, 0, 0x800 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0x2 }, { 0x30, 0, 0 }, { 0x30, 0, 0x3 }, { 0x20, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0x40 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x2 }, { 0x30, 0, 0 }, + { 0x30, 0, 0x2 }, { 0x30, 0, 0x5 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x40, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x5 }, { 0x30, 0, 0xC2 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0x80 }, { 0x30, 0, 0x80 }, { 0x30, 0, 0 }, { 0x30, 0, 0x2 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x68, 0, 0x2 }, + { 0x30, 0, 0x2 }, { 0x30, 0, 0x4040 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x2 }, + { 0x30, 0, 0x2 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0xC0 }, { 0x80, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x2 }, { 0xA0, 0, 0xA003 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x80 }, { 0x30, 0, 0 }, + { 0x30, 0, 0x85 }, { 0x30, 0, 0x40 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x60, 0, 0x2000 }, { 0x30, 0, 0 }, { 0x30, 0, 0x40 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0x2000 }, { 0x30, 0, 0x2 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0 }, { 0x30, 0, 0x40 }, + { 0x30, 0, 0x40 }, { 0x30, 0, 0x80 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0xC0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x80, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x43 }, + { 0x30, 0, 0x2000 }, { 0x30, 0, 0 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, + { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0x3 }, { 0xA0, 0, 0x4000 }, { 0x30, 0, 0x43 }, { 0x30, 0, 0x40 }, { 0x60, 0, 0x2 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x2080 }, { 0x30, 0, 0x2080 }, { 0x30, 0, 0x2000 }, + { 0x30, 0, 0 }, { 0x30, 0, 0x2000 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x60, 0, 0 }, + { 0x30, 0, 0x2 }, { 0x30, 0, 0 }, { 0x30, 0, 0x2 }, { 0x30, 0, 0x80 }, { 0x60, 0, 0x42 }, + { 0x30, 0, 0x2000 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x2000 }, { 0x30, 0, 0x2000 }, { 0x30, 0, 0x2000 }, + { 0x30, 0, 0 }, { 0x30, 0, 0x2000 }, { 0x30, 0, 0 }, { 0x30, 0, 0x2000 }, { 0x80, 0, 0 }, + { 0x80, 0, 0x3 }, { 0x80, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x80, 0, 0x2 }, { 0x80, 0, 0x2 }, + { 0x30, 0, 0 }, { 0x60, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x42 }, { 0x30, 0, 0x42 }, + { 0x30, 0, 0x43 }, { 0x60, 0x80, 0x2000 }, { 0x60, 0x80, 0x2000 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0x3 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x3 }, + { 0x30, 0, 0x2000 }, { 0x80, 0, 0x2000 }, { 0x80, 0, 0x3 }, { 0x30, 0, 0 }, { 0x30, 0, 0x2000 }, + { 0x30, 0, 0x2000 }, { 0x30, 0, 0x2000 }, { 0x30, 0, 0x2000 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x80, 0, 0x3 }, { 0x30, 0, 0x2000 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0x43 }, + { 0x30, 0, 0x3 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0 }, { 0x30, 0, 0x2000 }, { 0x10, 0, 0x7 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x2000 }, { 0x30, 0, 0x2000 }, { 0x30, 0, 0x2000 }, + { 0x58, 0, 0x60 }, { 0x60, 0, 0x3 }, { 0x60, 0, 0x3 }, { 0x60, 0, 0x3 }, { 0x70, 0, 0x3 }, + { 0x70, 0, 0x3 }, { 0x30, 0, 0 }, { 0x70, 0, 0x3 }, { 0x30, 0, 0x4 }, { 0x30, 0, 0x3 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x60, 0, 0 }, { 0x60, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0x80, 0 }, { 0x30, 0x80, 0x40 }, { 0x30, 0x80, 0x40 }, { 0x60, 0, 0x2000 }, { 0x70, 0, 0x2000 }, + { 0x30, 0, 0x80 }, { 0x30, 0, 0x2000 }, { 0x30, 0, 0x3 }, { 0x30, 0, 0 }, { 0x60, 0, 0x3 }, + { 0x70, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x40, 0, 0 }, { 0x58, 0, 0x40 }, { 0x58, 0, 0x40 }, + { 0x30, 0, 0x40 }, { 0x30, 0, 0x41 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, +}; + +SfxParams sSystemBankParams[] = { + { 0xC0, 0, 0 }, { 0xC0, 0, 0 }, { 0xB0, 0, 0x20 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x50, 0, 0 }, { 0x30, 0, 0x20 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x20, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x28, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x18, 0, 0 }, { 0x2C, 0, 0 }, { 0x2C, 0, 0 }, { 0x20, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x20, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x60, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x60, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0x20 }, { 0x60, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0xA0, 0, 0x8 }, { 0xA0, 0, 0x8 }, { 0x30, 0, 0 }, +}; + +SfxParams sOcarinaBankParams[] = { + { 0x30, 0, 0 }, { 0x30, 0, 0x20 }, { 0x30, 0, 0x642 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x2000 }, { 0x30, 0, 0x2000 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, +}; + +SfxParams sVoiceBankParams[] = { + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x20, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x442 }, + { 0x30, 0, 0x442 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x50, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x482 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x80, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x20, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x442 }, { 0x30, 0, 0x442 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x50, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x481 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0 }, { 0x60, 0, 0x20 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0 }, + { 0x30, 0, 0 }, { 0x30, 0, 0 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, + { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, + { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8000 }, { 0x30, 0, 0x8000 }, + { 0x30, 0, 0x8000 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, + { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, + { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, + { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, + { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8001 }, { 0x30, 0, 0x8043 }, { 0x30, 0, 0x8043 }, { 0x30, 0, 0x8043 }, + { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, + { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x8041 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x20, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x442 }, { 0x30, 0, 0x442 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x50, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x481 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x20, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x442 }, + { 0x30, 0, 0x442 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x50, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x482 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x80, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x20, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x442 }, { 0x30, 0, 0x442 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x50, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x482 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x80, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x442 }, + { 0x30, 0, 0x442 }, { 0x30, 0, 0x442 }, { 0x20, 0, 0x442 }, { 0x30, 0, 0x442 }, { 0x30, 0, 0x442 }, + { 0x30, 0, 0x442 }, { 0x30, 0, 0x442 }, { 0x30, 0, 0x442 }, { 0x30, 0, 0x442 }, { 0x30, 0, 0x442 }, + { 0x30, 0, 0x442 }, { 0x30, 0, 0x442 }, { 0x50, 0, 0x442 }, { 0x30, 0, 0x442 }, { 0x30, 0, 0x442 }, + { 0x30, 0, 0x442 }, { 0x30, 0, 0x442 }, { 0x30, 0, 0x442 }, { 0x30, 0, 0x442 }, { 0x30, 0, 0x442 }, + { 0x30, 0, 0x442 }, { 0x30, 0, 0x442 }, { 0x30, 0, 0x442 }, { 0x30, 0, 0x482 }, { 0x30, 0, 0x442 }, + { 0x30, 0, 0x442 }, { 0x30, 0, 0x442 }, { 0x30, 0, 0x442 }, { 0x80, 0, 0x442 }, { 0x30, 0, 0x442 }, + { 0x30, 0x80, 0x442 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, + { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, { 0x30, 0, 0x402 }, +}; + +SfxParams* gSfxParams[7] = { + sPlayerBankParams, sItemBankParams, sEnvBankParams, sEnemyBankParams, + sSystemBankParams, sOcarinaBankParams, sVoiceBankParams, +}; diff --git a/src/code/audio/code_80194710.c b/src/code/audio/code_80194710.c deleted file mode 100644 index 090c5735b..000000000 --- a/src/code/audio/code_80194710.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_80194710/func_80194710.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_80194710/func_80194750.s") diff --git a/src/code/code_800F07C0.c b/src/code/code_800F07C0.c deleted file mode 100644 index 9255dcfcb..000000000 --- a/src/code/code_800F07C0.c +++ /dev/null @@ -1,31 +0,0 @@ -#include "global.h" - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F07C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0888.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0944.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F09B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0A20.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0A94.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0BB4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0CE4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0DD4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0E94.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0EEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0F28.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F0FF0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F10AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/code/code_800F07C0/func_800F112C.s") diff --git a/src/code/code_8012EC80.c b/src/code/code_8012EC80.c index 3bd5aac92..34ad973f6 100644 --- a/src/code/code_8012EC80.c +++ b/src/code/code_8012EC80.c @@ -45,7 +45,7 @@ void* gItemIcons[] = { 0x08007000, // ITEM_BOMBCHU 0x08008000, // ITEM_STICK 0x08009000, // ITEM_NUT - 0x0800A000, // ITEM_BEAN + 0x0800A000, // ITEM_MAGIC_BEANS 0x0800B000, // ITEM_SLINGSHOT 0x0800C000, // ITEM_POWDER_KEG 0x0800D000, // ITEM_PICTO_BOX @@ -82,7 +82,7 @@ void* gItemIcons[] = { 0x0802C000, // ITEM_DEED_OCEAN 0x0802D000, // ITEM_ROOM_KEY 0x0802E000, // ITEM_LETTER_MAMA - 0x0802F000, // ITEM_LETTER_KAFEI + 0x0802F000, // ITEM_LETTER_TO_KAFEI 0x08030000, // ITEM_PENDANT_MEMORIES 0x08031000, // ITEM_TINGLE_MAP 0x08032000, // ITEM_MASK_DEKU @@ -90,7 +90,7 @@ void* gItemIcons[] = { 0x08034000, // ITEM_MASK_ZORA 0x08035000, // ITEM_MASK_FIERCE_DEITY 0x08036000, // ITEM_MASK_TRUTH - 0x08037000, // ITEM_MASK_KAFEI + 0x08037000, // ITEM_MASK_KAFEIS_MASK 0x08038000, // ITEM_MASK_ALL_NIGHT 0x08039000, // ITEM_MASK_BUNNY 0x0803A000, // ITEM_MASK_KEATON @@ -180,7 +180,7 @@ u8 gItemSlots[] = { SLOT_BOMBCHU, // ITEM_BOMBCHU SLOT_STICK, // ITEM_STICK SLOT_NUT, // ITEM_NUT - SLOT_BEAN, // ITEM_BEAN + SLOT_MAGIC_BEANS, // ITEM_MAGIC_BEANS SLOT_TRADE_KEY_MAMA, // ITEM_SLINGSHOT SLOT_POWDER_KEG, // ITEM_POWDER_KEG SLOT_PICTO_BOX, // ITEM_PICTO_BOX @@ -217,7 +217,7 @@ u8 gItemSlots[] = { SLOT_TRADE_DEED, // ITEM_DEED_OCEAN SLOT_TRADE_KEY_MAMA, // ITEM_ROOM_KEY SLOT_TRADE_KEY_MAMA, // ITEM_LETTER_MAMA - SLOT_TRADE_COUPLE, // ITEM_LETTER_KAFEI + SLOT_TRADE_COUPLE, // ITEM_LETTER_TO_KAFEI SLOT_TRADE_COUPLE, // ITEM_PENDANT_MEMORIES SLOT_TRADE_COUPLE, // ITEM_TINGLE_MAP SLOT_MASK_DEKU, // ITEM_MASK_DEKU @@ -225,7 +225,7 @@ u8 gItemSlots[] = { SLOT_MASK_ZORA, // ITEM_MASK_ZORA SLOT_MASK_FIERCE_DEITY, // ITEM_MASK_FIERCE_DEITY SLOT_MASK_TRUTH, // ITEM_MASK_TRUTH - SLOT_MASK_KAFEI, // ITEM_MASK_KAFEI + SLOT_MASK_KAFEIS_MASK, // ITEM_MASK_KAFEIS_MASK SLOT_MASK_ALL_NIGHT, // ITEM_MASK_ALL_NIGHT SLOT_MASK_BUNNY, // ITEM_MASK_BUNNY SLOT_MASK_KEATON, // ITEM_MASK_KEATON @@ -260,7 +260,7 @@ s16 gItemPrices[] = { 0, // ITEM_BOMBCHU 0, // ITEM_STICK 0, // ITEM_NUT - 0, // ITEM_BEAN + 0, // ITEM_MAGIC_BEANS 0, // ITEM_SLINGSHOT 0, // ITEM_POWDER_KEG 0, // ITEM_PICTO_BOX diff --git a/src/code/graph.c b/src/code/graph.c index 7ef1715fd..b874fef51 100644 --- a/src/code/graph.c +++ b/src/code/graph.c @@ -88,33 +88,27 @@ GameStateOverlay* Graph_GetNextGameState(GameState* gameState) { return NULL; } -#ifdef NON_MATCHING -// Regalloc differences void* Graph_FaultAddrConvFunc(void* address, void* param) { - u32 addr = address; - GameStateOverlay* gamestateOvl; - u32 ramConv; - u32 ramStart; - u32 diff; + uintptr_t addr = address; + GameStateOverlay* gamestateOvl = &gGameStateOverlayTable[0]; + uintptr_t ramConv; + void* ramStart; + uintptr_t diff; s32 i; - for (i = 0; i < graphNumGameStates; i++) { - gamestateOvl = &gGameStateOverlayTable[i]; + for (i = 0; i < graphNumGameStates; i++, gamestateOvl++) { + diff = (uintptr_t)gamestateOvl->vramEnd - (uintptr_t)gamestateOvl->vramStart; ramStart = gamestateOvl->loadedRamAddr; - diff = (u32)gamestateOvl->vramEnd - (u32)gamestateOvl->vramStart; - ramConv = (u32)gamestateOvl->vramStart - ramStart; + ramConv = (uintptr_t)gamestateOvl->vramStart - (uintptr_t)ramStart; - if (gamestateOvl->loadedRamAddr != NULL) { - if (addr >= ramStart && addr < ramStart + diff) { + if (ramStart != NULL) { + if (addr >= (uintptr_t)ramStart && addr < (uintptr_t)ramStart + diff) { return addr + ramConv; } } } return NULL; } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/graph/Graph_FaultAddrConvFunc.s") -#endif void Graph_Init(GraphicsContext* gfxCtx) { bzero(gfxCtx, sizeof(GraphicsContext)); diff --git a/src/code/sys_initial_check.c b/src/code/sys_initial_check.c index 84871255b..ec61d07b5 100644 --- a/src/code/sys_initial_check.c +++ b/src/code/sys_initial_check.c @@ -10,8 +10,16 @@ #include "misc/locerrmsg/locerrmsg.h" #include "misc/memerrmsg/memerrmsg.h" -#define SIZEOF_LOCERRMSG (sizeof(gNotDesignedForSystemErrorTex)) -#define SIZEOF_MEMERRMSG (sizeof(gExpansionPakNotInstalledErrorTex) + sizeof(gSeeInstructionBookletErrorTex)) +#define LOCERRMSG_WIDTH 208 +#define LOCERRMSG_HEIGHT 16 +#define NUMBEROF_LOCERRMSGS 1 + +#define MEMERRMSG_WIDTH 128 +#define MEMERRMSG_HEIGHT 37 +#define NUMBEROF_MEMERRMSGS 2 + +#define SIZEOF_LOCERRMSG (LOCERRMSG_WIDTH * LOCERRMSG_HEIGHT / 2 * NUMBEROF_LOCERRMSGS) +#define SIZEOF_MEMERRMSG (MEMERRMSG_WIDTH * MEMERRMSG_HEIGHT / 2 * NUMBEROF_MEMERRMSGS) // Address with enough room after to load either of the error message image files before the fault screen buffer at the // end of RDRAM @@ -64,9 +72,9 @@ void Check_ClearRGBA16(u16* buffer) { void Check_DrawExpansionPakErrorMessage(void) { DmaMgr_SendRequest0(CHECK_ERRMSG_STATIC_SEGMENT, SEGMENT_ROM_START(memerrmsg), SEGMENT_SIZE(memerrmsg)); Check_ClearRGBA16((u16*)FAULT_FB_ADDRESS); - Check_DrawI4Texture((u16*)FAULT_FB_ADDRESS, 96, 71, 128, 37, CHECK_ERRMSG_STATIC_SEGMENT); - Check_DrawI4Texture((u16*)FAULT_FB_ADDRESS, 96, 127, 128, 37, - CHECK_ERRMSG_STATIC_SEGMENT + sizeof(gExpansionPakNotInstalledErrorTex)); + Check_DrawI4Texture((u16*)FAULT_FB_ADDRESS, 96, 71, MEMERRMSG_WIDTH, MEMERRMSG_HEIGHT, CHECK_ERRMSG_STATIC_SEGMENT); + Check_DrawI4Texture((u16*)FAULT_FB_ADDRESS, 96, 127, MEMERRMSG_WIDTH, MEMERRMSG_HEIGHT, + CHECK_ERRMSG_STATIC_SEGMENT + MEMERRMSG_WIDTH * MEMERRMSG_HEIGHT / 2); osWritebackDCacheAll(); osViSwapBuffer((u16*)FAULT_FB_ADDRESS); osViBlack(false); @@ -78,7 +86,8 @@ void Check_DrawExpansionPakErrorMessage(void) { void Check_DrawRegionLockErrorMessage(void) { DmaMgr_SendRequest0(CHECK_ERRMSG_STATIC_SEGMENT, SEGMENT_ROM_START(locerrmsg), SEGMENT_SIZE(locerrmsg)); Check_ClearRGBA16((u16*)FAULT_FB_ADDRESS); - Check_DrawI4Texture((u16*)FAULT_FB_ADDRESS, 56, 112, 208, 16, CHECK_ERRMSG_STATIC_SEGMENT); + Check_DrawI4Texture((u16*)FAULT_FB_ADDRESS, 56, 112, LOCERRMSG_WIDTH, LOCERRMSG_HEIGHT, + CHECK_ERRMSG_STATIC_SEGMENT); osWritebackDCacheAll(); osViSwapBuffer((u16*)FAULT_FB_ADDRESS); osViBlack(false); diff --git a/src/code/sys_ucode.c b/src/code/sys_ucode.c index a832f9d38..9bde9e6df 100644 --- a/src/code/sys_ucode.c +++ b/src/code/sys_ucode.c @@ -1,9 +1,27 @@ +/* + * File: sys_ucode.c + * Description: Functions for obtaining locations and sizes of microcode + */ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_ucode/SysUcode_GetUCodeBoot.s") +extern u64 rspbootTextStart[]; +extern u64 rspbootTextEnd[]; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_ucode/SysUcode_GetUCodeBootSize.s") +u64* initialgspUcodeText = gspF3DEX2_NoN_fifoTextStart; +u64* initialgspUcodeData = gspF3DEX2_NoN_fifoDataStart; -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_ucode/SysUcode_GetUCode.s") +u64* SysUcode_GetUCodeBoot(void) { + return rspbootTextStart; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/sys_ucode/SysUcode_GetUCodeData.s") +size_t SysUcode_GetUCodeBootSize(void) { + return (uintptr_t)rspbootTextEnd - (uintptr_t)rspbootTextStart; +} + +u64* SysUcode_GetUCode(void) { + return initialgspUcodeText; +} + +u64* SysUcode_GetUCodeData(void) { + return initialgspUcodeData; +} diff --git a/src/code/z_bgcheck.c b/src/code/z_bgcheck.c index e5cb1ddb1..d7a94da5b 100644 --- a/src/code/z_bgcheck.c +++ b/src/code/z_bgcheck.c @@ -68,10 +68,12 @@ BgSpecialSceneMaxObjects sCustomDynapolyMem[] = { { SCENE_21MITURINMAE, 1000, 600, 512 }, }; +// TODO: All these bss variables are localized to one function and can +// likely be made into in-function static bss variables in the future char D_801ED950[80]; char D_801ED9A0[80]; Vec3f D_801ED9F0[3]; // polyVerts -Vec3f D_801EDA18[3]; // polyVerts //not ok, needs to be inlined to match +Vec3f D_801EDA18[3]; // polyVerts MtxF D_801EDA40; Vec3f D_801EDA80[3]; // polyVerts char D_801EDAA8[80]; @@ -79,8 +81,6 @@ char D_801EDAF8[80]; Vec3f D_801EDB48[3]; // polyVerts Vec3f D_801EDB70[3]; Plane D_801EDB98; -Sphere16 D_801EDBA8; -TriNorm D_801EDBB0; void BgCheck_GetStaticLookupIndicesFromPos(CollisionContext* colCtx, Vec3f* pos, Vec3i* sector); f32 BgCheck_RaycastFloorDyna(DynaRaycast* dynaRaycast); @@ -322,40 +322,34 @@ s32 CollisionPoly_CheckYIntersectApprox1(CollisionPoly* poly, Vec3s* vtxList, f3 * Checks if point (`x`,`z`) is within `checkDist` of `poly`, computing `yIntersect` if true * Determinant max 0.0f (checks if on or within poly) */ -#ifdef NON_MATCHING s32 CollisionPoly_CheckYIntersect(CollisionPoly* poly, Vec3s* vtxList, f32 x, f32 z, f32* yIntersect, f32 checkDist) { - static Vec3f polyVerts[3]; // D_801EDA18 Vec3s* sVerts; f32 nx; f32 ny; f32 nz; sVerts = &vtxList[COLPOLY_VTX_INDEX(poly->flags_vIA)]; - polyVerts[0].x = sVerts->x; - polyVerts[0].y = sVerts->y; - polyVerts[0].z = sVerts->z; + D_801EDA18[0].x = sVerts->x; + D_801EDA18[0].y = sVerts->y; + D_801EDA18[0].z = sVerts->z; sVerts = &vtxList[COLPOLY_VTX_INDEX(poly->flags_vIB)]; - polyVerts[1].x = sVerts->x; - polyVerts[1].y = sVerts->y; - polyVerts[1].z = sVerts->z; - sVerts = &vtxList[poly->vIC]; - polyVerts[2].x = sVerts->x; - polyVerts[2].y = sVerts->y; - polyVerts[2].z = sVerts->z; + D_801EDA18[1].x = sVerts->x; + D_801EDA18[1].y = sVerts->y; + D_801EDA18[1].z = sVerts->z; + sVerts = &vtxList[(s32)poly->vIC]; + D_801EDA18[2].x = sVerts->x; + D_801EDA18[2].y = sVerts->y; + D_801EDA18[2].z = sVerts->z; - if (!func_8017A304(&polyVerts[0], &polyVerts[1], &polyVerts[2], z, x, checkDist)) { + if (!func_8017A304(&D_801EDA18[0], &D_801EDA18[1], &D_801EDA18[2], z, x, checkDist)) { return 0; } nx = COLPOLY_GET_NORMAL(poly->normal.x); ny = COLPOLY_GET_NORMAL(poly->normal.y); nz = COLPOLY_GET_NORMAL(poly->normal.z); - return Math3D_TriChkPointParaYIntersectInsideTri2(&polyVerts[0], &polyVerts[1], &polyVerts[2], nx, ny, nz, + return Math3D_TriChkPointParaYIntersectInsideTri2(&D_801EDA18[0], &D_801EDA18[1], &D_801EDA18[2], nx, ny, nz, poly->dist, z, x, yIntersect, checkDist); } -#else -s32 CollisionPoly_CheckYIntersect(CollisionPoly* poly, Vec3s* vtxList, f32 x, f32 z, f32* yIntersect, f32 checkDist); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/CollisionPoly_CheckYIntersect.s") -#endif s32 CollisionPoly_CheckYIntersectApprox2(CollisionPoly* poly, Vec3s* vtxList, f32 x, f32 z, f32* yIntersect) { return CollisionPoly_CheckYIntersectApprox1(poly, vtxList, x, z, yIntersect, 1.0f); @@ -427,8 +421,6 @@ s32 CollisionPoly_LineVsPoly(BgLineVsPolyTest* a0); #pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/CollisionPoly_LineVsPoly.s") #endif -#ifdef NON_MATCHING -// OK but .bss order issues s32 CollisionPoly_SphVsPoly(CollisionPoly* poly, Vec3s* vtxList, Vec3f* center, f32 radius) { static Sphere16 sphere; // D_801EDBA8 static TriNorm tri; // D_801EDBB0 @@ -443,12 +435,7 @@ s32 CollisionPoly_SphVsPoly(CollisionPoly* poly, Vec3s* vtxList, Vec3f* center, sphere.radius = radius; return Math3D_ColSphereTri(&sphere, &tri, &intersect); } -#else -s32 CollisionPoly_SphVsPoly(CollisionPoly* poly, Vec3s* vtxList, Vec3f* center, f32 radius); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/CollisionPoly_SphVsPoly.s") -#endif -#ifdef NON_MATCHING /** * Add poly to StaticLookup table * Table is sorted by poly's smallest y vertex component @@ -486,6 +473,8 @@ void StaticLookup_AddPolyToSSList(CollisionContext* colCtx, SSList* ssList, Coll while (true) { // if at the end of the list if (curNode->next == SS_NULL) { + s32 pad; + newNodeId = SSNodeList_GetNextNodeIdx(&colCtx->polyNodes); SSNode_SetValue(&colCtx->polyNodes.tbl[newNodeId], &polyId, SS_NULL); curNode->next = newNodeId; @@ -507,9 +496,6 @@ void StaticLookup_AddPolyToSSList(CollisionContext* colCtx, SSList* ssList, Coll curNode = nextNode; } } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/StaticLookup_AddPolyToSSList.s") -#endif /** * Add CollisionPoly to StaticLookup list @@ -871,28 +857,29 @@ s32 BgCheck_SphVsStaticWall(StaticLookup* lookup, CollisionContext* colCtx, u16 * `outPoly` returns the poly collided with * `outY` returns the y coordinate needed to not collide with `outPoly` */ -#ifdef NON_MATCHING s32 BgCheck_CheckStaticCeiling(StaticLookup* lookup, u16 xpFlags, CollisionContext* colCtx, f32* outY, Vec3f* pos, f32 checkHeight, CollisionPoly** outPoly, Actor* actor) { s32 result = false; - // u16 nextId; CollisionPoly* curPoly; CollisionPoly* polyList; - f32 ceilingY; - Vec3s* vtxList; - SSNode* curNode; s32 curPolyId; + f32 ceilingY; + SSNode* curNode; + Vec3s* vtxList; if (lookup->ceiling.head == SS_NULL) { return result; } - curNode = &colCtx->polyNodes.tbl[lookup->ceiling.head]; polyList = colCtx->colHeader->polyList; vtxList = colCtx->colHeader->vtxList; + curNode = &colCtx->polyNodes.tbl[lookup->ceiling.head]; *outY = pos->y; while (true) { + f32 intersectDist; + f32 ny; + curPolyId = curNode->polyId; curPoly = &polyList[curPolyId]; if (COLPOLY_VIA_FLAG_TEST(colCtx->colHeader->polyList[curPolyId].flags_vIA, xpFlags) || @@ -908,8 +895,8 @@ s32 BgCheck_CheckStaticCeiling(StaticLookup* lookup, u16 xpFlags, CollisionConte } if (CollisionPoly_CheckYIntersectApprox2(curPoly, vtxList, pos->x, pos->z, &ceilingY)) { - f32 intersectDist = ceilingY - *outY; - f32 ny = COLPOLY_GET_NORMAL(curPoly->normal.y); + intersectDist = ceilingY - *outY; + ny = COLPOLY_GET_NORMAL(curPoly->normal.y); if (intersectDist > 0 && intersectDist < checkHeight && intersectDist * ny <= 0) { *outY = ceilingY - checkHeight; @@ -926,11 +913,6 @@ s32 BgCheck_CheckStaticCeiling(StaticLookup* lookup, u16 xpFlags, CollisionConte } return result; } -#else -s32 BgCheck_CheckStaticCeiling(StaticLookup* lookup, u16 xpFlags, CollisionContext* colCtx, f32* outY, Vec3f* pos, - f32 checkHeight, CollisionPoly** outPoly, Actor* actor); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_CheckStaticCeiling.s") -#endif /** * Tests if line `posA` to `posB` intersects with a static poly in list `ssList`. Uses polyCheckTbl @@ -1049,7 +1031,6 @@ s32 BgCheck_CheckLineInSubdivision(StaticLineTest* arg0) { * returns true if any poly intersects the sphere, else returns false * `outPoly` returns the pointer of the first poly found that intersects */ -#ifdef NON_MATCHING s32 BgCheck_SphVsFirstStaticPolyList(SSNode* node, u16 xpFlags, CollisionContext* colCtx, Vec3f* center, f32 radius, CollisionPoly** outPoly, Actor* actor) { Vec3s* vtxList; @@ -1057,7 +1038,6 @@ s32 BgCheck_SphVsFirstStaticPolyList(SSNode* node, u16 xpFlags, CollisionContext CollisionPoly* curPoly; u16 nextId; s16 curPolyId; - s32 pad; polyList = colCtx->colHeader->polyList; vtxList = colCtx->colHeader->vtxList; @@ -1088,17 +1068,14 @@ s32 BgCheck_SphVsFirstStaticPolyList(SSNode* node, u16 xpFlags, CollisionContext } if (node->next != SS_NULL) { node = &colCtx->polyNodes.tbl[node->next]; + { s32 pad; } + continue; } break; } return false; } -#else -s32 BgCheck_SphVsFirstStaticPolyList(SSNode* node, u16 xpFlags, CollisionContext* colCtx, Vec3f* center, f32 radius, - CollisionPoly** outPoly, Actor* actor); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_SphVsFirstStaticPolyList.s") -#endif /** * Get first static poly intersecting sphere `center` `radius` within `lookup` @@ -1539,16 +1516,12 @@ s32 BgCheck_GetSpecialSceneMaxObjects(GlobalContext* globalCtx, s32* maxNodes, s /** * Allocate CollisionContext */ -#ifdef NON_MATCHING void BgCheck_Allocate(CollisionContext* colCtx, GlobalContext* globalCtx, CollisionHeader* colHeader) { u32 tblMax; u32 memSize; u32 lookupTblMemSize; SSNodeList* nodeList; - s32 useCustomSubdivisions; - u32 customMemSize; s32 customNodeListMax; - s32 i; customNodeListMax = -1; colCtx->colHeader = colHeader; @@ -1563,6 +1536,10 @@ void BgCheck_Allocate(CollisionContext* colCtx, GlobalContext* globalCtx, Collis colCtx->subdivAmount.y = 4; colCtx->subdivAmount.z = 16; } else { + u32 customMemSize; + s32 useCustomSubdivisions; + s32 i; + if (BgCheck_TryGetCustomMemsize(globalCtx->sceneNum, &customMemSize)) { colCtx->memSize = customMemSize; } else { @@ -1631,10 +1608,6 @@ void BgCheck_Allocate(CollisionContext* colCtx, GlobalContext* globalCtx, Collis DynaPoly_Init(globalCtx, &colCtx->dyna); DynaPoly_Alloc(globalCtx, &colCtx->dyna); } -#else -void BgCheck_Allocate(CollisionContext* colCtx, GlobalContext* globalCtx, CollisionHeader* colHeader); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_Allocate.s") -#endif /** * Enables CollisionContext wide flags @@ -2182,7 +2155,6 @@ s32 BgCheck_EntityCheckCeiling(CollisionContext* colCtx, f32* outY, Vec3f* pos, return BgCheck_CheckCeilingImpl(colCtx, COLPOLY_IGNORE_ENTITY, outY, pos, checkHeight, outPoly, outBgId, actor); } -#ifdef NON_MATCHING /** * Tests if a line from `posA` to `posB` intersects with a poly * returns true if it does, else false @@ -2202,12 +2174,9 @@ s32 BgCheck_CheckLineImpl(CollisionContext* colCtx, u16 xpFlags1, u16 xpFlags2, StaticLineTest checkLine; Vec3f sectorMin; Vec3f sectorMax; - s32 k; + s32 temp_lo; StaticLookup* lookup; s32 j; - StaticLookup* jLookup; - s32 temp_lo; - s32 pad[2]; lookupTbl = colCtx->lookupTbl; posBTemp = *posB; @@ -2247,11 +2216,15 @@ s32 BgCheck_CheckLineImpl(CollisionContext* colCtx, u16 xpFlags1, u16 xpFlags2, sectorMax.z = colCtx->subdivLength.z + sectorMin.z; for (i = subdivMin[2]; i < subdivMax[2] + 1; i++) { - jLookup = iLookup + subdivMin[1] * colCtx->subdivAmount.x; + StaticLookup* jLookup = iLookup + subdivMin[1] * colCtx->subdivAmount.x; + s32 pad; + sectorMin.y = subdivMin[1] * colCtx->subdivLength.y + colCtx->minBounds.y; sectorMax.y = colCtx->subdivLength.y + sectorMin.y; for (j = subdivMin[1]; j < subdivMax[1] + 1; j++) { + s32 k; + lookup = jLookup + subdivMin[0]; sectorMin.x = subdivMin[0] * colCtx->subdivLength.x + colCtx->minBounds.x; sectorMax.x = colCtx->subdivLength.x + sectorMin.x; @@ -2292,9 +2265,6 @@ s32 BgCheck_CheckLineImpl(CollisionContext* colCtx, u16 xpFlags1, u16 xpFlags2, } return result; } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_CheckLineImpl.s") -#endif /** * Get bccFlags @@ -3373,8 +3343,6 @@ f32 BgCheck_RaycastFloorDyna(DynaRaycast* dynaRaycast) { #pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_RaycastFloorDyna.s") #endif -#ifdef NON_MATCHING -// regalloc, minor instruction ordering /** * Performs collision detection on a BgActor's wall polys on sphere `pos`, `radius` * returns true if a collision was detected @@ -3401,8 +3369,6 @@ s32 BgCheck_SphVsDynaWallInBgActor(CollisionContext* colCtx, u16 xpFlags, DynaCo f32 invNormalXZ; f32 planeDist; f32 temp_f18; - f32 zIntersectDist; - f32 xIntersectDist; f32 zMin; f32 zMax; f32 xMin; @@ -3472,6 +3438,8 @@ s32 BgCheck_SphVsDynaWallInBgActor(CollisionContext* colCtx, u16 xpFlags, DynaCo } } if (CollisionPoly_CheckZIntersectApprox(poly, dyna->vtxList, resultPos.x, pos->y, &intersect)) { + s32 pad; + if (fabsf(intersect - resultPos.z) <= radius / temp_f18) { if ((intersect - resultPos.z) * nz <= 4.0f) { if (BgCheck_ComputeWallDisplacement(colCtx, poly, &resultPos.x, &resultPos.z, nx, ny, nz, @@ -3547,7 +3515,8 @@ s32 BgCheck_SphVsDynaWallInBgActor(CollisionContext* colCtx, u16 xpFlags, DynaCo } if (CollisionPoly_CheckXIntersectApprox(poly, dyna->vtxList, pos->y, resultPos.z, &intersect)) { - xIntersectDist = intersect - resultPos.x; + f32 xIntersectDist = intersect - resultPos.x; + if (fabsf(xIntersectDist) <= radius / temp_f18) { if (xIntersectDist * nx <= 4.0f) { if (BgCheck_ComputeWallDisplacement(colCtx, poly, &resultPos.x, &resultPos.z, nx, ny, nz, @@ -3567,12 +3536,6 @@ s32 BgCheck_SphVsDynaWallInBgActor(CollisionContext* colCtx, u16 xpFlags, DynaCo *outZ = resultPos.z; return result; } -#else -s32 BgCheck_SphVsDynaWallInBgActor(CollisionContext* colCtx, u16 xpFlags, DynaCollisionContext* dyna, SSList* ssList, - f32* outX, f32* outZ, CollisionPoly** outPoly, s32* outBgId, Vec3f* pos, f32 radius, - s32 bgId, Actor* actor); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_bgcheck/BgCheck_SphVsDynaWallInBgActor.s") -#endif /** * Performs collision detection on all dyna poly walls using sphere `pos`, `radius` diff --git a/src/code/z_collision_check.c b/src/code/z_collision_check.c index e11e6cbd7..44885d6c7 100644 --- a/src/code/z_collision_check.c +++ b/src/code/z_collision_check.c @@ -27,12 +27,12 @@ Vec3f D_801EE1C0; Vec3f D_801EE1D0; Vec3f D_801EE1E0; Vec3f D_801EE1F0; -EffSparkParams D_801EE200; +EffectSparkInit D_801EE200; TriNorm D_801EE6C8; TriNorm D_801EE700; -EffSparkParams D_801EE738; -EffSparkParams D_801EEC00; -EffSparkParams D_801EF0C8; +EffectSparkInit D_801EE738; +EffectSparkInit D_801EEC00; +EffectSparkInit D_801EF0C8; TriNorm D_801EF590; TriNorm D_801EF5C8; TriNorm D_801EF600; @@ -1382,14 +1382,14 @@ void CollisionCheck_NoBlood(GlobalContext* globalCtx, Collider* collider, Vec3f* #ifdef NON_MATCHING // needs in-function static bss void CollisionCheck_BlueBlood(GlobalContext* globalCtx, Collider* collider, Vec3f* v) { - static EffSparkParams D_801EEC00; + static EffectSparkInit D_801EEC00; s32 effectIndex; D_801EEC00.position.x = v->x; D_801EEC00.position.x = v->y; D_801EEC00.position.x = v->z; - D_801EEC00.particleFactor1 = 5; - D_801EEC00.particleFactor2 = 5; + D_801EEC00.uDiv = 5; + D_801EEC00.vDiv = 5; D_801EEC00.colorStart[0].r = 10; D_801EEC00.colorStart[0].g = 10; D_801EEC00.colorStart[0].b = 200; @@ -1422,12 +1422,12 @@ void CollisionCheck_BlueBlood(GlobalContext* globalCtx, Collider* collider, Vec3 D_801EEC00.colorEnd[3].g = 0; D_801EEC00.colorEnd[3].b = 64; D_801EEC00.colorEnd[3].a = 0; - D_801EEC00.age = 0; + D_801EEC00.timer = 0; D_801EEC00.duration = 16; - D_801EEC00.velocity = 8.0f; + D_801EEC00.speed = 8.0f; D_801EEC00.gravity = -1.0f; - Effect_Add(globalCtx, &effectIndex, 0, 0, 1, &D_801EEC00); + Effect_Add(globalCtx, &effectIndex, EFFECT_SPARK, 0, 1, &D_801EEC00); } #else #pragma GLOBAL_ASM("asm/non_matchings/code/z_collision_check/CollisionCheck_BlueBlood.s") @@ -1440,14 +1440,14 @@ void CollisionCheck_BlueBlood(GlobalContext* globalCtx, Collider* collider, Vec3 #ifdef NON_MATCHING // needs in-function static bss void CollisionCheck_GreenBlood(GlobalContext* globalCtx, Collider* collider, Vec3f* v) { - static EffSparkParams D_801EF0C8; + static EffectSparkInit D_801EF0C8; s32 effectIndex; D_801EF0C8.position.x = v->x; D_801EF0C8.position.x = v->y; D_801EF0C8.position.x = v->z; - D_801EF0C8.particleFactor1 = 5; - D_801EF0C8.particleFactor2 = 5; + D_801EF0C8.uDiv = 5; + D_801EF0C8.vDiv = 5; D_801EF0C8.colorStart[0].r = 10; D_801EF0C8.colorStart[0].g = 200; D_801EF0C8.colorStart[0].b = 10; @@ -1480,11 +1480,11 @@ void CollisionCheck_GreenBlood(GlobalContext* globalCtx, Collider* collider, Vec D_801EF0C8.colorEnd[3].g = 64; D_801EF0C8.colorEnd[3].b = 0; D_801EF0C8.colorEnd[3].a = 0; - D_801EF0C8.age = 0; + D_801EF0C8.timer = 0; D_801EF0C8.duration = 16; - D_801EF0C8.velocity = 8.0f; + D_801EF0C8.speed = 8.0f; D_801EF0C8.gravity = -1.0f; - Effect_Add(globalCtx, &effectIndex, 0, 0, 1, &D_801EF0C8); + Effect_Add(globalCtx, &effectIndex, EFFECT_SPARK, 0, 1, &D_801EF0C8); } #else #pragma GLOBAL_ASM("asm/non_matchings/code/z_collision_check/CollisionCheck_GreenBlood.s") @@ -3751,14 +3751,14 @@ void Collider_UpdateSphere(s32 limb, ColliderSphere* collider) { #ifdef NON_MATCHING // needs in-function static bss void CollisionCheck_SpawnRedBlood(GlobalContext* globalCtx, Vec3f* v) { - static EffSparkParams D_801EE200; + static EffectSparkInit D_801EE200; s32 effectIndex; D_801EE200.position.x = v->x; D_801EE200.position.x = v->y; D_801EE200.position.x = v->z; - D_801EE200.particleFactor1 = 5; - D_801EE200.particleFactor2 = 5; + D_801EE200.uDiv = 5; + D_801EE200.vDiv = 5; D_801EE200.colorStart[0].r = 128; D_801EE200.colorStart[0].g = 0; D_801EE200.colorStart[0].b = 64; @@ -3791,12 +3791,12 @@ void CollisionCheck_SpawnRedBlood(GlobalContext* globalCtx, Vec3f* v) { D_801EE200.colorEnd[3].g = 0; D_801EE200.colorEnd[3].b = 64; D_801EE200.colorEnd[3].a = 0; - D_801EE200.age = 0; + D_801EE200.timer = 0; D_801EE200.duration = 16; - D_801EE200.velocity = 8.0f; + D_801EE200.speed = 8.0f; D_801EE200.gravity = -1.0f; - Effect_Add(globalCtx, &effectIndex, 0, 0, 1, &D_801EE200); + Effect_Add(globalCtx, &effectIndex, EFFECT_SPARK, 0, 1, &D_801EE200); } #else #pragma GLOBAL_ASM("asm/non_matchings/code/z_collision_check/CollisionCheck_SpawnRedBlood.s") @@ -3809,14 +3809,14 @@ void CollisionCheck_SpawnRedBlood(GlobalContext* globalCtx, Vec3f* v) { #ifdef NON_MATCHING // needs in-function static bss void CollisionCheck_SpawnWaterDroplets(GlobalContext* globalCtx, Vec3f* v) { - static EffSparkParams D_801EE738; + static EffectSparkInit D_801EE738; s32 effectIndex; D_801EE738.position.x = v->x; D_801EE738.position.x = v->y; D_801EE738.position.x = v->z; - D_801EE738.particleFactor1 = 5; - D_801EE738.particleFactor2 = 5; + D_801EE738.uDiv = 5; + D_801EE738.vDiv = 5; D_801EE738.colorStart[0].r = 255; D_801EE738.colorStart[0].g = 255; D_801EE738.colorStart[0].b = 255; @@ -3849,12 +3849,12 @@ void CollisionCheck_SpawnWaterDroplets(GlobalContext* globalCtx, Vec3f* v) { D_801EE738.colorEnd[3].g = 0; D_801EE738.colorEnd[3].b = 0; D_801EE738.colorEnd[3].a = 0; - D_801EE738.age = 0; + D_801EE738.timer = 0; D_801EE738.duration = 16; - D_801EE738.velocity = 8.0f; + D_801EE738.speed = 8.0f; D_801EE738.gravity = -1.0f; - Effect_Add(globalCtx, &effectIndex, 0, 0, 1, &D_801EE738); + Effect_Add(globalCtx, &effectIndex, EFFECT_SPARK, 0, 1, &D_801EE738); } #else #pragma GLOBAL_ASM("asm/non_matchings/code/z_collision_check/CollisionCheck_SpawnWaterDroplets.s") @@ -3864,7 +3864,7 @@ void CollisionCheck_SpawnWaterDroplets(GlobalContext* globalCtx, Vec3f* v) { * Spawns streaks of light from hits against solid objects */ void CollisionCheck_SpawnShieldParticles(GlobalContext* globalCtx, Vec3f* v) { - static EffShieldParticleInit shieldParticleInitMetal = { + static EffectShieldParticleInit shieldParticleInitMetal = { 16, { 0, 0, 0 }, { 0, 200, 255, 255 }, @@ -3889,7 +3889,7 @@ void CollisionCheck_SpawnShieldParticles(GlobalContext* globalCtx, Vec3f* v) { shieldParticleInitMetal.lightPoint.y = shieldParticleInitMetal.position.y; shieldParticleInitMetal.lightPoint.z = shieldParticleInitMetal.position.z; - Effect_Add(globalCtx, &effectIndex, 3, 0, 1, &shieldParticleInitMetal); + Effect_Add(globalCtx, &effectIndex, EFFECT_SHIELD_PARTICLE, 0, 1, &shieldParticleInitMetal); } /** @@ -3919,7 +3919,7 @@ void CollisionCheck_SpawnShieldParticlesMetal2(GlobalContext* globalCtx, Vec3f* * Spawns streaks of light and makes a wooden sound */ void CollisionCheck_SpawnShieldParticlesWood(GlobalContext* globalCtx, Vec3f* v, Vec3f* pos) { - static EffShieldParticleInit shieldParticleInitWood = { + static EffectShieldParticleInit shieldParticleInitWood = { 16, { 0, 0, 0 }, { 0, 200, 255, 255 }, @@ -3944,7 +3944,7 @@ void CollisionCheck_SpawnShieldParticlesWood(GlobalContext* globalCtx, Vec3f* v, shieldParticleInitWood.lightPoint.y = shieldParticleInitWood.position.y; shieldParticleInitWood.lightPoint.z = shieldParticleInitWood.position.z; - Effect_Add(globalCtx, &effectIndex, 3, 0, 1, &shieldParticleInitWood); + Effect_Add(globalCtx, &effectIndex, EFFECT_SHIELD_PARTICLE, 0, 1, &shieldParticleInitWood); func_8019F1C0(pos, NA_SE_IT_REFLECTION_WOOD); } diff --git a/src/code/z_debug_display.c b/src/code/z_debug_display.c index 2fe6b7977..ab3478fa1 100644 --- a/src/code/z_debug_display.c +++ b/src/code/z_debug_display.c @@ -68,10 +68,10 @@ void DebugDisplay_DrawSpriteI8(DebugDispObject* dispObj, void* texture, GlobalCo func_8012C6FC(globalCtx->state.gfxCtx); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, dispObj->color.r, dispObj->color.g, dispObj->color.b, dispObj->color.a); - Matrix_InsertTranslation(dispObj->pos.x, dispObj->pos.y, dispObj->pos.z, 0); - Matrix_Scale(dispObj->scale.x, dispObj->scale.y, dispObj->scale.z, 1); - Matrix_InsertMatrix(&globalCtx->mf_187FC, 1); - Matrix_InsertRotation(dispObj->rot.x, dispObj->rot.y, dispObj->rot.z, 1); + Matrix_InsertTranslation(dispObj->pos.x, dispObj->pos.y, dispObj->pos.z, MTXMODE_NEW); + Matrix_Scale(dispObj->scale.x, dispObj->scale.y, dispObj->scale.z, MTXMODE_APPLY); + Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_APPLY); + Matrix_InsertRotation(dispObj->rot.x, dispObj->rot.y, dispObj->rot.z, MTXMODE_APPLY); gDPLoadTextureBlock(POLY_XLU_DISP++, texture, G_IM_FMT_I, G_IM_SIZ_8b, 16, 16, 0, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMASK, G_TX_NOMASK, G_TX_NOLOD, G_TX_NOLOD); @@ -95,7 +95,7 @@ void DebugDisplay_DrawPolygon(DebugDispObject* dispObj, void* arg1, GlobalContex gSPSetLights1(POLY_XLU_DISP++, sDebugDisplayLight1); Matrix_SetStateRotationAndTranslation(dispObj->pos.x, dispObj->pos.y, dispObj->pos.z, &dispObj->rot); - Matrix_Scale(dispObj->scale.x, dispObj->scale.y, dispObj->scale.z, 1); + Matrix_Scale(dispObj->scale.x, dispObj->scale.y, dispObj->scale.z, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, arg1); @@ -116,7 +116,7 @@ void func_800E992C(GlobalContext* globalCtx, s32 arg1) { OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C560(globalCtx->state.gfxCtx); - gSPMatrix(POLY_XLU_DISP++, &D_801D1DE0, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPMatrix(POLY_XLU_DISP++, &gIdentityMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, func_800E99B0(globalCtx->state.gfxCtx, arg1)); CLOSE_DISPS(globalCtx->state.gfxCtx); diff --git a/src/code/z_eff_blure.c b/src/code/z_eff_blure.c index 17685de15..887534366 100644 --- a/src/code/z_eff_blure.c +++ b/src/code/z_eff_blure.c @@ -1,27 +1,18 @@ #include "global.h" -#ifdef NON_MATCHING -void func_800A81F0(EffectBlure* this, Vec3f* p1, Vec3f* p2) { +void EffectBlure_AddVertex(EffectBlure* this, Vec3f* p1, Vec3f* p2) { EffectBlureElement* elem; s32 numElements; - Vec3f sp16C; - Vec3f sp160; - Vec3f sp154; - f32 scale; - MtxF sp110; - MtxF spD0; - MtxF sp90; - MtxF sp50; - Vec3f sp44; - Vec3f sp38; + + if (this) {} + if (this) {} if (this != NULL) { - numElements = this->numElements; - if (numElements >= 16) { + if (this->numElements >= ARRAY_COUNT(this->elements)) { return; } - elem = &this->elements[numElements]; + elem = &this->elements[this->numElements]; elem->state = 1; if (!(this->flags & 2)) { @@ -32,6 +23,17 @@ void func_800A81F0(EffectBlure* this, Vec3f* p1, Vec3f* p2) { elem->p2.y = p2->y; elem->p2.z = p2->z; } 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.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; @@ -41,7 +43,7 @@ void func_800A81F0(EffectBlure* this, Vec3f* p1, Vec3f* p2) { Math_Vec3f_Diff(&sp160, &sp16C, &sp154); scale = Math3D_Vec3fMagnitude(&sp154); - if (!(fabsf(scale) < D_801DC080)) { + if (!(fabsf(scale) < 0.008f)) { scale = 1.0f / scale; Math_Vec3f_Scale(&sp154, scale); @@ -66,40 +68,977 @@ void func_800A81F0(EffectBlure* this, Vec3f* p1, Vec3f* p2) { this->numElements++; } } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_blure/func_800A81F0.s") -#endif -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_blure/func_800A8514.s") +void EffectBlure_AddSpace(EffectBlure* this) { + EffectBlureElement* elem; + s32 numElements; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_blure/EffectBlure_Initcommon.s") + if (this != NULL) { + numElements = this->numElements; + if (numElements >= ARRAY_COUNT(this->elements)) { + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_blure/EffectBlure_Init1.s") + elem = &this->elements[numElements]; + elem->state = 0; + elem->timer = 1; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_blure/EffectBlure_Init2.s") + this->numElements++; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_blure/EffectBlure_Destroy.s") +void EffectBlure_InitElements(EffectBlure* this) { + EffectBlureElement* elem; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_blure/EffectBlure_Update.s") + this->numElements = 0; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_blure/func_800A8C78.s") + for (i = 0; i < ARRAY_COUNT(this->elements); i++) { + elem = &this->elements[i]; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_blure/func_800A8DE8.s") + elem->state = 2; + elem->p1.x = 0; + elem->p1.y = 0; + elem->p1.z = 0; + elem->p2.x = 0; + elem->p2.y = 0; + elem->p2.z = 0; + elem->timer = 0; + elem->flags = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_blure/func_800A92FC.s") +void EffectBlure_Init1(void* thisx, void* initParamsx) { + EffectBlure* this = (EffectBlure*)thisx; + EffectBlureInit1* initParams = (EffectBlureInit1*)initParamsx; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_blure/func_800A9330.s") + if ((this != NULL) && (initParams != NULL)) { + EffectBlure_InitElements(this); + this->p1StartColor.r = initParams->p1StartColor[0]; + this->p2StartColor.r = initParams->p2StartColor[0]; + this->p1EndColor.r = initParams->p1EndColor[0]; + this->p2EndColor.r = initParams->p2EndColor[0]; + this->p1StartColor.g = initParams->p1StartColor[1]; + this->p2StartColor.g = initParams->p2StartColor[1]; + this->p1EndColor.g = initParams->p1EndColor[1]; + this->p2EndColor.g = initParams->p2EndColor[1]; + this->p1StartColor.b = initParams->p1StartColor[2]; + this->p2StartColor.b = initParams->p2StartColor[2]; + this->p1EndColor.b = initParams->p1EndColor[2]; + this->p2EndColor.b = initParams->p2EndColor[2]; + this->p1StartColor.a = initParams->p1StartColor[3]; + this->p2StartColor.a = initParams->p2StartColor[3]; + this->p1EndColor.a = initParams->p1EndColor[3]; + this->p2EndColor.a = initParams->p2EndColor[3]; + this->elemDuration = initParams->elemDuration; + this->unkFlag = initParams->unkFlag; + this->calcMode = initParams->calcMode; + this->flags = 0; + this->addAngleChange = 0; + this->addAngle = 0; + this->drawMode = 0; + this->altPrimColor.r = 0; + this->altPrimColor.g = 0; + this->altPrimColor.b = 0; + this->altPrimColor.a = 0; + this->altEnvColor.r = 0; + this->altEnvColor.g = 0; + this->altEnvColor.b = 0; + this->altEnvColor.a = 0; + this->mode4Param = 1.0f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_blure/func_800A9804.s") +void EffectBlure_Init2(void* thisx, void* initParamsx) { + EffectBlure* this = (EffectBlure*)thisx; + EffectBlureInit2* initParams = (EffectBlureInit2*)initParamsx; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_blure/func_800AA190.s") + if ((this != NULL) && (initParams != NULL)) { + EffectBlure_InitElements(this); + this->p1StartColor.r = initParams->p1StartColor[0]; + this->p2StartColor.r = initParams->p2StartColor[0]; + this->p1EndColor.r = initParams->p1EndColor[0]; + this->p2EndColor.r = initParams->p2EndColor[0]; + this->p1StartColor.g = initParams->p1StartColor[1]; + this->p2StartColor.g = initParams->p2StartColor[1]; + this->p1EndColor.g = initParams->p1EndColor[1]; + this->p2EndColor.g = initParams->p2EndColor[1]; + this->p1StartColor.b = initParams->p1StartColor[2]; + this->p2StartColor.b = initParams->p2StartColor[2]; + this->p1EndColor.b = initParams->p1EndColor[2]; + this->p2EndColor.b = initParams->p2EndColor[2]; + this->p1StartColor.a = initParams->p1StartColor[3]; + this->p2StartColor.a = initParams->p2StartColor[3]; + this->p1EndColor.a = initParams->p1EndColor[3]; + this->p2EndColor.a = initParams->p2EndColor[3]; + this->elemDuration = initParams->elemDuration; + this->unkFlag = initParams->unkFlag; + this->calcMode = initParams->calcMode; + this->flags = initParams->flags; + this->drawMode = initParams->drawMode; + this->addAngleChange = initParams->addAngleChange; + this->addAngle = 0; + this->mode4Param = initParams->mode4Param; + this->altPrimColor = initParams->altPrimColor; + this->altEnvColor = initParams->altEnvColor; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_blure/func_800AA460.s") +void EffectBlure_Destroy(void* thisx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_blure/func_800AA498.s") +s32 EffectBlure_Update(void* thisx) { + EffectBlure* this = (EffectBlure*)thisx; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_blure/func_800AA700.s") + if (this == NULL) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_blure/func_800AABE0.s") + if (this->numElements == 0) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_blure/EffectBlure_Draw.s") + while (true) { + if (this->elements[0].state == 0) { + for (i = 0; i < ARRAY_COUNT(this->elements) - 1; i++) { + this->elements[i] = this->elements[i + 1]; + } + + this->elements[i].state = 2; + this->elements[i].p1.x = 0; + this->elements[i].p1.y = 0; + this->elements[i].p1.z = 0; + this->elements[i].p2.x = 0; + this->elements[i].p2.y = 0; + this->elements[i].p2.z = 0; + this->elements[i].flags = 0; + this->elements[i].timer = 0; + + this->numElements--; + if (this->numElements <= 0) { + this->numElements = 0; + return 0; + } + } else { + break; + } + } + + if (this->elements[0].state == 2) { + return 0; + } + + for (i = 0; i < this->numElements; i++) { + this->elements[i].timer++; + } + + if (this->elemDuration < this->elements[0].timer) { + for (i = 0; i < ARRAY_COUNT(this->elements) - 1; i++) { + this->elements[i] = this->elements[i + 1]; + if (this->elements[i].timer >= this->elemDuration) { + this->elements[i].timer = this->elemDuration; + } + } + + this->elements[i].state = 2; + this->elements[i].p1.x = 0; + this->elements[i].p1.y = 0; + this->elements[i].p1.z = 0; + this->elements[i].p2.x = 0; + this->elements[i].p2.y = 0; + this->elements[i].p2.z = 0; + this->elements[i].flags = 0; + this->elements[i].timer = 0; + + this->numElements--; + if (this->numElements <= 0) { + this->numElements = 0; + return 0; + } + return 0; + } + + for (i = 0; i < this->numElements; i++) { + if (this->elements[i].timer >= this->elemDuration) { + this->elements[i].timer = this->elemDuration; + } + } + + this->addAngle += this->addAngleChange; + return 0; +} + +void EffectBlure_UpdateFlags(EffectBlureElement* elem) { + Vec3f sp64; + Vec3f sp58; + Vec3f sp4C; + Vec3f sp40; + EffectBlureElement* prev = elem - 1; + EffectBlureElement* next = elem + 1; + f32 sp34; + f32 sp30; + f32 sp2C; + + 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(&sp58, &elem->p2, &prev->p2); + Math_Vec3s_DiffToVec3f(&sp4C, &next->p1, &elem->p1); + Math_Vec3s_DiffToVec3f(&sp40, &next->p2, &elem->p2); + + if (Math3D_AngleBetweenVectors(&sp64, &sp4C, &sp34) || Math3D_AngleBetweenVectors(&sp58, &sp40, &sp30) || + Math3D_AngleBetweenVectors(&sp4C, &sp40, &sp2C)) { + elem->flags &= ~3; + elem->flags |= 0; + } else if ((sp34 <= -0.5f) || (sp30 <= -0.5f) || (sp2C <= 0.7071f)) { + elem->flags &= ~3; + elem->flags |= 0; + } else { + elem->flags &= ~3; + elem->flags |= 1; + } + } +} + +void EffectBlure_GetComputedValues(EffectBlure* this, s32 index, f32 ratio, Vec3s* vec1, Vec3s* vec2, + Color_RGBA8* color1, Color_RGBA8* color2) { + Vec3s sp30; + f32 mode4Param; + EffectBlureElement* elem = &this->elements[index]; + + switch (this->calcMode) { + case 1: + vec1->x = func_800B09D0(elem->p1.x, elem->p2.x, ratio); + vec1->y = func_800B09D0(elem->p1.y, elem->p2.y, ratio); + vec1->z = func_800B09D0(elem->p1.z, elem->p2.z, ratio); + vec2->x = elem->p2.x; + vec2->y = elem->p2.y; + vec2->z = elem->p2.z; + break; + + case 2: + vec1->x = elem->p1.x; + vec1->y = elem->p1.y; + vec1->z = elem->p1.z; + vec2->x = func_800B09D0(elem->p2.x, elem->p1.x, ratio); + vec2->y = func_800B09D0(elem->p2.y, elem->p1.y, ratio); + vec2->z = func_800B09D0(elem->p2.z, elem->p1.z, ratio); + break; + + case 3: + ratio *= 0.5f; + vec1->x = func_800B09D0(elem->p1.x, elem->p2.x, ratio); + vec1->y = func_800B09D0(elem->p1.y, elem->p2.y, ratio); + vec1->z = func_800B09D0(elem->p1.z, elem->p2.z, ratio); + vec2->x = func_800B09D0(elem->p2.x, elem->p1.x, ratio); + vec2->y = func_800B09D0(elem->p2.y, elem->p1.y, ratio); + vec2->z = func_800B09D0(elem->p2.z, elem->p1.z, ratio); + ratio *= 2.0f; + break; + + case 4: + sp30.x = elem->p1.x - elem->p2.x; + sp30.y = elem->p1.y - elem->p2.y; + sp30.z = elem->p1.z - elem->p2.z; + mode4Param = this->mode4Param - 1.0f; + + vec1->x = (sp30.x * 0.5f * mode4Param * ratio) + elem->p1.x; + vec1->y = (sp30.y * 0.5f * mode4Param * ratio) + elem->p1.y; + if (1) {} // Necessary to match + vec1->z = (sp30.z * 0.5f * mode4Param * ratio) + elem->p1.z; + + vec2->x = -(sp30.x * 0.5f * mode4Param * ratio) + elem->p2.x; + vec2->y = -(sp30.y * 0.5f * mode4Param * ratio) + elem->p2.y; + vec2->z = -(sp30.z * 0.5f * mode4Param * ratio) + elem->p2.z; + break; + + case 0: + default: + vec1->x = elem->p1.x; + vec1->y = elem->p1.y; + vec1->z = elem->p1.z; + vec2->x = elem->p2.x; + vec2->y = elem->p2.y; + vec2->z = elem->p2.z; + break; + } + + sp30 = sp30; // Optimized out but seems necessary to match stack usage + + if (this->flags & 0x10) { + color1->r = color1->g = color1->b = color1->a = 255; + color2->r = color2->g = color2->b = color2->a = 255; + } else { + color1->r = func_800B0A24(this->p1StartColor.r, this->p1EndColor.r, ratio); + color1->g = func_800B0A24(this->p1StartColor.g, this->p1EndColor.g, ratio); + color1->b = func_800B0A24(this->p1StartColor.b, this->p1EndColor.b, ratio); + color1->a = func_800B0A24(this->p1StartColor.a, this->p1EndColor.a, ratio); + color2->r = func_800B0A24(this->p2StartColor.r, this->p2EndColor.r, ratio); + color2->g = func_800B0A24(this->p2StartColor.g, this->p2EndColor.g, ratio); + color2->b = func_800B0A24(this->p2StartColor.b, this->p2EndColor.b, ratio); + color2->a = func_800B0A24(this->p2StartColor.a, this->p2EndColor.a, ratio); + } +} + +void EffectBlure_SetupSmooth(EffectBlure* this, GraphicsContext* gfxCtx) { + OPEN_DISPS(gfxCtx); + + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0x26); + + CLOSE_DISPS(gfxCtx); +} + +void EffectBlure_DrawElemNoInterpolation(EffectBlure* this, EffectBlureElement* elem, s32 index, + GraphicsContext* gfxCtx) { + static Vtx_t baseVtx = VTX_T(0, 0, 0, 0, 0, 255, 255, 255, 255); + Vtx* vtx; + Vec3s sp8C; + Vec3s sp84; + f32 ratio; + Color_RGBA8 sp7C; + Color_RGBA8 sp78; + Vec3f sp6C; + Vec3f sp60; + Vec3f sp54; + + OPEN_DISPS(gfxCtx); + + Math_Vec3s_ToVec3f(&sp6C, &this->elements[0].p2); + + vtx = GRAPH_ALLOC(gfxCtx, sizeof(Vtx[4])); + if (vtx == NULL) { + } else { + vtx[0].v = baseVtx; + vtx[1].v = baseVtx; + vtx[2].v = baseVtx; + vtx[3].v = baseVtx; + + ratio = (f32)elem->timer / (f32)this->elemDuration; + EffectBlure_GetComputedValues(this, index, ratio, &sp8C, &sp84, &sp7C, &sp78); + + sp60.x = sp84.x; + sp60.y = sp84.y; + sp60.z = sp84.z; + Math_Vec3f_Diff(&sp60, &sp6C, &sp54); + Math_Vec3f_Scale(&sp54, 10.0f); + vtx[0].v.ob[0] = sp54.x; + vtx[0].v.ob[1] = sp54.y; + vtx[0].v.ob[2] = sp54.z; + vtx[0].v.cn[0] = sp78.r; + vtx[0].v.cn[1] = sp78.g; + vtx[0].v.cn[2] = sp78.b; + vtx[0].v.cn[3] = sp78.a; + + sp60.x = sp8C.x; + sp60.y = sp8C.y; + sp60.z = sp8C.z; + Math_Vec3f_Diff(&sp60, &sp6C, &sp54); + Math_Vec3f_Scale(&sp54, 10.0f); + vtx[1].v.ob[0] = sp54.x; + vtx[1].v.ob[1] = sp54.y; + vtx[1].v.ob[2] = sp54.z; + vtx[1].v.cn[0] = sp7C.r; + vtx[1].v.cn[1] = sp7C.g; + vtx[1].v.cn[2] = sp7C.b; + vtx[1].v.cn[3] = sp7C.a; + + ratio = (f32)(elem + 1)->timer / (f32)this->elemDuration; + EffectBlure_GetComputedValues(this, index + 1, ratio, &sp8C, &sp84, &sp7C, &sp78); + + sp60.x = sp8C.x; + sp60.y = sp8C.y; + sp60.z = sp8C.z; + Math_Vec3f_Diff(&sp60, &sp6C, &sp54); + Math_Vec3f_Scale(&sp54, 10.0f); + vtx[2].v.ob[0] = sp54.x; + vtx[2].v.ob[1] = sp54.y; + vtx[2].v.ob[2] = sp54.z; + vtx[2].v.cn[0] = sp7C.r; + vtx[2].v.cn[1] = sp7C.g; + vtx[2].v.cn[2] = sp7C.b; + vtx[2].v.cn[3] = sp7C.a; + + sp60.x = sp84.x; + sp60.y = sp84.y; + sp60.z = sp84.z; + Math_Vec3f_Diff(&sp60, &sp6C, &sp54); + Math_Vec3f_Scale(&sp54, 10.0f); + vtx[3].v.ob[0] = sp54.x; + vtx[3].v.ob[1] = sp54.y; + vtx[3].v.ob[2] = sp54.z; + vtx[3].v.cn[0] = sp78.r; + vtx[3].v.cn[1] = sp78.g; + vtx[3].v.cn[2] = sp78.b; + vtx[3].v.cn[3] = sp78.a; + + gSPVertex(POLY_XLU_DISP++, vtx, 4, 0); + gSP2Triangles(POLY_XLU_DISP++, 0, 1, 2, 0, 0, 2, 3, 0); + } + + CLOSE_DISPS(gfxCtx); +} + +void EffectBlure_DrawElemHermiteInterpolation(EffectBlure* this, EffectBlureElement* elem, s32 index, + GraphicsContext* gfxCtx) { + static Vtx_t baseVtx = VTX_T(0, 0, 0, 0, 0, 255, 255, 255, 255); + Vtx* vtx; + Vec3s sp1EC; + Vec3s sp1E4; + f32 ratio; + Color_RGBA8 sp1DC; + Color_RGBA8 sp1D8; + Vec3f sp1CC; + Vec3f sp1C0; + Vec3f sp1B4; + Vec3f sp1A8; + Color_RGBA8 sp1A4; + Color_RGBA8 sp1A0; + Color_RGBA8 sp19C; + Color_RGBA8 sp198; + Vec3f sp18C; + Vec3f sp180; + Vec3f sp174; + Vec3f sp168; + s32 i; + Vec3f sp158; + Vec3f sp14C; + Color_RGBA8 sp148; + Color_RGBA8 sp144; + Vec3f sp138; + + OPEN_DISPS(gfxCtx); + + Math_Vec3s_ToVec3f(&sp138, &this->elements[0].p2); + + ratio = (f32)elem->timer / (f32)this->elemDuration; + EffectBlure_GetComputedValues(this, index, ratio, &sp1EC, &sp1E4, &sp1A4, &sp1A0); + Math_Vec3s_ToVec3f(&sp1CC, &sp1EC); + Math_Vec3s_ToVec3f(&sp1C0, &sp1E4); + + ratio = (f32)(elem + 1)->timer / (f32)this->elemDuration; + EffectBlure_GetComputedValues(this, index + 1, ratio, &sp1EC, &sp1E4, &sp19C, &sp198); + Math_Vec3s_ToVec3f(&sp18C, &sp1EC); + Math_Vec3s_ToVec3f(&sp180, &sp1E4); + + if ((elem->flags & 3) == 2) { + Math_Vec3f_Diff(&sp18C, &sp1CC, &sp1B4); + Math_Vec3f_Diff(&sp180, &sp1C0, &sp1A8); + } else { + Vec3f sp118; + Vec3f sp10C; + + ratio = (f32)(elem - 1)->timer / (f32)this->elemDuration; + EffectBlure_GetComputedValues(this, index - 1, ratio, &sp1EC, &sp1E4, &sp1DC, &sp1D8); + Math_Vec3s_ToVec3f(&sp118, &sp1EC); + Math_Vec3s_ToVec3f(&sp10C, &sp1E4); + Math_Vec3f_Diff(&sp18C, &sp118, &sp1B4); + Math_Vec3f_Diff(&sp180, &sp10C, &sp1A8); + } + + Math_Vec3f_Scale(&sp1B4, 0.5f); + Math_Vec3f_Scale(&sp1A8, 0.5f); + + if (((elem + 1)->flags & 3) == 2) { + Math_Vec3f_Diff(&sp18C, &sp1CC, &sp174); + Math_Vec3f_Diff(&sp180, &sp1C0, &sp168); + } else { + Vec3f sp100; + Vec3f spF4; + + ratio = (f32)(elem + 2)->timer / (f32)this->elemDuration; + EffectBlure_GetComputedValues(this, index + 2, ratio, &sp1EC, &sp1E4, &sp1DC, &sp1D8); + Math_Vec3s_ToVec3f(&sp100, &sp1EC); + Math_Vec3s_ToVec3f(&spF4, &sp1E4); + Math_Vec3f_Diff(&sp100, &sp1CC, &sp174); + Math_Vec3f_Diff(&spF4, &sp1C0, &sp168); + } + + Math_Vec3f_Scale(&sp174, 0.5f); + Math_Vec3f_Scale(&sp168, 0.5f); + + vtx = GRAPH_ALLOC(gfxCtx, sizeof(Vtx[16])); + if (vtx == NULL) { + } else { + Math_Vec3f_Diff(&sp1CC, &sp138, &sp158); + Math_Vec3f_Scale(&sp158, 10.0f); + Math_Vec3f_Diff(&sp1C0, &sp138, &sp14C); + Math_Vec3f_Scale(&sp14C, 10.0f); + + Color_RGBA8_Copy(&sp148, &sp1A4); + Color_RGBA8_Copy(&sp144, &sp1A0); + + vtx[0].v = baseVtx; + vtx[1].v = baseVtx; + + vtx[0].v.ob[0] = func_80086814(sp158.x); + vtx[0].v.ob[1] = func_80086814(sp158.y); + vtx[0].v.ob[2] = func_80086814(sp158.z); + vtx[0].v.cn[0] = sp148.r; + vtx[0].v.cn[1] = sp148.g; + vtx[0].v.cn[2] = sp148.b; + vtx[0].v.cn[3] = sp148.a; + vtx[1].v.ob[0] = func_80086814(sp14C.x); + vtx[1].v.ob[1] = func_80086814(sp14C.y); + vtx[1].v.ob[2] = func_80086814(sp14C.z); + vtx[1].v.cn[0] = sp144.r; + vtx[1].v.cn[1] = sp144.g; + vtx[1].v.cn[2] = sp144.b; + vtx[1].v.cn[3] = sp144.a; + + for (i = 1; i < 8; i++) { + s32 j1 = 2 * i; + s32 j2 = 2 * i + 1; + Vec3f spE0; + f32 temp_f28 = i / 7.0f; // t + f32 temp_f0 = SQ(temp_f28); // t^2 + f32 temp_f2 = temp_f0 * temp_f28; // t^3 + f32 temp_f20 = temp_f2 - temp_f0; // t^3 - t^2 + f32 temp_f22 = temp_f2 - 2.0f * temp_f0 + temp_f28; // t^3 - 2t^2 + t + f32 temp_f24 = 2.0f * temp_f2 - temp_f0 * 3.0f + 1.0f; // 2t^3 - 3t^2 + 1 + f32 temp_f26 = temp_f0 * 3.0f - 2.0f * temp_f2; // 3t^2 - 2t^3 + s32 pad1; + s32 pad2; + + // p = (2t^3 - 3t^2 + 1)p0 + (3t^2 - 2t^3)p1 + (t^3 - 2t^2 + t)m0 + (t^3 - t^2)m1 + spE0.x = (temp_f24 * sp1CC.x) + (temp_f26 * sp18C.x) + (temp_f22 * sp1B4.x) + (temp_f20 * sp174.x); + spE0.y = (temp_f24 * sp1CC.y) + (temp_f26 * sp18C.y) + (temp_f22 * sp1B4.y) + (temp_f20 * sp174.y); + spE0.z = (temp_f24 * sp1CC.z) + (temp_f26 * sp18C.z) + (temp_f22 * sp1B4.z) + (temp_f20 * sp174.z); + Math_Vec3f_Diff(&spE0, &sp138, &sp158); + Math_Vec3f_Scale(&sp158, 10.0f); + + spE0.x = (temp_f24 * sp1C0.x) + (temp_f26 * sp180.x) + (temp_f22 * sp1A8.x) + (temp_f20 * sp168.x); + spE0.y = (temp_f24 * sp1C0.y) + (temp_f26 * sp180.y) + (temp_f22 * sp1A8.y) + (temp_f20 * sp168.y); + spE0.z = (temp_f24 * sp1C0.z) + (temp_f26 * sp180.z) + (temp_f22 * sp1A8.z) + (temp_f20 * sp168.z); + Math_Vec3f_Diff(&spE0, &sp138, &sp14C); + Math_Vec3f_Scale(&sp14C, 10.0f); + + vtx[j1].v = baseVtx; + vtx[j2].v = baseVtx; + + vtx[j1].v.ob[0] = func_80086814(sp158.x); + vtx[j1].v.ob[1] = func_80086814(sp158.y); + vtx[j1].v.ob[2] = func_80086814(sp158.z); + vtx[j1].v.cn[0] = func_800B0A24(sp1A4.r, sp19C.r, temp_f28); + vtx[j1].v.cn[1] = func_800B0A24(sp1A4.g, sp19C.g, temp_f28); + vtx[j1].v.cn[2] = func_800B0A24(sp1A4.b, sp19C.b, temp_f28); + vtx[j1].v.cn[3] = func_800B0A24(sp1A4.a, sp19C.a, temp_f28); + + vtx[j2].v.ob[0] = func_80086814(sp14C.x); + vtx[j2].v.ob[1] = func_80086814(sp14C.y); + vtx[j2].v.ob[2] = func_80086814(sp14C.z); + vtx[j2].v.cn[0] = func_800B0A24(sp1A0.r, sp198.r, temp_f28); + vtx[j2].v.cn[1] = func_800B0A24(sp1A0.g, sp198.g, temp_f28); + vtx[j2].v.cn[2] = func_800B0A24(sp1A0.b, sp198.b, temp_f28); + vtx[j2].v.cn[3] = func_800B0A24(sp1A0.a, sp198.a, temp_f28); + } + + gSPVertex(POLY_XLU_DISP++, vtx, 16, 0); + gSP2Triangles(POLY_XLU_DISP++, 0, 1, 3, 0, 0, 3, 2, 0); + gSP2Triangles(POLY_XLU_DISP++, 2, 3, 5, 0, 2, 5, 4, 0); + gSP2Triangles(POLY_XLU_DISP++, 4, 5, 7, 0, 4, 7, 6, 0); + gSP2Triangles(POLY_XLU_DISP++, 6, 7, 9, 0, 6, 9, 8, 0); + gSP2Triangles(POLY_XLU_DISP++, 8, 9, 11, 0, 8, 11, 10, 0); + gSP2Triangles(POLY_XLU_DISP++, 10, 11, 13, 0, 10, 13, 12, 0); + gSP2Triangles(POLY_XLU_DISP++, 12, 13, 15, 0, 12, 15, 14, 0); + } + + CLOSE_DISPS(gfxCtx); +} + +void EffectBlure_DrawSmooth(EffectBlure* this2, GraphicsContext* gfxCtx) { + EffectBlure* this = this2; + EffectBlureElement* elem; + s32 i; + MtxF spDC; + MtxF sp9C; + MtxF sp5C; + Mtx* mtx; + + OPEN_DISPS(gfxCtx); + + if (this->numElements < 2) { + return; + } + + this->elements[0].flags &= ~3; + this->elements[0].flags |= 2; + + for (elem = &this->elements[1]; elem < this->elements + this->numElements - 1; elem++) { + EffectBlure_UpdateFlags(elem); + } + + this->elements[this->numElements - 1].flags &= ~3; + this->elements[this->numElements - 1].flags |= 2; + + EffectBlure_SetupSmooth(this, gfxCtx); + SkinMatrix_SetTranslate(&spDC, this->elements[0].p2.x, this->elements[0].p2.y, this->elements[0].p2.z); + SkinMatrix_SetScale(&sp9C, 0.1f, 0.1f, 0.1f); + SkinMatrix_MtxFMtxFMult(&spDC, &sp9C, &sp5C); + + mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &sp5C); + if (mtx == NULL) { + return; + } + + gSPMatrix(POLY_XLU_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + for (i = 0, elem = &this->elements[0]; elem < this->elements + this->numElements - 1; i++, elem++) { + if ((elem->state == 0) || ((elem + 1)->state == 0)) { + continue; + } + if ((((elem->flags & 3) == 0) && (((elem + 1)->flags & 3) == 0)) || + (((elem->flags & 3) == 2) && (((elem + 1)->flags & 3) == 0)) || + (((elem->flags & 3) == 0) && (((elem + 1)->flags & 3) == 2)) || + (((elem->flags & 3) == 2) && (((elem + 1)->flags & 3) == 2))) { + EffectBlure_DrawElemNoInterpolation(this, elem, i, gfxCtx); + } else { + EffectBlure_DrawElemHermiteInterpolation(this, elem, i, gfxCtx); + } + } + + CLOSE_DISPS(gfxCtx); +} + +void EffectBlure_SetupSimple(GraphicsContext* gfxCtx, EffectBlure* this, Vtx* vtx) { + OPEN_DISPS(gfxCtx); + + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0x26); + + CLOSE_DISPS(gfxCtx); +} + +void EffectBlure_SetupSimpleAlt(GraphicsContext* gfxCtx, EffectBlure* this, Vtx* vtx) { + OPEN_DISPS(gfxCtx); + + gDPPipeSync(POLY_XLU_DISP++); + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0x26); + + gDPSetCycleType(POLY_XLU_DISP++, G_CYC_2CYCLE); + gDPSetTextureLUT(POLY_XLU_DISP++, G_TT_NONE); + gSPTexture(POLY_XLU_DISP++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + + gDPLoadTextureBlock(POLY_XLU_DISP++, D_04014570, G_IM_FMT_I, G_IM_SIZ_8b, 64, 32, 0, G_TX_NOMIRROR | G_TX_CLAMP, + G_TX_NOMIRROR | G_TX_WRAP, 6, 5, G_TX_NOLOD, G_TX_NOLOD); + + gDPSetCombineLERP(POLY_XLU_DISP++, TEXEL0, PRIMITIVE, PRIM_LOD_FRAC, TEXEL0, TEXEL0, 0, PRIMITIVE, 0, PRIMITIVE, + ENVIRONMENT, COMBINED, ENVIRONMENT, 0, 0, 0, COMBINED); + gDPSetRenderMode(POLY_XLU_DISP++, G_RM_PASS, G_RM_ZB_CLD_SURF2); + gSPClearGeometryMode(POLY_XLU_DISP++, G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR); + gSPSetGeometryMode(POLY_XLU_DISP++, G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH); + gDPPipeSync(POLY_XLU_DISP++); + + gDPSetEnvColor(POLY_XLU_DISP++, this->altEnvColor.r, this->altEnvColor.g, this->altEnvColor.b, this->altEnvColor.a); + + CLOSE_DISPS(gfxCtx); +} + +void (*sSetupHandlers[])(GraphicsContext* gfxCtx, EffectBlure* this, Vtx* vtx) = { + EffectBlure_SetupSimple, + EffectBlure_SetupSimpleAlt, +}; + +s32 D_801AE268 = 0; // unused + +void EffectBlure_DrawSimpleVertices(GraphicsContext* gfxCtx, EffectBlure* this, Vtx* vtx) { + Mtx* mtx; + + OPEN_DISPS(gfxCtx); + + sSetupHandlers[this->drawMode](gfxCtx, this, vtx); + gDPPipeSync(POLY_XLU_DISP++); + + { + Vec3f sp1B0; + Vec3f sp1A4; + Vec3f sp198; + f32 alphaRatio; + MtxF sp154; + MtxF sp114; + MtxF spD4; + MtxF sp94; + f32 scale; + s32 i; + s32 j; + + j = 0; + + for (i = 0; i < this->numElements - 1; i++) { + if (this->drawMode == 1) { + alphaRatio = (f32)this->elements[i].timer / (f32)this->elemDuration; + gDPSetPrimColor(POLY_XLU_DISP++, 0x00, 0x80, this->altPrimColor.r, this->altPrimColor.g, + this->altPrimColor.b, this->altPrimColor.a * (1.0f - alphaRatio)); + gDPPipeSync(POLY_XLU_DISP++); + } + + if (1) {} // Necessary to match + + gSPVertex(POLY_XLU_DISP++, &vtx[j], 4, 0); + gSP2Triangles(POLY_XLU_DISP++, 0, 1, 3, 0, 0, 3, 2, 0); + + if (this->flags & 4) { + sp1B0.x = ((f32)vtx[4 * i + 0].v.ob[0] + (f32)vtx[4 * i + 1].v.ob[0]) * 0.5f; + sp1B0.y = ((f32)vtx[4 * i + 0].v.ob[1] + (f32)vtx[4 * i + 1].v.ob[1]) * 0.5f; + sp1B0.z = ((f32)vtx[4 * i + 0].v.ob[2] + (f32)vtx[4 * i + 1].v.ob[2]) * 0.5f; + sp1A4.x = ((f32)vtx[4 * i + 2].v.ob[0] + (f32)vtx[4 * i + 3].v.ob[0]) * 0.5f; + sp1A4.y = ((f32)vtx[4 * i + 2].v.ob[1] + (f32)vtx[4 * i + 3].v.ob[1]) * 0.5f; + sp1A4.z = ((f32)vtx[4 * i + 2].v.ob[2] + (f32)vtx[4 * i + 3].v.ob[2]) * 0.5f; + + Math_Vec3f_Diff(&sp1A4, &sp1B0, &sp198); + scale = sqrtf(SQXYZ(sp198)); + + if (fabsf(scale) > 0.0005f) { + scale = 1.0f / scale; + Math_Vec3f_Scale(&sp198, scale); + + SkinMatrix_SetTranslate(&sp154, sp1B0.x, sp1B0.y, sp1B0.z); + SkinMatrix_SetRotateAroundVec(&sp114, 0x3FFF, sp198.x, sp198.y, sp198.z); + SkinMatrix_MtxFMtxFMult(&sp154, &sp114, &spD4); + SkinMatrix_SetTranslate(&sp154, -sp1B0.x, -sp1B0.y, -sp1B0.z); + SkinMatrix_MtxFMtxFMult(&spD4, &sp154, &sp94); + + mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &sp94); + if (mtx == NULL) { + break; + } + + gSPMatrix(POLY_XLU_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPVertex(POLY_XLU_DISP++, &vtx[j], 4, 0); + gSP2Triangles(POLY_XLU_DISP++, 0, 1, 3, 0, 0, 3, 2, 0); + gSPMatrix(POLY_XLU_DISP++, &gIdentityMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + } + } + + j += 4; + } + } + + CLOSE_DISPS(gfxCtx); +} + +Vtx_t D_801AE26C[] = { + VTX_T(0, 0, 0, 0, 1024, 255, 255, 255, 255), + VTX_T(0, 0, 0, 0, 0, 255, 255, 255, 255), + VTX_T(0, 0, 0, 2048, 1024, 255, 255, 255, 255), + VTX_T(0, 0, 0, 2048, 0, 255, 255, 255, 255), +}; + +Vtx_t D_801AE2AC[] = { + VTX_T(0, 0, 0, 2048, 1024, 255, 255, 255, 255), + VTX_T(0, 0, 0, 2048, 0, 255, 255, 255, 255), + VTX_T(0, 0, 0, 2048, 1024, 255, 255, 255, 255), + VTX_T(0, 0, 0, 2048, 0, 255, 255, 255, 255), +}; + +void EffectBlure_DrawSimple(EffectBlure* this2, GraphicsContext* gfxCtx) { + EffectBlure* this = this2; + Vtx* vtx; + Vtx* vtxIter; + EffectBlureElement* elem; + s32 vtxCount; + s32 i; + s32 j; + Vec3s sp74; + Vec3s sp6C; + f32 ratio; + Color_RGBA8 sp64; + Color_RGBA8 sp60; + + if (this->numElements >= 2) { + vtxCount = this->numElements * 4; + + vtx = GRAPH_ALLOC(gfxCtx, ALIGN16(vtxCount * sizeof(Vtx))); + if (vtx == NULL) { + return; + } + + vtxIter = vtx; + for (i = 0; i < 4; i++) { + vtxIter->v = D_801AE26C[i]; + vtxIter++; + } + + if (this->numElements >= 2) { + for (elem = this->elements; elem < this->elements + this->numElements - 2; elem++) { + for (i = 0; i < 4; i++) { + vtxIter->v = D_801AE2AC[i]; + vtxIter++; + } + } + } + + for (i = 0; i < this->numElements; i++) { + elem = &this->elements[i]; + + ratio = (f32)elem->timer / (f32)this->elemDuration; + EffectBlure_GetComputedValues(this, i, ratio, &sp74, &sp6C, &sp64, &sp60); + + j = i * 4 - 2; + if (j >= 0) { + vtx[j].v.ob[0] = sp74.x; + vtx[j].v.ob[1] = sp74.y; + vtx[j].v.ob[2] = sp74.z; + vtx[j].v.cn[0] = sp64.r; + vtx[j].v.cn[1] = sp64.g; + vtx[j].v.cn[2] = sp64.b; + vtx[j].v.cn[3] = sp64.a; + } + + j++; + if (j >= 0) { + vtx[j].v.ob[0] = sp6C.x; + vtx[j].v.ob[1] = sp6C.y; + vtx[j].v.ob[2] = sp6C.z; + vtx[j].v.cn[0] = sp60.r; + vtx[j].v.cn[1] = sp60.g; + vtx[j].v.cn[2] = sp60.b; + vtx[j].v.cn[3] = sp60.a; + } + + j++; + if (vtxCount >= j) { + vtx[j].v.ob[0] = sp74.x; + vtx[j].v.ob[1] = sp74.y; + vtx[j].v.ob[2] = sp74.z; + vtx[j].v.cn[0] = sp64.r; + vtx[j].v.cn[1] = sp64.g; + vtx[j].v.cn[2] = sp64.b; + vtx[j].v.cn[3] = sp64.a; + } + + j++; + if (vtxCount >= j) { + vtx[j].v.ob[0] = sp6C.x; + vtx[j].v.ob[1] = sp6C.y; + vtx[j].v.ob[2] = sp6C.z; + vtx[j].v.cn[0] = sp60.r; + vtx[j].v.cn[1] = sp60.g; + vtx[j].v.cn[2] = sp60.b; + vtx[j].v.cn[3] = sp60.a; + } + } + + EffectBlure_DrawSimpleVertices(gfxCtx, this, vtx); + } +} + +void EffectBlure_Draw(void* thisx, GraphicsContext* gfxCtx) { + EffectBlure* this = (EffectBlure*)thisx; + Vtx* vtx; + EffectBlureElement* elem; + s32 i; + s32 j; + s32 phi_t2; + + OPEN_DISPS(gfxCtx); + + gSPMatrix(POLY_XLU_DISP++, &gIdentityMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + if (this->numElements != 0) { + if (this->flags == 0) { + func_8012C560(gfxCtx); + gDPPipeSync(POLY_XLU_DISP++); + + vtx = GRAPH_ALLOC(gfxCtx, sizeof(Vtx[32])); + if (vtx == NULL) { + } else { + j = 0; + for (i = 0; i < this->numElements; i++) { + elem = &this->elements[i]; + + if (elem->state == 1) { + f32 ratio = (f32)elem->timer / (f32)this->elemDuration; + + switch (this->calcMode) { + case 1: + vtx[j].v.ob[0] = func_800B09D0(elem->p1.x, elem->p2.x, ratio); + vtx[j].v.ob[1] = func_800B09D0(elem->p1.y, elem->p2.y, ratio); + vtx[j].v.ob[2] = func_800B09D0(elem->p1.z, elem->p2.z, ratio); + vtx[j + 1].v.ob[0] = elem->p2.x; + vtx[j + 1].v.ob[1] = elem->p2.y; + vtx[j + 1].v.ob[2] = elem->p2.z; + break; + case 2: + vtx[j].v.ob[0] = elem->p1.x; + vtx[j].v.ob[1] = elem->p1.y; + vtx[j].v.ob[2] = elem->p1.z; + vtx[j + 1].v.ob[0] = func_800B09D0(elem->p2.x, elem->p1.x, ratio); + vtx[j + 1].v.ob[1] = func_800B09D0(elem->p2.y, elem->p1.y, ratio); + vtx[j + 1].v.ob[2] = func_800B09D0(elem->p2.z, elem->p1.z, ratio); + break; + case 3: + ratio *= 0.5f; + vtx[j].v.ob[0] = func_800B09D0(elem->p1.x, elem->p2.x, ratio); + vtx[j].v.ob[1] = func_800B09D0(elem->p1.y, elem->p2.y, ratio); + vtx[j].v.ob[2] = func_800B09D0(elem->p1.z, elem->p2.z, ratio); + vtx[j + 1].v.ob[0] = func_800B09D0(elem->p2.x, elem->p1.x, ratio); + vtx[j + 1].v.ob[1] = func_800B09D0(elem->p2.y, elem->p1.y, ratio); + vtx[j + 1].v.ob[2] = func_800B09D0(elem->p2.z, elem->p1.z, ratio); + ratio *= 2.0f; + break; + case 0: + default: + vtx[j].v.ob[0] = elem->p1.x; + vtx[j].v.ob[1] = elem->p1.y; + vtx[j].v.ob[2] = elem->p1.z; + vtx[j + 1].v.ob[0] = elem->p2.x; + vtx[j + 1].v.ob[1] = elem->p2.y; + vtx[j + 1].v.ob[2] = elem->p2.z; + break; + } + + vtx[j].v.flag = 0; + vtx[j].v.tc[0] = 0; + vtx[j].v.tc[1] = 0; + vtx[j].v.cn[0] = func_800B0A24(this->p1StartColor.r, this->p1EndColor.r, ratio); + vtx[j].v.cn[1] = func_800B0A24(this->p1StartColor.g, this->p1EndColor.g, ratio); + vtx[j].v.cn[2] = func_800B0A24(this->p1StartColor.b, this->p1EndColor.b, ratio); + vtx[j].v.cn[3] = func_800B0A24(this->p1StartColor.a, this->p1EndColor.a, ratio); + j++; + + vtx[j].v.flag = 0; + vtx[j].v.tc[0] = 0; + vtx[j].v.tc[1] = 0; + vtx[j].v.cn[0] = func_800B0A24(this->p2StartColor.r, this->p2EndColor.r, ratio); + vtx[j].v.cn[1] = func_800B0A24(this->p2StartColor.g, this->p2EndColor.g, ratio); + vtx[j].v.cn[2] = func_800B0A24(this->p2StartColor.b, this->p2EndColor.b, ratio); + vtx[j].v.cn[3] = func_800B0A24(this->p2StartColor.a, this->p2EndColor.a, ratio); + j++; + } + } + + phi_t2 = 0; + j = 0; + + gSPVertex(POLY_XLU_DISP++, vtx, 32, 0); + + for (i = 0; i < this->numElements; i++) { + elem = &this->elements[i]; + + if (elem->state == 0) { + phi_t2 = 0; + } else { + if (phi_t2 == 0) { + phi_t2 = 1; + } else { + gSP1Quadrangle(POLY_XLU_DISP++, j - 2, j - 1, j + 1, j, 0); + + if (this->unkFlag == 1) { + phi_t2 = 0; + } + } + j += 2; + } + } + } + } else if (this->drawMode < 2) { + EffectBlure_DrawSimple(this, gfxCtx); + } else { + EffectBlure_DrawSmooth(this, gfxCtx); + } + } + + CLOSE_DISPS(gfxCtx); +} diff --git a/src/code/z_eff_shield_particle.c b/src/code/z_eff_shield_particle.c index 29d93a715..05669d63a 100644 --- a/src/code/z_eff_shield_particle.c +++ b/src/code/z_eff_shield_particle.c @@ -1,11 +1,207 @@ #include "global.h" +#include "vt.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_shield_particle/EffectShieldParticle_Init.s") +#include "assets/code/eff_shield_particle/eff_shield_particle.c" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_shield_particle/EffectShieldParticle_Destroy.s") +void EffectShieldParticle_Init(void* thisx, void* initParamsx) { + EffectShieldParticle* this = (EffectShieldParticle*)thisx; + EffectShieldParticleInit* initParams = (EffectShieldParticleInit*)initParamsx; + EffectShieldParticleElement* elem; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_shield_particle/EffectShieldParticle_Update.s") + if ((this != NULL) && (initParams != NULL)) { + this->numElements = initParams->numElements; + if (this->numElements > ARRAY_COUNT(this->elements)) { + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_shield_particle/EffectShieldParticle_CalculateColors.s") + this->position = initParams->position; + this->primColorStart = initParams->primColorStart; + this->envColorStart = initParams->envColorStart; + this->primColorMid = initParams->primColorMid; + this->envColorMid = initParams->envColorMid; + this->primColorEnd = initParams->primColorEnd; + this->envColorEnd = initParams->envColorEnd; + this->deceleration = initParams->deceleration; + this->maxInitialSpeed = initParams->maxInitialSpeed; + this->lengthCutoff = initParams->lengthCutoff; + this->duration = initParams->duration; + this->timer = 0; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_shield_particle/EffectShieldParticle_Draw.s") + for (elem = &this->elements[0]; elem < &this->elements[this->numElements]; elem++) { + elem->initialSpeed = (Rand_ZeroOne() * (this->maxInitialSpeed * 0.5f)) + (this->maxInitialSpeed * 0.5f); + elem->endX = 0.0f; + elem->startXChange = 0.0f; + elem->startX = 0.0f; + elem->endXChange = elem->initialSpeed; + elem->yaw = Rand_ZeroOne() * 65534.0f; + elem->pitch = Rand_ZeroOne() * 65534.0f; + } + + this->lightDecay = initParams->lightDecay; + if (this->lightDecay == true) { + this->lightInfo.type = LIGHT_POINT_NOGLOW; + this->lightInfo.params.point = initParams->lightPoint; + this->lightNode = + LightContext_InsertLight(Effect_GetGlobalCtx(), &Effect_GetGlobalCtx()->lightCtx, &this->lightInfo); + } else { + this->lightNode = NULL; + } + } +} + +void EffectShieldParticle_Destroy(void* thisx) { + EffectShieldParticle* this = (EffectShieldParticle*)thisx; + + if ((this != NULL) && (this->lightDecay == true)) { + if (this->lightNode == Effect_GetGlobalCtx()->lightCtx.listHead) { + Effect_GetGlobalCtx()->lightCtx.listHead = this->lightNode->next; + } + LightContext_RemoveLight(Effect_GetGlobalCtx(), &Effect_GetGlobalCtx()->lightCtx, this->lightNode); + } +} + +s32 EffectShieldParticle_Update(void* thisx) { + EffectShieldParticle* this = (EffectShieldParticle*)thisx; + EffectShieldParticleElement* elem; + + if (this == NULL) { + return 0; + } + + for (elem = &this->elements[0]; elem < &this->elements[this->numElements]; elem++) { + elem->endXChange -= this->deceleration; + if (elem->endXChange < 0.0f) { + elem->endXChange = 0.0f; + } + + if (elem->startXChange > 0.0f) { + elem->startXChange -= this->deceleration; + if (elem->startXChange < 0.0f) { + elem->startXChange = 0.0f; + } + } + + elem->endX += elem->endXChange; + elem->startX += elem->startXChange; + + if ((elem->startXChange == 0.0f) && (this->lengthCutoff < (elem->endX - elem->startX))) { + elem->startXChange = elem->initialSpeed; + } + } + + if (this->lightDecay == true) { + this->lightInfo.params.point.radius /= 2; + } + + this->timer++; + + if (this->duration < this->timer) { + return 1; + } + + return 0; +} + +void EffectShieldParticle_GetColors(EffectShieldParticle* this, Color_RGBA8* primColor, Color_RGBA8* envColor) { + s32 halfDuration = this->duration * 0.5f; + + if (halfDuration == 0) { + primColor->r = this->primColorStart.r; + primColor->g = this->primColorStart.g; + primColor->b = this->primColorStart.b; + primColor->a = this->primColorStart.a; + envColor->r = this->envColorStart.r; + envColor->g = this->envColorStart.g; + envColor->b = this->envColorStart.b; + envColor->a = this->envColorStart.a; + } else if (this->timer < halfDuration) { + f32 ratio = this->timer / (f32)halfDuration; + + primColor->r = LERPIMP(this->primColorStart.r, this->primColorMid.r, ratio); + primColor->g = LERPIMP(this->primColorStart.g, this->primColorMid.g, ratio); + primColor->b = LERPIMP(this->primColorStart.b, this->primColorMid.b, ratio); + primColor->a = LERPIMP(this->primColorStart.a, this->primColorMid.a, ratio); + envColor->r = LERPIMP(this->envColorStart.r, this->envColorMid.r, ratio); + envColor->g = LERPIMP(this->envColorStart.g, this->envColorMid.g, ratio); + envColor->b = LERPIMP(this->envColorStart.b, this->envColorMid.b, ratio); + envColor->a = LERPIMP(this->envColorStart.a, this->envColorMid.a, ratio); + } else { + f32 ratio = (this->timer - halfDuration) / (f32)halfDuration; + + primColor->r = LERPIMP(this->primColorMid.r, this->primColorEnd.r, ratio); + primColor->g = LERPIMP(this->primColorMid.g, this->primColorEnd.g, ratio); + primColor->b = LERPIMP(this->primColorMid.b, this->primColorEnd.b, ratio); + primColor->a = LERPIMP(this->primColorMid.a, this->primColorEnd.a, ratio); + envColor->r = LERPIMP(this->envColorMid.r, this->envColorEnd.r, ratio); + envColor->g = LERPIMP(this->envColorMid.g, this->envColorEnd.g, ratio); + envColor->b = LERPIMP(this->envColorMid.b, this->envColorEnd.b, ratio); + envColor->a = LERPIMP(this->envColorMid.a, this->envColorEnd.a, ratio); + } +} + +void EffectShieldParticle_Draw(void* thisx, GraphicsContext* gfxCtx) { + EffectShieldParticle* this = (EffectShieldParticle*)thisx; + EffectShieldParticleElement* elem; + Color_RGBA8 primColor; + Color_RGBA8 envColor; + + OPEN_DISPS(gfxCtx); + + if (this != NULL) { + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0x26); + + gDPSetCycleType(POLY_XLU_DISP++, G_CYC_2CYCLE); + gDPPipeSync(POLY_XLU_DISP++); + gSPTexture(POLY_XLU_DISP++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + + gDPLoadTextureBlock(POLY_XLU_DISP++, D_04054F20, G_IM_FMT_I, G_IM_SIZ_8b, 32, 32, 0, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMIRROR | G_TX_WRAP, 5, 5, G_TX_NOLOD, G_TX_NOLOD); + + gDPSetCombineLERP(POLY_XLU_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, 0, TEXEL0, 0, 0, 0, + 0, COMBINED, 0, 0, 0, COMBINED); + gDPSetRenderMode(POLY_XLU_DISP++, G_RM_PASS, G_RM_ZB_CLD_SURF2); + gSPClearGeometryMode(POLY_XLU_DISP++, G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR); + gSPSetGeometryMode(POLY_XLU_DISP++, G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH); + + EffectShieldParticle_GetColors(this, &primColor, &envColor); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, primColor.r, primColor.g, primColor.b, primColor.a); + gDPSetEnvColor(POLY_XLU_DISP++, envColor.r, envColor.g, envColor.b, envColor.a); + gDPPipeSync(POLY_XLU_DISP++); + + for (elem = &this->elements[0]; elem < &this->elements[this->numElements]; elem++) { + Mtx* mtx; + MtxF sp104; + MtxF spC4; + MtxF sp84; + f32 temp1 = (elem->endX + elem->startX) * 0.5f; + f32 temp2 = elem->endX - elem->startX; + f32 temp3 = (temp2 * (1.0f / 64.0f)) / 0.02f; + + if (temp3 < 1.0f) { + temp3 = 1.0f; + } + + SkinMatrix_SetTranslate(&spC4, this->position.x, this->position.y, this->position.z); + SkinMatrix_SetRotateRPY(&sp104, 0, elem->yaw, 0); + SkinMatrix_MtxFMtxFMult(&spC4, &sp104, &sp84); + SkinMatrix_SetRotateRPY(&sp104, 0, 0, elem->pitch); + SkinMatrix_MtxFMtxFMult(&sp84, &sp104, &spC4); + SkinMatrix_SetTranslate(&sp104, temp1, 0.0f, 0.0f); + SkinMatrix_MtxFMtxFMult(&spC4, &sp104, &sp84); + SkinMatrix_SetScale(&sp104, temp3 * 0.02f, 0.02f, 0.02f); + SkinMatrix_MtxFMtxFMult(&sp84, &sp104, &spC4); + + mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &spC4); + if (mtx == NULL) { + break; + } + + gSPMatrix(POLY_XLU_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPVertex(POLY_XLU_DISP++, sEffShieldParticleVtx, 4, 0); + gSP2Triangles(POLY_XLU_DISP++, 0, 1, 2, 0, 0, 3, 1, 0); + } + } + + CLOSE_DISPS(gfxCtx); +} diff --git a/src/code/z_eff_spark.c b/src/code/z_eff_spark.c index d06bc4b27..27ed1443d 100644 --- a/src/code/z_eff_spark.c +++ b/src/code/z_eff_spark.c @@ -1,9 +1,265 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_spark/EffectSpark_Init.s") +void EffectSpark_Init(void* thisx, void* initParamsx) { + EffectSpark* this = (EffectSpark*)thisx; + EffectSparkInit* initParams = (EffectSparkInit*)initParamsx; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_spark/EffectSpark_Destroy.s") + f32 velocityNorm; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_spark/EffectSpark_Update.s") + if ((this != NULL) && (initParams != NULL)) { + if ((initParams->uDiv == 0) || (initParams->vDiv == 0)) { + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_spark/EffectSpark_Draw.s") + this->position = initParams->position; + this->speed = initParams->speed; + this->gravity = initParams->gravity; + this->uDiv = initParams->uDiv; + this->vDiv = initParams->vDiv; + this->colorStart[0].r = initParams->colorStart[0].r; + this->colorStart[0].g = initParams->colorStart[0].g; + this->colorStart[0].b = initParams->colorStart[0].b; + this->colorStart[0].a = initParams->colorStart[0].a; + this->colorStart[1].r = initParams->colorStart[1].r; + this->colorStart[1].g = initParams->colorStart[1].g; + this->colorStart[1].b = initParams->colorStart[1].b; + this->colorStart[1].a = initParams->colorStart[1].a; + this->colorStart[2].r = initParams->colorStart[2].r; + this->colorStart[2].g = initParams->colorStart[2].g; + this->colorStart[2].b = initParams->colorStart[2].b; + this->colorStart[2].a = initParams->colorStart[2].a; + this->colorStart[3].r = initParams->colorStart[3].r; + this->colorStart[3].g = initParams->colorStart[3].g; + this->colorStart[3].b = initParams->colorStart[3].b; + this->colorStart[3].a = initParams->colorStart[3].a; + this->colorEnd[0].r = initParams->colorEnd[0].r; + this->colorEnd[0].g = initParams->colorEnd[0].g; + this->colorEnd[0].b = initParams->colorEnd[0].b; + this->colorEnd[0].a = initParams->colorEnd[0].a; + this->colorEnd[1].r = initParams->colorEnd[1].r; + this->colorEnd[1].g = initParams->colorEnd[1].g; + this->colorEnd[1].b = initParams->colorEnd[1].b; + this->colorEnd[1].a = initParams->colorEnd[1].a; + this->colorEnd[2].r = initParams->colorEnd[2].r; + this->colorEnd[2].g = initParams->colorEnd[2].g; + this->colorEnd[2].b = initParams->colorEnd[2].b; + this->colorEnd[2].a = initParams->colorEnd[2].a; + this->colorEnd[3].r = initParams->colorEnd[3].r; + this->colorEnd[3].g = initParams->colorEnd[3].g; + this->colorEnd[3].b = initParams->colorEnd[3].b; + this->colorEnd[3].a = initParams->colorEnd[3].a; + this->duration = initParams->duration; + + this->numElements = (this->uDiv * this->vDiv) + 2; + if (this->numElements > ARRAY_COUNT(this->elements)) { + return; + } + + for (i = 0; i < this->numElements; i++) { + EffectSparkElement* elem = &this->elements[i]; + + elem->position.x = this->position.x; + elem->position.y = this->position.y; + elem->position.z = this->position.z; + elem->velocity.x = Rand_ZeroOne() - 0.5f; + elem->velocity.y = Rand_ZeroOne() - 0.5f; + elem->velocity.z = Rand_ZeroOne() - 0.5f; + + velocityNorm = sqrtf(SQXYZ(elem->velocity)); + + if (!(fabsf(velocityNorm) < 0.008f)) { + elem->velocity.x *= this->speed * (1.0f / velocityNorm); + elem->velocity.y *= this->speed * (1.0f / velocityNorm); + elem->velocity.z *= this->speed * (1.0f / velocityNorm); + } else { + elem->velocity.x = elem->velocity.z = 0.0f; + elem->velocity.y = this->speed; + } + + elem->unkVelocity.x = 30000.0f - Rand_ZeroOne() * 15000.0f; + elem->unkVelocity.y = 30000.0f - Rand_ZeroOne() * 15000.0f; + elem->unkVelocity.z = 30000.0f - Rand_ZeroOne() * 15000.0f; + elem->unkPosition.x = Rand_ZeroOne() * 65534.0f; + elem->unkPosition.y = Rand_ZeroOne() * 65534.0f; + elem->unkPosition.z = Rand_ZeroOne() * 65534.0f; + } + + this->timer = 0; + } +} + +void EffectSpark_Destroy(void* thisx) { +} + +s32 EffectSpark_Update(void* thisx) { + EffectSpark* this = (EffectSpark*)thisx; + EffectSparkElement* elem; + s32 i; + + for (i = 0; i < this->numElements; i++) { + elem = &this->elements[i]; + + elem->position.x += elem->velocity.x; + elem->position.y += elem->velocity.y; + elem->position.z += elem->velocity.z; + elem->velocity.y += this->gravity; + elem->unkPosition.x += elem->unkVelocity.x; + elem->unkPosition.y += elem->unkVelocity.y; + elem->unkPosition.z += elem->unkVelocity.z; + } + + this->timer++; + + if (this->duration < this->timer) { + return 1; + } else { + return 0; + } +} + +void EffectSpark_Draw(void* thisx, GraphicsContext* gfxCtx) { + Vtx* vertices; + EffectSpark* this = (EffectSpark*)thisx; + GlobalContext* globalCtx = Effect_GetGlobalCtx(); + s32 i; + s32 j; + u8 sp1D3; + u8 sp1D2; + u8 sp1D1; + u8 sp1D0; + u8 sp1CF; + u8 sp1CE; + u8 sp1CD; + u8 sp1CC; + u8 sp1CB; + u8 sp1CA; + u8 sp1C9; + u8 sp1C8; + u8 sp1C7; + u8 sp1C6; + u8 sp1C5; + u8 sp1C4; + f32 ratio; + + OPEN_DISPS(gfxCtx); + + if (this != NULL) { + gSPMatrix(POLY_XLU_DISP++, &gIdentityMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0x26); + gDPSetCycleType(POLY_XLU_DISP++, G_CYC_2CYCLE); + gDPPipeSync(POLY_XLU_DISP++); + + gSPTexture(POLY_XLU_DISP++, 0xFFFF, 0xFFFF, 0, G_TX_RENDERTILE, G_ON); + gDPLoadTextureBlock(POLY_XLU_DISP++, D_04054F20, G_IM_FMT_I, G_IM_SIZ_8b, 32, 32, 0, G_TX_NOMIRROR | G_TX_WRAP, + G_TX_NOMIRROR | G_TX_WRAP, 5, 5, G_TX_NOLOD, G_TX_NOLOD); + + gDPSetCombineMode(POLY_XLU_DISP++, G_CC_SHADEDECALA, G_CC_PASS2); + gDPSetRenderMode(POLY_XLU_DISP++, G_RM_PASS, G_RM_ZB_CLD_SURF2); + gSPClearGeometryMode(POLY_XLU_DISP++, G_CULL_BOTH | G_FOG | G_LIGHTING | G_TEXTURE_GEN | G_TEXTURE_GEN_LINEAR); + gSPSetGeometryMode(POLY_XLU_DISP++, G_ZBUFFER | G_SHADE | G_SHADING_SMOOTH); + gDPPipeSync(POLY_XLU_DISP++); + + vertices = GRAPH_ALLOC(gfxCtx, ALIGN16(this->numElements * sizeof(Vtx[4]))); + if (vertices == NULL) { + goto end; + } + + j = 0; + + ratio = (f32)this->timer / (f32)this->duration; + sp1D3 = F32_LERPIMP(this->colorStart[0].r, this->colorEnd[0].r, ratio); + sp1D2 = F32_LERPIMP(this->colorStart[0].g, this->colorEnd[0].g, ratio); + sp1D1 = F32_LERPIMP(this->colorStart[0].b, this->colorEnd[0].b, ratio); + sp1D0 = F32_LERPIMP(this->colorStart[0].a, this->colorEnd[0].a, ratio); + sp1CF = F32_LERPIMP(this->colorStart[1].r, this->colorEnd[1].r, ratio); + sp1CE = F32_LERPIMP(this->colorStart[1].g, this->colorEnd[1].g, ratio); + sp1CD = F32_LERPIMP(this->colorStart[1].b, this->colorEnd[1].b, ratio); + sp1CC = F32_LERPIMP(this->colorStart[1].a, this->colorEnd[1].a, ratio); + sp1CB = F32_LERPIMP(this->colorStart[2].r, this->colorEnd[2].r, ratio); + sp1CA = F32_LERPIMP(this->colorStart[2].g, this->colorEnd[2].g, ratio); + sp1C9 = F32_LERPIMP(this->colorStart[2].b, this->colorEnd[2].b, ratio); + sp1C8 = F32_LERPIMP(this->colorStart[2].a, this->colorEnd[2].a, ratio); + sp1C7 = F32_LERPIMP(this->colorStart[3].r, this->colorEnd[3].r, ratio); + sp1C6 = F32_LERPIMP(this->colorStart[3].g, this->colorEnd[3].g, ratio); + sp1C5 = F32_LERPIMP(this->colorStart[3].b, this->colorEnd[3].b, ratio); + sp1C4 = F32_LERPIMP(this->colorStart[3].a, this->colorEnd[3].a, ratio); + + for (i = 0; i < this->numElements; i++) { + MtxF sp12C; + MtxF spEC; + MtxF spAC; + MtxF sp6C; + EffectSparkElement* elem = &this->elements[i]; + Mtx* mtx; + f32 temp; + + SkinMatrix_SetTranslate(&spEC, elem->position.x, elem->position.y, elem->position.z); + temp = ((Rand_ZeroOne() * 2.5f) + 1.5f) / 64.0f; + SkinMatrix_SetScale(&spAC, temp, temp, 1.0f); + SkinMatrix_MtxFMtxFMult(&spEC, &globalCtx->billboardMtxF, &sp6C); + SkinMatrix_MtxFMtxFMult(&sp6C, &spAC, &sp12C); + + vertices[j].v.ob[0] = -32; + vertices[j].v.ob[1] = -32; + vertices[j].v.ob[2] = 0; + vertices[j].v.cn[0] = sp1D3; + vertices[j].v.cn[1] = sp1D2; + vertices[j].v.cn[2] = sp1D1; + vertices[j].v.cn[3] = sp1D0; + vertices[j].v.tc[0] = 0; + vertices[j].v.tc[1] = 1024; + vertices[j].v.flag = 0; + + vertices[j + 1].v.ob[0] = 32; + vertices[j + 1].v.ob[1] = 32; + vertices[j + 1].v.ob[2] = 0; + vertices[j + 1].v.cn[0] = sp1CF; + vertices[j + 1].v.cn[1] = sp1CE; + vertices[j + 1].v.cn[2] = sp1CD; + vertices[j + 1].v.cn[3] = sp1CC; + vertices[j + 1].v.tc[0] = 1024; + vertices[j + 1].v.tc[1] = 0; + vertices[j + 1].v.flag = 0; + + vertices[j + 2].v.ob[0] = -32; + vertices[j + 2].v.ob[1] = 32; + vertices[j + 2].v.ob[2] = 0; + vertices[j + 2].v.cn[0] = sp1CB; + vertices[j + 2].v.cn[1] = sp1CA; + vertices[j + 2].v.cn[2] = sp1C9; + vertices[j + 2].v.cn[3] = sp1C8; + vertices[j + 2].v.tc[0] = 0; + vertices[j + 2].v.tc[1] = 0; + vertices[j + 2].v.flag = 0; + + vertices[j + 3].v.ob[0] = 32; + vertices[j + 3].v.ob[1] = -32; + vertices[j + 3].v.ob[2] = 0; + vertices[j + 3].v.cn[0] = sp1C7; + vertices[j + 3].v.cn[1] = sp1C6; + vertices[j + 3].v.cn[2] = sp1C5; + vertices[j + 3].v.cn[3] = sp1C4; + vertices[j + 3].v.tc[0] = 1024; + vertices[j + 3].v.tc[1] = 1024; + vertices[j + 3].v.flag = 0; + + j += 4; + + mtx = SkinMatrix_MtxFToNewMtx(gfxCtx, &sp12C); + if (mtx == NULL) { + goto end; + } + + gSPMatrix(POLY_XLU_DISP++, mtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPVertex(POLY_XLU_DISP++, &vertices[4 * i], 4, 0); + gSP2Triangles(POLY_XLU_DISP++, 2, 0, 3, 0, 2, 3, 1, 0); + } + + gDPPipeSync(POLY_XLU_DISP++); + } + +end: + CLOSE_DISPS(gfxCtx); +} diff --git a/src/code/z_eff_ss_dead.c b/src/code/z_eff_ss_dead.c index 12665d6b2..bd93f5eed 100644 --- a/src/code/z_eff_ss_dead.c +++ b/src/code/z_eff_ss_dead.c @@ -1,13 +1,111 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_ss_dead/func_800AE2A0.s") +void func_800AE2A0(GlobalContext* globalCtx, Color_RGBA8* color, s16 arg2, s16 arg3) { + f32 cos; + Gfx* displayListHead; + f32 absCos; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_ss_dead/func_800AE434.s") + OPEN_DISPS(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_ss_dead/func_800AE5A0.s") + displayListHead = POLY_OPA_DISP; + cos = Math_CosS((0x8000 / arg3) * arg2); + absCos = fabsf(cos); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_ss_dead/func_800AE5E4.s") + gDPPipeSync(displayListHead++); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_ss_dead/func_800AE778.s") + if (color == NULL) { + gDPSetFogColor(displayListHead++, 255, 0, 0, 0); + } else { + gDPSetFogColor(displayListHead++, color->r, color->g, color->b, color->a); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_ss_dead/func_800AE8EC.s") + gSPFogPosition(displayListHead++, 0, (s16)(absCos * 3000.0f) + 1500); + + POLY_OPA_DISP = displayListHead; + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_800AE434(GlobalContext* globalCtx, Color_RGBA8* color, s16 arg2, s16 arg3) { + Gfx* displayListHead; + f32 cos; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + cos = Math_CosS((0x4000 / arg3) * arg2); + displayListHead = POLY_OPA_DISP; + + gDPPipeSync(displayListHead++); + gDPSetFogColor(displayListHead++, color->r, color->g, color->b, color->a); + gSPFogPosition(displayListHead++, 0, (s16)(2800.0f * fabsf(cos)) + 1700); + + POLY_OPA_DISP = displayListHead; + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_800AE5A0(GlobalContext* globalCtx) { + s32 pad; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gDPPipeSync(POLY_OPA_DISP++); + POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_800AE5E4(GlobalContext* globalCtx, Color_RGBA8* color, s16 arg2, s16 arg3) { + f32 cos; + Gfx* displayListHead; + f32 absCos; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + displayListHead = POLY_XLU_DISP; + cos = Math_CosS((0x8000 / arg3) * arg2); + absCos = fabsf(cos); + + gDPPipeSync(displayListHead++); + + if (color == NULL) { + gDPSetFogColor(displayListHead++, 255, 0, 0, 0); + } else { + gDPSetFogColor(displayListHead++, color->r, color->g, color->b, color->a); + } + + gSPFogPosition(displayListHead++, 0, (s16)(absCos * 3000.0f) + 1500); + + POLY_XLU_DISP = displayListHead; + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_800AE778(GlobalContext* globalCtx, Color_RGBA8* color, s16 arg2, s16 arg3) { + f32 cos; + Gfx* displayListHead; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + displayListHead = POLY_XLU_DISP; + cos = Math_CosS((0x4000 / arg3) * arg2); + + gDPPipeSync(displayListHead++); + gDPSetFogColor(displayListHead++, color->r, color->g, color->b, color->a); + gSPFogPosition(displayListHead++, 0, (s16)(2800.0f * fabsf(cos)) + 1700); + + POLY_XLU_DISP = displayListHead; + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_800AE8EC(GlobalContext* globalCtx) { + s32 pad; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gDPPipeSync(POLY_XLU_DISP++); + POLY_XLU_DISP = func_801660B8(globalCtx, POLY_XLU_DISP); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/code/z_eff_tire_mark.c b/src/code/z_eff_tire_mark.c index 0ae14c86f..517ee5251 100644 --- a/src/code/z_eff_tire_mark.c +++ b/src/code/z_eff_tire_mark.c @@ -1,17 +1,287 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_tire_mark/func_800AE930.s") +void func_800AE930(CollisionContext* colCtx, EffectTireMark* this, Vec3f* pos, f32 arg3, s16 arg4, + CollisionPoly* colPoly, s32 arg6) { + Vec3s spB8; + Vec3s spB0; + EffectTireMarkElement* spAC; + EffectTireMarkElement* spA8; + u32 spA4; + u32 spA0; + Vec3s* vtxList = colCtx->colHeader->vtxList; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_tire_mark/func_800AEF44.s") + if ((arg6 != 50) || (this->numElements >= (ARRAY_COUNT(this->elements) - 1)) || (colPoly == NULL)) { + func_800AEF44(this); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_tire_mark/EffectTireMark_InitParticle.s") + spB8.x = (Math_SinS(arg4 - 0x4000) * arg3) + pos->x; + spB8.z = (Math_CosS(arg4 - 0x4000) * arg3) + pos->z; + spB8.y = func_800BFD84(colPoly, spB8.x, spB8.z) + 2.0f; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_tire_mark/EffectTireMark_Init.s") + spB0.x = (Math_SinS(arg4 + 0x4000) * arg3) + pos->x; + spB0.z = (Math_CosS(arg4 + 0x4000) * arg3) + pos->z; + spB0.y = func_800BFD84(colPoly, spB0.x, spB0.z) + 2.0f; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_tire_mark/EffectTireMark_Destroy.s") + spAC = &this->elements[this->numElements - 1]; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_tire_mark/EffectTireMark_Update.s") + if ((this->numElements != 0) && (spAC->colPoly != NULL) && (colPoly != spAC->colPoly) && + (func_800BFDEC(spAC->colPoly, colPoly, &spA4, &spA0) == 2)) { + Vec3f sp90; + Vec3f sp84; + Vec3f sp78; + Vec3f sp6C; + Vec3f sp60; + Vec3f sp54; + Vec3f sp48; + Vec3f sp3C; + Vec3f sp30; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_tire_mark/EffectTireMark_InitVertices.s") + sp84.x = vtxList[spA4].x; + sp84.y = vtxList[spA4].y; + sp84.z = vtxList[spA4].z; + sp90.x = vtxList[spA0].x; + sp90.y = vtxList[spA0].y; + sp90.z = vtxList[spA0].z; + sp54.x = spAC->p1.x; + sp54.y = spAC->p1.y; + sp54.z = spAC->p1.z; + sp60.x = spB0.x; + sp60.y = spB0.y; + sp60.z = spB0.z; + sp3C.x = spAC->p2.x; + sp3C.y = spAC->p2.y; + sp3C.z = spAC->p2.z; + sp48.x = spB8.x; + sp48.y = spB8.y; + sp48.z = spB8.z; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_eff_tire_mark/EffectTireMark_Draw.s") + if ((func_80179798(&sp84, &sp90, &sp54, &sp60, &sp6C, &sp30) != 0) && + (func_80179798(&sp84, &sp90, &sp3C, &sp48, &sp78, &sp30) != 0)) { + if (!(spAC->flags & 2)) { + spAC->flags |= 1; + } + + spA8 = &this->elements[this->numElements]; + spA8->flags = 0; + spA8->p1.x = sp6C.x; + spA8->p1.y = sp6C.y; + spA8->p1.z = sp6C.z; + spA8->p2.x = sp78.x; + spA8->p2.y = sp78.y; + spA8->p2.z = sp78.z; + spA8->life = this->elemDuration; + spA8->colPoly = NULL; + this->numElements++; + + spAC = &this->elements[this->numElements - 1]; + if (!(spAC->flags & 2)) { + spAC->flags |= 1; + } + + if (spA8) {} // Necessary to match + + spA8 = &this->elements[this->numElements]; + spA8->flags = 0; + spA8->p1 = spB0; + spA8->p2 = spB8; + spA8->life = this->elemDuration; + spA8->colPoly = colPoly; + this->numElements++; + return; + } + + if (!(spAC->flags & 2)) { + spAC->flags |= 1; + } + + spA8 = &this->elements[this->numElements]; + spA8->flags = 0; + spA8->p1 = spB0; + spA8->p2 = spB8; + spA8->life = this->elemDuration; + spA8->colPoly = colPoly; + + this->numElements++; + return; + } + + if (!(spAC->flags & 2)) { + spAC->flags |= 1; + } + + spA8 = &this->elements[this->numElements]; + spA8->flags = 0; + spA8->p1 = spB0; + spA8->p2 = spB8; + spA8->life = this->elemDuration; + spA8->colPoly = colPoly; + + this->numElements++; +} + +void func_800AEF44(EffectTireMark* this) { + EffectTireMarkElement* elem = &this->elements[this->numElements - 1]; + + elem->flags |= 2; +} + +void EffectTireMark_InitElement(EffectTireMarkElement* elem) { + elem->flags = 0; + elem->life = 0; + elem->colPoly = NULL; + elem->p1.x = elem->p1.y = elem->p1.z = elem->p2.x = elem->p2.y = elem->p2.z = 0; +} + +void EffectTireMark_Init(void* thisx, void* initParamsx) { + EffectTireMark* this = (EffectTireMark*)thisx; + EffectTireMarkInit* initParams = (EffectTireMarkInit*)initParamsx; + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->elements); i++) { + EffectTireMark_InitElement(&this->elements[i]); + } + + this->unk600 = initParams->unk0; + this->numElements = 0; + + if (initParams->elemDuration > 62) { + this->elemDuration = 62; + } else { + this->elemDuration = initParams->elemDuration; + } + + this->color = initParams->color; +} + +void EffectTireMark_Destroy(void* thisx) { +} + +s32 EffectTireMark_Update(void* thisx) { + EffectTireMark* this = (EffectTireMark*)thisx; + s32 i; + s32 j; + + if (this->numElements == 0) { + return 0; + } + + for (i = 0; i < this->numElements; i++) { + this->elements[i].life--; + } + + if (this->elements[0].life <= 0) { + for (j = 0; j < ARRAY_COUNT(this->elements) - 1; j++) { + this->elements[j] = this->elements[j + 1]; + } + + EffectTireMark_InitElement(&this->elements[j]); + + this->numElements--; + if (this->numElements < 0) { + this->numElements = 0; + } + return 0; + } + + return 0; +} + +void EffectTireMark_SetVertices(Vtx* vtx, EffectTireMarkElement* elem, s32 i, s32 alpha) { + s32 i1 = i * 2; + s32 i2 = i * 2 + 1; + + vtx[i1].v.ob[0] = elem->p1.x; + vtx[i1].v.ob[1] = elem->p1.y; + vtx[i1].v.ob[2] = elem->p1.z; + vtx[i1].v.tc[0] = 2048; + vtx[i1].v.tc[1] = 0; + vtx[i1].v.cn[0] = 255; + vtx[i1].v.cn[1] = 255; + vtx[i1].v.cn[2] = 255; + vtx[i1].v.cn[3] = alpha; + + vtx[i2].v.ob[0] = elem->p2.x; + vtx[i2].v.ob[1] = elem->p2.y; + vtx[i2].v.ob[2] = elem->p2.z; + vtx[i2].v.tc[0] = 2048; + vtx[i2].v.tc[1] = 1024; + vtx[i2].v.cn[0] = 255; + vtx[i2].v.cn[1] = 255; + vtx[i2].v.cn[2] = 255; + vtx[i2].v.cn[3] = alpha; +} + +void EffectTireMark_Draw(void* thisx, GraphicsContext* gfxCtx) { + EffectTireMark* this = (EffectTireMark*)thisx; + EffectTireMarkElement* elem; + Vtx* vtx; + s32 pad; + f32 sp34; + s32 i; + + sp34 = 1.0f / this->elemDuration; + + OPEN_DISPS(gfxCtx); + + if (this->numElements >= 2) { + vtx = GRAPH_ALLOC(gfxCtx, ALIGN16(this->numElements * sizeof(Vtx[2]))); + + if (vtx != NULL) { + gSPMatrix(POLY_OPA_DISP++, &gIdentityMtx, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + POLY_OPA_DISP = Gfx_CallSetupDL(POLY_OPA_DISP++, 0x2C); + gDPSetRenderMode(POLY_OPA_DISP++, G_RM_PASS, G_RM_ZB_CLD_SURF2); + + gDPLoadTextureBlock(POLY_OPA_DISP++, D_04014570, G_IM_FMT_I, G_IM_SIZ_8b, 64, 32, 0, + G_TX_NOMIRROR | G_TX_CLAMP, G_TX_NOMIRROR | G_TX_WRAP, 6, 5, G_TX_NOLOD, G_TX_NOLOD); + + gDPSetCombineLERP(POLY_OPA_DISP++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, COMBINED, 0, 0, 0, + COMBINED); + gSPSetGeometryMode(POLY_OPA_DISP++, G_SHADE | G_SHADING_SMOOTH); + gSPClearGeometryMode(POLY_OPA_DISP++, G_CULL_BACK | G_LIGHTING); + + EffectTireMark_SetVertices(vtx, &this->elements[0], 0, 255); + + vtx[0].v.tc[0] = 0; + vtx[0].v.tc[1] = 0; + vtx[1].v.tc[0] = 0; + vtx[1].v.tc[1] = 1024; + + for (i = 1; i < this->numElements; i++) { + elem = &this->elements[i]; + + EffectTireMark_SetVertices(vtx, elem, i, 255); + + if ((elem - 1)->flags & 1) { + if (!(elem->flags & 1)) { + vtx[i * 2 + 0].v.tc[0] = 0; + vtx[i * 2 + 0].v.tc[1] = 0; + vtx[i * 2 + 1].v.tc[0] = 0; + vtx[i * 2 + 1].v.tc[1] = 1024; + dummy_label:; + } else if ((i >= 2) && !((elem - 2)->flags & 1)) { + vtx[i * 2 - 2].v.tc[0] = 0; + vtx[i * 2 - 2].v.tc[1] = 0; + vtx[i * 2 - 1].v.tc[0] = 0; + vtx[i * 2 - 1].v.tc[1] = 1024; + } + + if (i == (this->numElements - 1)) { + vtx[i * 2 + 0].v.tc[0] = 0; + vtx[i * 2 + 0].v.tc[1] = 0; + vtx[i * 2 + 1].v.tc[0] = 0; + vtx[i * 2 + 1].v.tc[1] = 1024; + } + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->color.r, this->color.g, this->color.b, + (s32)((f32)this->color.a * (f32)elem->life * sp34)); + gSPVertex(POLY_OPA_DISP++, &vtx[i * 2 - 2], 4, 0); + gSP2Triangles(POLY_OPA_DISP++, 0, 1, 3, 0, 0, 3, 2, 0); + } + } + } + } + + CLOSE_DISPS(gfxCtx); +} diff --git a/src/code/z_effect.c b/src/code/z_effect.c index 1c7ad3891..dd696393f 100644 --- a/src/code/z_effect.c +++ b/src/code/z_effect.c @@ -1,55 +1,57 @@ #include "global.h" -EffInfo sEffInfoTable[] = { +EffectContext sEffectContext; + +EffectInfo sEffectInfoTable[] = { { - sizeof(EffSparkParams), - (eff_init_func)EffectSpark_Init, - (eff_destroy_func)EffectSpark_Destroy, - (eff_update_func)EffectSpark_Update, - (eff_draw_func)EffectSpark_Draw, + sizeof(EffectSpark), + EffectSpark_Init, + EffectSpark_Destroy, + EffectSpark_Update, + EffectSpark_Draw, }, { sizeof(EffectBlure), - (eff_init_func)EffectBlure_Init1, - (eff_destroy_func)EffectBlure_Destroy, - (eff_update_func)EffectBlure_Update, - (eff_draw_func)EffectBlure_Draw, + EffectBlure_Init1, + EffectBlure_Destroy, + EffectBlure_Update, + EffectBlure_Draw, }, { sizeof(EffectBlure), - (eff_init_func)EffectBlure_Init2, - (eff_destroy_func)EffectBlure_Destroy, - (eff_update_func)EffectBlure_Update, - (eff_draw_func)EffectBlure_Draw, + EffectBlure_Init2, + EffectBlure_Destroy, + EffectBlure_Update, + EffectBlure_Draw, }, { - sizeof(EffShieldParticleParams), - (eff_init_func)EffectShieldParticle_Init, - (eff_destroy_func)EffectShieldParticle_Destroy, - (eff_update_func)EffectShieldParticle_Update, - (eff_draw_func)EffectShieldParticle_Draw, + sizeof(EffectShieldParticle), + EffectShieldParticle_Init, + EffectShieldParticle_Destroy, + EffectShieldParticle_Update, + EffectShieldParticle_Draw, }, { - sizeof(EffTireMarkParams), - (eff_init_func)EffectTireMark_Init, - (eff_destroy_func)EffectTireMark_Destroy, - (eff_update_func)EffectTireMark_Update, - (eff_draw_func)EffectTireMark_Draw, + sizeof(EffectTireMark), + EffectTireMark_Init, + EffectTireMark_Destroy, + EffectTireMark_Update, + EffectTireMark_Draw, }, }; -GlobalContext* Effect_GetContext(void) { - return sEffTable.globalCtx; +GlobalContext* Effect_GetGlobalCtx(void) { + return sEffectContext.globalCtx; } -void* Effect_GetParams(s32 index) { +void* Effect_GetByIndex(s32 index) { if (index == TOTAL_EFFECT_COUNT) { return NULL; } if (index < SPARK_COUNT) { - if (sEffTable.sparks[index].base.active == 1) { - return &sEffTable.sparks[index].params; + if (sEffectContext.sparks[index].status.active == true) { + return &sEffectContext.sparks[index].effect; } else { return NULL; } @@ -57,8 +59,8 @@ void* Effect_GetParams(s32 index) { index -= SPARK_COUNT; if (index < BLURE_COUNT) { - if (sEffTable.blures[index].base.active == 1) { - return &sEffTable.blures[index].params; + if (sEffectContext.blures[index].status.active == true) { + return &sEffectContext.blures[index].effect; } else { return NULL; } @@ -66,8 +68,8 @@ void* Effect_GetParams(s32 index) { index -= BLURE_COUNT; if (index < SHIELD_PARTICLE_COUNT) { - if (sEffTable.shieldParticles[index].base.active == 1) { - return &sEffTable.shieldParticles[index].params; + if (sEffectContext.shieldParticles[index].status.active == true) { + return &sEffectContext.shieldParticles[index].effect; } else { return NULL; } @@ -75,8 +77,8 @@ void* Effect_GetParams(s32 index) { index -= SHIELD_PARTICLE_COUNT; if (index < TIRE_MARK_COUNT) { - if (sEffTable.tireMarks[index].base.active == 1) { - return &sEffTable.tireMarks[index].params; + if (sEffectContext.tireMarks[index].status.active == true) { + return &sEffectContext.tireMarks[index].effect; } else { return NULL; } @@ -85,89 +87,87 @@ void* Effect_GetParams(s32 index) { return NULL; } -void Effect_InitCommon(EffCommon* common) { - common->active = 0; - common->unk1 = 0; - common->unk2 = 0; +void Effect_InitStatus(EffectStatus* status) { + status->active = false; + status->unk1 = 0; + status->unk2 = 0; } void Effect_Init(GlobalContext* globalCtx) { s32 i; for (i = 0; i < SPARK_COUNT; i++) { - Effect_InitCommon(&sEffTable.sparks[i].base); + Effect_InitStatus(&sEffectContext.sparks[i].status); } for (i = 0; i < BLURE_COUNT; i++) { - Effect_InitCommon(&sEffTable.blures[i].base); + Effect_InitStatus(&sEffectContext.blures[i].status); } - //! @bug This is probably supposed to loop over shieldParticles, not blures again for (i = 0; i < SHIELD_PARTICLE_COUNT; i++) { - Effect_InitCommon(&sEffTable.blures[i].base); + //! @bug This is probably supposed to initialize shieldParticles, not blures again + Effect_InitStatus(&sEffectContext.blures[i].status); } for (i = 0; i < TIRE_MARK_COUNT; i++) { - Effect_InitCommon(&sEffTable.tireMarks[i].base); + Effect_InitStatus(&sEffectContext.tireMarks[i].status); } - sEffTable.globalCtx = globalCtx; + sEffectContext.globalCtx = globalCtx; } -void Effect_Add(GlobalContext* globalCtx, s32* index, s32 type, u8 param_4, u8 param_5, void* initParams) { +void Effect_Add(GlobalContext* globalCtx, s32* pIndex, s32 type, u8 arg3, u8 arg4, void* initParams) { u32 slotFound; s32 i; - void* params; - EffCommon* common; + void* effect = NULL; + EffectStatus* status = NULL; - params = NULL; - *index = TOTAL_EFFECT_COUNT; - common = NULL; + *pIndex = TOTAL_EFFECT_COUNT; if (FrameAdvance_IsEnabled(globalCtx) != true) { - slotFound = 0; + slotFound = false; switch (type) { - case 0: + case EFFECT_SPARK: for (i = 0; i < SPARK_COUNT; i++) { - if (sEffTable.sparks[i].base.active == 0) { - slotFound = 1; - *index = i; - params = &sEffTable.sparks[i].params; - common = &sEffTable.sparks[i].base; + if (sEffectContext.sparks[i].status.active == false) { + slotFound = true; + *pIndex = i; + effect = &sEffectContext.sparks[i].effect; + status = &sEffectContext.sparks[i].status; break; } } break; - case 1: - case 2: + case EFFECT_BLURE1: + case EFFECT_BLURE2: for (i = 0; i < BLURE_COUNT; i++) { - if (sEffTable.blures[i].base.active == 0) { - slotFound = 1; - *index = i + 3; - params = &sEffTable.blures[i].params; - common = &sEffTable.blures[i].base; + if (sEffectContext.blures[i].status.active == false) { + slotFound = true; + *pIndex = i + SPARK_COUNT; + effect = &sEffectContext.blures[i].effect; + status = &sEffectContext.blures[i].status; break; } } break; - case 3: + case EFFECT_SHIELD_PARTICLE: for (i = 0; i < SHIELD_PARTICLE_COUNT; i++) { - if (sEffTable.shieldParticles[i].base.active == 0) { - slotFound = 1; - *index = i + 28; - params = &sEffTable.shieldParticles[i].params; - common = &sEffTable.shieldParticles[i].base; + if (sEffectContext.shieldParticles[i].status.active == false) { + slotFound = true; + *pIndex = i + SPARK_COUNT + BLURE_COUNT; + effect = &sEffectContext.shieldParticles[i].effect; + status = &sEffectContext.shieldParticles[i].status; break; } } break; - case 4: + case EFFECT_TIRE_MARK: for (i = 0; i < TIRE_MARK_COUNT; i++) { - if (sEffTable.tireMarks[i].base.active == 0) { - slotFound = 1; - *index = i + 31; - params = &sEffTable.tireMarks[i].params; - common = &sEffTable.tireMarks[i].base; + if (sEffectContext.tireMarks[i].status.active == false) { + slotFound = true; + *pIndex = i + SPARK_COUNT + BLURE_COUNT + SHIELD_PARTICLE_COUNT; + effect = &sEffectContext.tireMarks[i].effect; + status = &sEffectContext.tireMarks[i].status; break; } } @@ -175,10 +175,10 @@ void Effect_Add(GlobalContext* globalCtx, s32* index, s32 type, u8 param_4, u8 p } if (slotFound) { - sEffInfoTable[type].init(params, initParams); - common->unk2 = param_4; - common->unk1 = param_5; - common->active = 1; + sEffectInfoTable[type].init(effect, initParams); + status->unk2 = arg3; + status->unk1 = arg4; + status->active = true; } } } @@ -188,8 +188,8 @@ void Effect_DrawAll(GraphicsContext* gfxCtx) { for (i = 0; i < SPARK_COUNT; i++) { if (1) {} // necessary to match - if (sEffTable.sparks[i].base.active) { - sEffInfoTable[0].draw(&sEffTable.sparks[i].params, gfxCtx); + if (sEffectContext.sparks[i].status.active) { + sEffectInfoTable[EFFECT_SPARK].draw(&sEffectContext.sparks[i].effect, gfxCtx); } } @@ -197,22 +197,22 @@ void Effect_DrawAll(GraphicsContext* gfxCtx) { if (1) { if (gfxCtx) {} } // necessary to match - if (sEffTable.blures[i].base.active) { - sEffInfoTable[1].draw(&sEffTable.blures[i].params, gfxCtx); + if (sEffectContext.blures[i].status.active) { + sEffectInfoTable[EFFECT_BLURE1].draw(&sEffectContext.blures[i].effect, gfxCtx); } } for (i = 0; i < SHIELD_PARTICLE_COUNT; i++) { if (1) {} // necessary to match - if (sEffTable.shieldParticles[i].base.active) { - sEffInfoTable[3].draw(&sEffTable.shieldParticles[i].params, gfxCtx); + if (sEffectContext.shieldParticles[i].status.active) { + sEffectInfoTable[EFFECT_SHIELD_PARTICLE].draw(&sEffectContext.shieldParticles[i].effect, gfxCtx); } } if (1) {} // necessary to match for (i = 0; i < TIRE_MARK_COUNT; i++) { - if (sEffTable.tireMarks[i].base.active) { - sEffInfoTable[4].draw(&sEffTable.tireMarks[i].params, gfxCtx); + if (sEffectContext.tireMarks[i].status.active) { + sEffectInfoTable[EFFECT_TIRE_MARK].draw(&sEffectContext.tireMarks[i].effect, gfxCtx); } } } @@ -222,8 +222,8 @@ void Effect_UpdateAll(GlobalContext* globalCtx) { for (i = 0; i < SPARK_COUNT; i++) { if (1) {} // necessary to match - if (sEffTable.sparks[i].base.active) { - if (sEffInfoTable[0].update(&sEffTable.sparks[i].params) == 1) { + if (sEffectContext.sparks[i].status.active) { + if (sEffectInfoTable[EFFECT_SPARK].update(&sEffectContext.sparks[i].effect) == 1) { Effect_Destroy(globalCtx, i); } } @@ -231,27 +231,27 @@ void Effect_UpdateAll(GlobalContext* globalCtx) { for (i = 0; i < BLURE_COUNT; i++) { if (1) {} // necessary to match - if (sEffTable.blures[i].base.active) { - if (sEffInfoTable[1].update(&sEffTable.blures[i].params) == 1) { - Effect_Destroy(globalCtx, i + 3); + if (sEffectContext.blures[i].status.active) { + if (sEffectInfoTable[EFFECT_BLURE1].update(&sEffectContext.blures[i].effect) == 1) { + Effect_Destroy(globalCtx, i + SPARK_COUNT); } } } for (i = 0; i < SHIELD_PARTICLE_COUNT; i++) { if (1) {} // necessary to match - if (sEffTable.shieldParticles[i].base.active) { - if (sEffInfoTable[3].update(&sEffTable.shieldParticles[i].params) == 1) { - Effect_Destroy(globalCtx, i + 28); + if (sEffectContext.shieldParticles[i].status.active) { + if (sEffectInfoTable[EFFECT_SHIELD_PARTICLE].update(&sEffectContext.shieldParticles[i].effect) == 1) { + Effect_Destroy(globalCtx, i + SPARK_COUNT + BLURE_COUNT); } } } for (i = 0; i < TIRE_MARK_COUNT; i++) { if (1) {} // necessary to match - if (sEffTable.tireMarks[i].base.active) { - if (sEffInfoTable[4].update(&sEffTable.tireMarks[i].params) == 1) { - Effect_Destroy(globalCtx, i + 31); + if (sEffectContext.tireMarks[i].status.active) { + if (sEffectInfoTable[EFFECT_TIRE_MARK].update(&sEffectContext.tireMarks[i].effect) == 1) { + Effect_Destroy(globalCtx, i + SPARK_COUNT + BLURE_COUNT + SHIELD_PARTICLE_COUNT); } } } @@ -263,29 +263,29 @@ void Effect_Destroy(GlobalContext* globalCtx, s32 index) { } if (index < SPARK_COUNT) { - sEffTable.sparks[index].base.active = 0; - sEffInfoTable[0].destroy(&sEffTable.sparks[index].params); + sEffectContext.sparks[index].status.active = false; + sEffectInfoTable[EFFECT_SPARK].destroy(&sEffectContext.sparks[index].effect); return; } index -= SPARK_COUNT; if (index < BLURE_COUNT) { - sEffTable.blures[index].base.active = 0; - sEffInfoTable[1].destroy(&sEffTable.blures[index].params); + sEffectContext.blures[index].status.active = false; + sEffectInfoTable[EFFECT_BLURE1].destroy(&sEffectContext.blures[index].effect); return; } index -= BLURE_COUNT; if (index < SHIELD_PARTICLE_COUNT) { - sEffTable.shieldParticles[index].base.active = 0; - sEffInfoTable[3].destroy(&sEffTable.shieldParticles[index].params); + sEffectContext.shieldParticles[index].status.active = false; + sEffectInfoTable[EFFECT_SHIELD_PARTICLE].destroy(&sEffectContext.shieldParticles[index].effect); return; } index -= SHIELD_PARTICLE_COUNT; if (index < TIRE_MARK_COUNT) { - sEffTable.tireMarks[index].base.active = 0; - sEffInfoTable[4].destroy(&sEffTable.tireMarks[index].params); + sEffectContext.tireMarks[index].status.active = false; + sEffectInfoTable[EFFECT_TIRE_MARK].destroy(&sEffectContext.tireMarks[index].effect); return; } } @@ -294,22 +294,22 @@ void Effect_DestroyAll(GlobalContext* globalCtx) { s32 i; for (i = 0; i < SPARK_COUNT; i++) { - sEffTable.sparks[i].base.active = 0; - sEffInfoTable[0].destroy(&sEffTable.sparks[i].params); + sEffectContext.sparks[i].status.active = false; + sEffectInfoTable[EFFECT_SPARK].destroy(&sEffectContext.sparks[i].effect); } for (i = 0; i < BLURE_COUNT; i++) { - sEffTable.blures[i].base.active = 0; - sEffInfoTable[1].destroy(&sEffTable.blures[i].params); + sEffectContext.blures[i].status.active = false; + sEffectInfoTable[EFFECT_BLURE1].destroy(&sEffectContext.blures[i].effect); } for (i = 0; i < SHIELD_PARTICLE_COUNT; i++) { - sEffTable.shieldParticles[i].base.active = 0; - sEffInfoTable[3].destroy(&sEffTable.shieldParticles[i].params); + sEffectContext.shieldParticles[i].status.active = false; + sEffectInfoTable[EFFECT_SHIELD_PARTICLE].destroy(&sEffectContext.shieldParticles[i].effect); } for (i = 0; i < TIRE_MARK_COUNT; i++) { - sEffTable.tireMarks[i].base.active = 0; - sEffInfoTable[4].destroy(&sEffTable.tireMarks[i].params); + sEffectContext.tireMarks[i].status.active = false; + sEffectInfoTable[EFFECT_TIRE_MARK].destroy(&sEffectContext.tireMarks[i].effect); } } diff --git a/src/code/z_effect_soft_sprite.c b/src/code/z_effect_soft_sprite.c index 47c2202f1..424166f89 100644 --- a/src/code/z_effect_soft_sprite.c +++ b/src/code/z_effect_soft_sprite.c @@ -1,20 +1,22 @@ #include "global.h" +EffectSsInfo sEffectSsInfo = { NULL, 0, 0 }; + void EffectSS_Init(GlobalContext* globalCtx, s32 numEntries) { u32 i; EffectSs* effectsSs; EffectSsOverlay* overlay; - EffectSS2Info.data_table = (EffectSs*)THA_AllocEndAlign16(&globalCtx->state.heap, numEntries * sizeof(EffectSs)); - EffectSS2Info.searchIndex = 0; - EffectSS2Info.size = numEntries; + sEffectSsInfo.data_table = (EffectSs*)THA_AllocEndAlign16(&globalCtx->state.heap, numEntries * sizeof(EffectSs)); + sEffectSsInfo.searchIndex = 0; + sEffectSsInfo.size = numEntries; - for (effectsSs = &EffectSS2Info.data_table[0]; effectsSs < &EffectSS2Info.data_table[EffectSS2Info.size]; + for (effectsSs = &sEffectSsInfo.data_table[0]; effectsSs < &sEffectSsInfo.data_table[sEffectSsInfo.size]; effectsSs++) { EffectSS_ResetEntry(effectsSs); } - overlay = &particleOverlayTable[0]; + overlay = &gParticleOverlayTable[0]; for (i = 0; i < EFFECT_SS_MAX; i++) { overlay->loadedRamAddr = NULL; overlay++; @@ -27,30 +29,31 @@ void EffectSS_Clear(GlobalContext* globalCtx) { EffectSsOverlay* overlay; void* addr; - EffectSS2Info.data_table = NULL; - EffectSS2Info.searchIndex = 0; - EffectSS2Info.size = 0; + sEffectSsInfo.data_table = NULL; + sEffectSsInfo.searchIndex = 0; + sEffectSsInfo.size = 0; - // This code is completely useless, as data_table was just set to NULL and size to 0 - for (effectsSs = EffectSS2Info.data_table; effectsSs < EffectSS2Info.data_table + EffectSS2Info.size; effectsSs++) { + //! @bug: Effects left in the table are not properly deleted, as data_table was just set to NULL and size to 0 + for (effectsSs = &sEffectSsInfo.data_table[0]; effectsSs < &sEffectSsInfo.data_table[sEffectSsInfo.size]; + effectsSs++) { EffectSS_Delete(effectsSs); } // Free memory from loaded particle overlays - overlay = &particleOverlayTable[0]; + overlay = &gParticleOverlayTable[0]; for (i = 0; i < EFFECT_SS_MAX; i++) { addr = overlay->loadedRamAddr; if (addr != NULL) { ZeldaArena_Free(addr); } - overlay->loadedRamAddr = 0; + overlay->loadedRamAddr = NULL; overlay++; } } EffectSs* EffectSS_GetTable() { - return EffectSS2Info.data_table; + return sEffectSsInfo.data_table; } void EffectSS_Delete(EffectSs* effectSs) { @@ -90,27 +93,27 @@ s32 EffectSS_FindFreeSpace(s32 priority, s32* tableEntry) { s32 foundFree; s32 i; - if (EffectSS2Info.searchIndex >= EffectSS2Info.size) { - EffectSS2Info.searchIndex = 0; + if (sEffectSsInfo.searchIndex >= sEffectSsInfo.size) { + sEffectSsInfo.searchIndex = 0; } // Search for a unused entry - i = EffectSS2Info.searchIndex; + i = sEffectSsInfo.searchIndex; foundFree = false; while (true) { - if (EffectSS2Info.data_table[i].life == -1) { + if (sEffectSsInfo.data_table[i].life == -1) { foundFree = true; break; } i++; - if (i >= EffectSS2Info.size) { + if (i >= sEffectSsInfo.size) { i = 0; // Loop around the whole table } // After a full loop, break out - if (i == EffectSS2Info.searchIndex) { + if (i == sEffectSsInfo.searchIndex) { break; } } @@ -122,22 +125,22 @@ s32 EffectSS_FindFreeSpace(s32 priority, s32* tableEntry) { // If all slots are in use, search for a slot with a lower priority // Note that a lower priority is representend by a higher value - i = EffectSS2Info.searchIndex; + i = sEffectSsInfo.searchIndex; while (true) { // Equal priority should only be considered "lower" if flag 0 is set - if ((priority <= EffectSS2Info.data_table[i].priority) && - !((priority == EffectSS2Info.data_table[i].priority) && (EffectSS2Info.data_table[i].flags & 1))) { + if ((priority <= sEffectSsInfo.data_table[i].priority) && + !((priority == sEffectSsInfo.data_table[i].priority) && (sEffectSsInfo.data_table[i].flags & 1))) { break; } i++; - if (i >= EffectSS2Info.size) { + if (i >= sEffectSsInfo.size) { i = 0; // Loop around the whole table } // After a full loop, return 1 to indicate that we failed to find a suitable slot - if (i == EffectSS2Info.searchIndex) { + if (i == sEffectSsInfo.searchIndex) { return true; } } @@ -151,8 +154,8 @@ void EffectSS_Copy(GlobalContext* globalCtx, EffectSs* effectsSs) { if (FrameAdvance_IsEnabled(globalCtx) != true) { if (EffectSS_FindFreeSpace(effectsSs->priority, &index) == 0) { - EffectSS2Info.searchIndex = index + 1; - EffectSS2Info.data_table[index] = *effectsSs; + sEffectSsInfo.searchIndex = index + 1; + sEffectSsInfo.data_table[index] = *effectsSs; } } } @@ -160,7 +163,7 @@ void EffectSS_Copy(GlobalContext* globalCtx, EffectSs* effectsSs) { void EffectSs_Spawn(GlobalContext* globalCtx, s32 type, s32 priority, void* initData) { s32 index; u32 overlaySize; - EffectSsOverlay* entry = &particleOverlayTable[type]; + EffectSsOverlay* entry = &gParticleOverlayTable[type]; EffectSsInit* initInfo; if (EffectSS_FindFreeSpace(priority, &index) != 0) { @@ -168,8 +171,8 @@ void EffectSs_Spawn(GlobalContext* globalCtx, s32 type, s32 priority, void* init return; } - EffectSS2Info.searchIndex = index + 1; - overlaySize = (u32)entry->vramEnd - (u32)entry->vramStart; + sEffectSsInfo.searchIndex = index + 1; + overlaySize = (uintptr_t)entry->vramEnd - (uintptr_t)entry->vramStart; if (entry->vramStart == NULL) { initInfo = entry->initInfo; @@ -184,27 +187,27 @@ void EffectSs_Spawn(GlobalContext* globalCtx, s32 type, s32 priority, void* init Load2_LoadOverlay(entry->vromStart, entry->vromEnd, entry->vramStart, entry->vramEnd, entry->loadedRamAddr); } - initInfo = (void*)(u32)( - entry->initInfo != NULL - ? (EffectSsInit*)(-((u32)entry->vramStart - (u32)entry->loadedRamAddr) + (u32)entry->initInfo) - : NULL); + initInfo = (u32)((entry->initInfo != NULL) + ? (EffectSsInit*)(-((uintptr_t)entry->vramStart - (uintptr_t)entry->loadedRamAddr) + + (uintptr_t)entry->initInfo) + : NULL); } if (initInfo->init != NULL) { // Delete the previous effect in the slot, in case the slot wasn't free - EffectSS_Delete(&EffectSS2Info.data_table[index]); + EffectSS_Delete(&sEffectSsInfo.data_table[index]); - EffectSS2Info.data_table[index].type = type; - EffectSS2Info.data_table[index].priority = priority; + sEffectSsInfo.data_table[index].type = type; + sEffectSsInfo.data_table[index].priority = priority; - if (initInfo->init(globalCtx, index, &EffectSS2Info.data_table[index], initData) == 0) { - EffectSS_ResetEntry(&EffectSS2Info.data_table[index]); + if (initInfo->init(globalCtx, index, &sEffectSsInfo.data_table[index], initData) == 0) { + EffectSS_ResetEntry(&sEffectSsInfo.data_table[index]); } } } void EffectSS_UpdateParticle(GlobalContext* globalCtx, s32 index) { - EffectSs* particle = &EffectSS2Info.data_table[index]; + EffectSs* particle = &sEffectSsInfo.data_table[index]; if (particle->update != NULL) { particle->velocity.x += particle->accel.x; @@ -222,23 +225,23 @@ void EffectSS_UpdateParticle(GlobalContext* globalCtx, s32 index) { void EffectSS_UpdateAllParticles(GlobalContext* globalCtx) { s32 i; - for (i = 0; i < EffectSS2Info.size; i++) { - if (EffectSS2Info.data_table[i].life > -1) { - EffectSS2Info.data_table[i].life--; + for (i = 0; i < sEffectSsInfo.size; i++) { + if (sEffectSsInfo.data_table[i].life > -1) { + sEffectSsInfo.data_table[i].life--; - if (EffectSS2Info.data_table[i].life < 0) { - EffectSS_Delete(&EffectSS2Info.data_table[i]); + if (sEffectSsInfo.data_table[i].life < 0) { + EffectSS_Delete(&sEffectSsInfo.data_table[i]); } } - if (EffectSS2Info.data_table[i].life > -1) { + if (sEffectSsInfo.data_table[i].life > -1) { EffectSS_UpdateParticle(globalCtx, i); } } } void EffectSS_DrawParticle(GlobalContext* globalCtx, s32 index) { - EffectSs* entry = &EffectSS2Info.data_table[index]; + EffectSs* entry = &sEffectSsInfo.data_table[index]; if (entry->draw != NULL) { entry->draw(globalCtx, index, entry); @@ -252,12 +255,12 @@ void EffectSS_DrawAllParticles(GlobalContext* globalCtx) { Lights_BindAll(lights, globalCtx->lightCtx.listHead, NULL, globalCtx); Lights_Draw(lights, globalCtx->state.gfxCtx); - for (i = 0; i < EffectSS2Info.size; i++) { - if (EffectSS2Info.data_table[i].life > -1) { - if ((EffectSS2Info.data_table[i].pos.x > 32000.0f) || (EffectSS2Info.data_table[i].pos.x < -32000.0f) || - (EffectSS2Info.data_table[i].pos.y > 32000.0f) || (EffectSS2Info.data_table[i].pos.y < -32000.0f) || - (EffectSS2Info.data_table[i].pos.z > 32000.0f) || (EffectSS2Info.data_table[i].pos.z < -32000.0f)) { - EffectSS_Delete(&EffectSS2Info.data_table[i]); + for (i = 0; i < sEffectSsInfo.size; i++) { + if (sEffectSsInfo.data_table[i].life > -1) { + if ((sEffectSsInfo.data_table[i].pos.x > 32000.0f) || (sEffectSsInfo.data_table[i].pos.x < -32000.0f) || + (sEffectSsInfo.data_table[i].pos.y > 32000.0f) || (sEffectSsInfo.data_table[i].pos.y < -32000.0f) || + (sEffectSsInfo.data_table[i].pos.z > 32000.0f) || (sEffectSsInfo.data_table[i].pos.z < -32000.0f)) { + EffectSS_Delete(&sEffectSsInfo.data_table[i]); } else { EffectSS_DrawParticle(globalCtx, i); } diff --git a/src/code/z_effect_soft_sprite_dlftbls.c b/src/code/z_effect_soft_sprite_dlftbls.c new file mode 100644 index 000000000..e215cdee9 --- /dev/null +++ b/src/code/z_effect_soft_sprite_dlftbls.c @@ -0,0 +1,56 @@ +#include "global.h" +#include "initvars.h" + +#define EFFECT_SS_OVERLAY(name) \ + { \ + SEGMENT_ROM_START(ovl_##name), SEGMENT_ROM_END(ovl_##name), SEGMENT_START(ovl_##name), \ + SEGMENT_END(ovl_##name), NULL, &name##_InitVars, 1, \ + } + +#define EFFECT_SS_OVERLAY_INTERNAL(name) \ + { 0, 0, NULL, NULL, NULL, &name##_InitVars, 1 } + +#define EFFECT_SS_OVERLAY_UNSET \ + { 0 } + +EffectSsOverlay gParticleOverlayTable[] = { + EFFECT_SS_OVERLAY(Effect_Ss_Dust), + EFFECT_SS_OVERLAY(Effect_Ss_Kirakira), + EFFECT_SS_OVERLAY_UNSET, + EFFECT_SS_OVERLAY(Effect_Ss_Bomb2), + EFFECT_SS_OVERLAY(Effect_Ss_Blast), + EFFECT_SS_OVERLAY(Effect_Ss_G_Spk), + EFFECT_SS_OVERLAY(Effect_Ss_D_Fire), + EFFECT_SS_OVERLAY(Effect_Ss_Bubble), + EFFECT_SS_OVERLAY_UNSET, + EFFECT_SS_OVERLAY(Effect_Ss_G_Ripple), + EFFECT_SS_OVERLAY(Effect_Ss_G_Splash), + EFFECT_SS_OVERLAY_UNSET, + EFFECT_SS_OVERLAY(Effect_Ss_G_Fire), + EFFECT_SS_OVERLAY(Effect_Ss_Lightning), + EFFECT_SS_OVERLAY(Effect_Ss_Dt_Bubble), + EFFECT_SS_OVERLAY(Effect_Ss_Hahen), + EFFECT_SS_OVERLAY(Effect_Ss_Stick), + EFFECT_SS_OVERLAY(Effect_Ss_Sibuki), + EFFECT_SS_OVERLAY_UNSET, + EFFECT_SS_OVERLAY_UNSET, + EFFECT_SS_OVERLAY(Effect_Ss_Stone1), + EFFECT_SS_OVERLAY(Effect_Ss_Hitmark), + EFFECT_SS_OVERLAY(Effect_Ss_Fhg_Flash), + EFFECT_SS_OVERLAY(Effect_Ss_K_Fire), + EFFECT_SS_OVERLAY(Effect_Ss_Solder_Srch_Ball), + EFFECT_SS_OVERLAY(Effect_Ss_Kakera), + EFFECT_SS_OVERLAY(Effect_Ss_Ice_Piece), + EFFECT_SS_OVERLAY(Effect_Ss_En_Ice), + EFFECT_SS_OVERLAY(Effect_Ss_Fire_Tail), + EFFECT_SS_OVERLAY(Effect_Ss_En_Fire), + EFFECT_SS_OVERLAY(Effect_Ss_Extra), + EFFECT_SS_OVERLAY_UNSET, + EFFECT_SS_OVERLAY(Effect_Ss_Dead_Db), + EFFECT_SS_OVERLAY(Effect_Ss_Dead_Dd), + EFFECT_SS_OVERLAY(Effect_Ss_Dead_Ds), + EFFECT_SS_OVERLAY_UNSET, + EFFECT_SS_OVERLAY(Effect_Ss_Ice_Smoke), + EFFECT_SS_OVERLAY(Effect_En_Ice_Block), + EFFECT_SS_OVERLAY(Effect_Ss_Sbn), +}; diff --git a/src/code/z_effect_soft_sprite_old_init.c b/src/code/z_effect_soft_sprite_old_init.c index f293c81c2..1c69f57f3 100644 --- a/src/code/z_effect_soft_sprite_old_init.c +++ b/src/code/z_effect_soft_sprite_old_init.c @@ -48,7 +48,7 @@ void EffectSs_DrawGEffect(GlobalContext* globalCtx, EffectSs* this, void* textur scale = this->rgScale * 0.0025f; SkinMatrix_SetTranslate(&mfTrans, this->pos.x, this->pos.y, this->pos.z); SkinMatrix_SetScale(&mfScale, scale, scale, scale); - SkinMatrix_MtxFMtxFMult(&mfTrans, &globalCtx->mf_187FC, &mfTrans11DA0); + SkinMatrix_MtxFMtxFMult(&mfTrans, &globalCtx->billboardMtxF, &mfTrans11DA0); SkinMatrix_MtxFMtxFMult(&mfTrans11DA0, &mfScale, &mfResult); gSegments[0x06] = PHYSICAL_TO_VIRTUAL(object); gSPSegment(POLY_XLU_DISP++, 0x06, object); @@ -124,32 +124,32 @@ void func_800B1054(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* EffectSsDust_Spawn(globalCtx, 1, pos, velocity, accel, primColor, envColor, scale, scaleStep, 10, 1); } -extern Color_RGBA8 D_801AE3B0; -extern Color_RGBA8 D_801AE3B4; +static Color_RGBA8 sDustBrownPrim = { 170, 130, 90, 255 }; +static Color_RGBA8 sDustBrownEnv = { 100, 60, 20, 255 }; void func_800B10C0(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel) { - EffectSsDust_Spawn(globalCtx, 4, pos, velocity, accel, &D_801AE3B0, &D_801AE3B4, 100, 5, 10, 0); + EffectSsDust_Spawn(globalCtx, 4, pos, velocity, accel, &sDustBrownPrim, &sDustBrownEnv, 100, 5, 10, 0); } void func_800B1130(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel) { - EffectSsDust_Spawn(globalCtx, 5, pos, velocity, accel, &D_801AE3B0, &D_801AE3B4, 100, 5, 10, 0); + EffectSsDust_Spawn(globalCtx, 5, pos, velocity, accel, &sDustBrownPrim, &sDustBrownEnv, 100, 5, 10, 0); } void func_800B11A0(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep) { - EffectSsDust_Spawn(globalCtx, 4, pos, velocity, accel, &D_801AE3B0, &D_801AE3B4, scale, scaleStep, 10, 0); + EffectSsDust_Spawn(globalCtx, 4, pos, velocity, accel, &sDustBrownPrim, &sDustBrownEnv, scale, scaleStep, 10, 0); } void func_800B1210(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep) { - EffectSsDust_Spawn(globalCtx, 5, pos, velocity, accel, &D_801AE3B0, &D_801AE3B4, scale, scaleStep, 10, 0); + EffectSsDust_Spawn(globalCtx, 5, pos, velocity, accel, &sDustBrownPrim, &sDustBrownEnv, scale, scaleStep, 10, 0); } void func_800B1280(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep, s16 life) { - EffectSsDust_Spawn(globalCtx, 4, pos, velocity, accel, &D_801AE3B0, &D_801AE3B4, scale, scaleStep, life, 0); + EffectSsDust_Spawn(globalCtx, 4, pos, velocity, accel, &sDustBrownPrim, &sDustBrownEnv, scale, scaleStep, life, 0); } void func_800B12F0(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep, s16 life) { - EffectSsDust_Spawn(globalCtx, 5, pos, velocity, accel, &D_801AE3B0, &D_801AE3B4, scale, scaleStep, life, 0); + EffectSsDust_Spawn(globalCtx, 5, pos, velocity, accel, &sDustBrownPrim, &sDustBrownEnv, scale, scaleStep, life, 0); } void func_800B1360(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, Color_RGBA8* primColor, @@ -206,12 +206,9 @@ void func_800B1598(GlobalContext* globalCtx, f32 randScale, Vec3f* srcPos) { } } -extern Color_RGBA8 D_801AE3B8; -extern Color_RGBA8 D_801AE3BC; - void EffectSsKiraKira_SpawnSmallYellow(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel) { - Color_RGBA8 primColor = D_801AE3B8; - Color_RGBA8 envColor = D_801AE3BC; + Color_RGBA8 primColor = { 255, 255, 200, 255 }; + Color_RGBA8 envColor = { 255, 200, 0, 0 }; EffectSsKiraKira_SpawnDispersed(globalCtx, pos, velocity, accel, &primColor, &envColor, 1000, 16); } @@ -307,12 +304,12 @@ void EffectSsBlast_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, EffectSs_Spawn(globalCtx, EFFECT_SS_BLAST, 128, &initParams); } -extern Color_RGBA8 D_801AE3C0; -extern Color_RGBA8 D_801AE3C4; - void EffectSsBlast_SpawnWhiteCustomScale(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep, s16 life) { - EffectSsBlast_Spawn(globalCtx, pos, velocity, accel, &D_801AE3C0, &D_801AE3C4, scale, scaleStep, 35, life); + static Color_RGBA8 primColor = { 255, 255, 255, 255 }; + static Color_RGBA8 envColor = { 200, 200, 200, 0 }; + + EffectSsBlast_Spawn(globalCtx, pos, velocity, accel, &primColor, &envColor, scale, scaleStep, 35, life); } void EffectSsBlast_SpawnShockwave(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, @@ -320,11 +317,11 @@ void EffectSsBlast_SpawnShockwave(GlobalContext* globalCtx, Vec3f* pos, Vec3f* v EffectSsBlast_Spawn(globalCtx, pos, velocity, accel, primColor, envColor, 100, 375, 35, life); } -extern Color_RGBA8 D_801AE3C8; -extern Color_RGBA8 D_801AE3CC; - void EffectSsBlast_SpawnWhiteShockwave(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel) { - EffectSsBlast_SpawnShockwave(globalCtx, pos, velocity, accel, &D_801AE3C8, &D_801AE3CC, 10); + static Color_RGBA8 primColor = { 255, 255, 255, 255 }; + static Color_RGBA8 envColor = { 200, 200, 200, 0 }; + + EffectSsBlast_SpawnShockwave(globalCtx, pos, velocity, accel, &primColor, &envColor, 10); } // EffectSsGSpk Spawn Functions @@ -364,24 +361,18 @@ void EffectSsGSpk_SpawnNoAccel(GlobalContext* globalCtx, Actor* actor, Vec3f* po EffectSs_Spawn(globalCtx, EFFECT_SS_G_SPK, 128, &initParams); } -extern Color_RGBA8 D_801AE3D0; -extern Color_RGBA8 D_801AE3D4; - void EffectSsGSpk_SpawnFuse(GlobalContext* globalCtx, Actor* actor, Vec3f* pos, Vec3f* velocity, Vec3f* accel) { - Color_RGBA8 primColor = D_801AE3D0; - Color_RGBA8 envColor = D_801AE3D4; + Color_RGBA8 primColor = { 255, 255, 150, 255 }; + Color_RGBA8 envColor = { 255, 0, 0, 0 }; EffectSsGSpk_SpawnSmall(globalCtx, actor, pos, velocity, accel, &primColor, &envColor); } -extern Color_RGBA8 D_801AE3D8; -extern Color_RGBA8 D_801AE3DC; - // unused void EffectSsGSpk_SpawnRandColor(GlobalContext* globalCtx, Actor* actor, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep) { - Color_RGBA8 primColor = D_801AE3D8; - Color_RGBA8 envColor = D_801AE3DC; + Color_RGBA8 primColor = { 255, 255, 150, 255 }; + Color_RGBA8 envColor = { 255, 0, 0, 0 }; s32 randOffset = (Rand_ZeroOne() * 20.0f) - 10.0f; primColor.r += randOffset; @@ -585,12 +576,10 @@ void EffectSsHahen_SpawnBurst(GlobalContext* globalCtx, Vec3f* pos, f32 burstSca } } -extern Vec3f D_801AE3E0; - void func_800B2364(GlobalContext* globalCtx, Vec3f* pos, Gfx* dList) { - Vec3f posVec = D_801AE3E0; + Vec3f accel = { 0.0f, -2.0f, 0.0f }; - EffectSsHahen_Spawn(globalCtx, pos, &D_801D15B0, &posVec, 1, 5, 1, 10, dList); + EffectSsHahen_Spawn(globalCtx, pos, &gZeroVec3f, &accel, 1, 5, 1, 10, dList); } // EffectSsStick Spawn Functions @@ -624,12 +613,9 @@ void EffectSsSibuki_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, EffectSs_Spawn(globalCtx, EFFECT_SS_SIBUKI, 128, &initParams); } -extern Vec3f D_801AE3EC; -extern Vec3f D_801AE3F8; - void EffectSsSibuki_SpawnBurst(GlobalContext* globalCtx, Vec3f* pos) { s16 i; - Vec3f zeroVec = D_801AE3EC; + Vec3f zeroVec = { 0.0f, 0.0f, 0.0f }; s16 randDirection = Rand_ZeroOne() * 1.99f; for (i = 0; i < KREG(19) + 30; i++) { @@ -759,11 +745,6 @@ void EffectSsIcePiece_Spawn(GlobalContext* globalCtx, Vec3f* pos, f32 scale, Vec EffectSs_Spawn(globalCtx, EFFECT_SS_ICE_PIECE, 128, &initParams); } -extern Vec3f D_801AE3F8; -extern Vec3f D_801AE404[10]; - -#ifdef NON_MATCHING -/* needs data migration to match */ void EffectSsIcePiece_SpawnBurst(GlobalContext* globalCtx, Vec3f* refPos, f32 scale) { static Vec3f accel = { 0.0f, 0.0f, 0.0f }; static Vec3f vecScales[] = { @@ -799,15 +780,11 @@ void EffectSsIcePiece_SpawnBurst(GlobalContext* globalCtx, Vec3f* refPos, f32 sc &accel, 25); } } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_effect_soft_sprite_old_init/EffectSsIcePiece_SpawnBurst.s") -#endif // EffectSsEnIce Spawn Functions void EffectSsEnIce_SpawnFlyingVec3f(GlobalContext* globalCtx, Actor* actor, Vec3f* pos, Color_RGBA8* prim, Color_RGBA8* env, f32 scale) { - EffectSsEnIceInitParams initParams; initParams.actor = actor; @@ -824,11 +801,11 @@ void EffectSsEnIce_SpawnFlyingVec3f(GlobalContext* globalCtx, Actor* actor, Vec3 EffectSs_Spawn(globalCtx, EFFECT_SS_EN_ICE, 80, &initParams); } -extern Color_RGBA8 D_801AE47C; -extern Color_RGBA8 D_801AE480; - void func_800B2B44(GlobalContext* globalCtx, Actor* actor, Vec3f* pos, f32 scale) { - EffectSsEnIce_SpawnFlyingVec3f(globalCtx, actor, pos, &D_801AE47C, &D_801AE480, scale); + static Color_RGBA8 primColor = { 150, 150, 150, 250 }; + static Color_RGBA8 envColor = { 235, 245, 255, 255 }; + + EffectSsEnIce_SpawnFlyingVec3f(globalCtx, actor, pos, &primColor, &envColor, scale); } void func_800B2B7C(GlobalContext* globalCtx, Actor* actor, Vec3s* arg2, f32 scale) { @@ -874,29 +851,21 @@ void EffectSsFireTail_Spawn(GlobalContext* globalCtx, Actor* actor, Vec3f* pos, EffectSs_Spawn(globalCtx, EFFECT_SS_FIRE_TAIL, 128, &initParams); } -extern Color_RGBA8 D_801AE484; -extern Color_RGBA8 D_801AE488; - -#ifdef NON_MATCHING -// needs data migration to match void EffectSsFireTail_SpawnFlame(GlobalContext* globalCtx, Actor* actor, Vec3f* pos, f32 arg3, s16 bodyPart, f32 colorIntensity) { + static Color_RGBA8 primColor = { 255, 255, 0, 255 }; + static Color_RGBA8 envColor = { 255, 0, 0, 255 }; - D_801AE484.g = (s32)(255.0f * colorIntensity); - D_801AE484.b = 0; + primColor.g = (s32)(255.0f * colorIntensity); + primColor.b = 0; - D_801AE488.g = 0; - D_801AE488.b = 0; - D_801AE484.r = D_801AE488.r = (s32)(255.0f * colorIntensity); + envColor.g = 0; + envColor.b = 0; + primColor.r = envColor.r = (s32)(255.0f * colorIntensity); - EffectSsFireTail_Spawn(globalCtx, actor, pos, arg3, &actor->velocity, 15, &D_801AE484, &D_801AE488, + EffectSsFireTail_Spawn(globalCtx, actor, pos, arg3, &actor->velocity, 15, &primColor, &envColor, (colorIntensity == 1.0f) ? 0 : 1, bodyPart, 1); } -#else -void EffectSsFireTail_SpawnFlame(GlobalContext* globalCtx, Actor* actor, Vec3f* pos, f32 arg3, s16 bodyPart, - f32 colorIntensity); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_effect_soft_sprite_old_init/EffectSsFireTail_SpawnFlame.s") -#endif void EffectSsFireTail_SpawnFlameOnPlayer(GlobalContext* globalCtx, f32 scale, s16 bodyPart, f32 colorIntensity) { Player* player = GET_PLAYER(globalCtx); @@ -982,12 +951,17 @@ void EffectSsDeadDb_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, EffectSs_Spawn(globalCtx, EFFECT_SS_DEAD_DB, 120, &initParams); } -extern Color_RGBA8 D_801AE48C; -extern Color_RGBA8 D_801AE490[4]; - void func_800B3030(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, Vec3f* accel, s16 scale, s16 scaleStep, s32 colorIndex) { - EffectSsDeadDb_Spawn(globalCtx, pos, velocity, accel, &D_801AE48C, &D_801AE490[colorIndex], scale, scaleStep, 9); + static Color_RGBA8 primColor = { 255, 255, 255, 255 }; + static Color_RGBA8 envColors[] = { + { 255, 0, 0, 255 }, + { 0, 255, 0, 255 }, + { 0, 0, 255, 255 }, + { 150, 150, 150, 255 }, + }; + + EffectSsDeadDb_Spawn(globalCtx, pos, velocity, accel, &primColor, &envColors[colorIndex], scale, scaleStep, 9); } // EffectSsDeadDd Spawn Functions @@ -1032,7 +1006,7 @@ void EffectSsDeadDs_Spawn(GlobalContext* globalCtx, Vec3f* pos, Vec3f* velocity, } void func_800B31BC(GlobalContext* globalCtx, Vec3f* pos, s16 scale, s16 scaleStep, s16 alpha, s32 life) { - EffectSsDeadDs_Spawn(globalCtx, pos, &D_801D15B0, &D_801D15B0, scale, scaleStep, alpha, life); + EffectSsDeadDs_Spawn(globalCtx, pos, &gZeroVec3f, &gZeroVec3f, scale, scaleStep, alpha, life); } // EffectSsIceSmoke Spawn Functions diff --git a/src/code/z_elf_message.c b/src/code/z_elf_message.c index a674f4564..7308b33f4 100644 --- a/src/code/z_elf_message.c +++ b/src/code/z_elf_message.c @@ -1,3 +1,62 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_elf_message/func_800F05C0.s") +u16 ElfMessage_GetFirstCycleHint(GlobalContext* globalCtx) { + if (INV_CONTENT(ITEM_OCARINA) == ITEM_OCARINA) { + return 0; + } + if (CURRENT_DAY <= 0) { + return 0; + } + if (gSaveContext.weekEventReg[88] & 0x20) { + return 0; + } + if (gSaveContext.weekEventReg[79] & 0x10) { + if (gSaveContext.weekEventReg[8] & 0x40) { + return 0; + } + return 0x224; + } + if (!(gSaveContext.weekEventReg[8] & 0x80)) { + if (gSaveContext.weekEventReg[9] & 1) { + return 0x21E; + } + if (globalCtx->sceneNum == SCENE_YOUSEI_IZUMI) { + return 0; + } + return 0x21D; + } + if (gSaveContext.magicAcquired != true) { + return 0x21F; + } + if (INV_CONTENT(ITEM_DEED_LAND) == ITEM_DEED_LAND) { + if (globalCtx->sceneNum != SCENE_OKUJOU) { + return 0x244; + } + return 0; + } + if (INV_CONTENT(ITEM_MOON_TEAR) == ITEM_MOON_TEAR) { + if (gSaveContext.weekEventReg[86] & 4) { + return 0x242; + } + return 0x243; + } + if (gSaveContext.weekEventReg[74] & 0x20) { + return 0x223; + } + if (gSaveContext.weekEventReg[73] & 0x80) { + return 0x222; + } + if (gSaveContext.weekEventReg[73] & 0x20) { + return 0x221; + } + if (gSaveContext.weekEventReg[77] & 2) { + if (gSaveContext.weekEventReg[73] & 0x10) { + return 0x240; + } + return 0x241; + } + if ((gSaveContext.weekEventReg[86] & 2) || (gSaveContext.weekEventReg[73] & 0x40)) { + return 0x23F; + } + return 0x220; +} diff --git a/src/code/z_en_hy.c b/src/code/z_en_hy.c new file mode 100644 index 000000000..323dc14f8 --- /dev/null +++ b/src/code/z_en_hy.c @@ -0,0 +1,271 @@ +/* + * File: z_en_hy.c + * Description: Unused System for NPCs (includes animation, door interaction, blinking, pathing, and collider helpers) + */ + +#include "global.h" +#include "overlays/actors/ovl_En_Door/z_en_door.h" + +extern AnimationHeader D_0600007C; +extern AnimationHeader D_0600066C; +extern AnimationHeader D_0600071C; +extern AnimationHeader D_060008C0; +extern AnimationHeader D_06000AB0; +extern AnimationHeader D_06000FDC; +extern AnimationHeader D_06001494; +extern AnimationHeader D_06001908; +extern AnimationHeader D_06001EE0; +extern AnimationHeader D_06005DC4; +extern AnimationHeader D_06005D9C; +extern AnimationHeader D_0600DED8; +extern AnimationHeader D_0600F920; +extern AnimationHeader D_0600FC1C; +extern AnimationHeader D_0600FEE4; +extern AnimationHeader D_06010330; + +static ActorAnimationEntryS animations[] = { + { &D_0600007C, 1.0f, 0, -1, 0, 0 }, { &D_06001494, 1.0f, 0, -1, 0, 0 }, { &D_06001494, 1.0f, 0, -1, 0, -8 }, + { &D_06001908, 1.0f, 0, -1, 0, 0 }, { &D_06001908, 1.0f, 0, -1, 0, -8 }, { &D_060008C0, 1.0f, 0, -1, 0, 0 }, + { &D_06005DC4, 1.0f, 0, -1, 0, 0 }, { &D_06000FDC, 1.0f, 0, -1, 0, 0 }, { &D_06000AB0, 1.0f, 0, -1, 0, -8 }, + { &D_0600066C, 1.0f, 0, -1, 0, 0 }, { &D_0600071C, 1.0f, 0, -1, 0, 0 }, { &D_06001EE0, 1.0f, 0, -1, 0, 0 }, + { &D_0600DED8, 1.5f, 0, -1, 2, 0 }, { &D_0600F920, 1.5f, 0, -1, 2, 0 }, { &D_0600FC1C, 1.0f, 0, -1, 0, 0 }, + { &D_0600FEE4, 1.0f, 0, -1, 0, 0 }, { &D_06010330, 1.0f, 0, -1, 0, 0 }, { &D_0600FC1C, 1.0f, 0, -1, 0, -8 }, + { &D_0600FEE4, 1.0f, 0, -1, 0, -8 }, { &D_06010330, 1.0f, 0, -1, 0, -8 }, { &D_06005D9C, 1.0f, 0, -1, 0, -8 }, +}; + +s8 D_801BC3F0[] = { -1, 1, 12, 13, 14, 9, 10, 11, 0, 6, 7, 8, 3, 4, 5, 2 }; + +s8 D_801BC400[] = { 0, 0, 0, 0, 3, 4, 0, 6, 7, 0, 9, 10, 0, 12, 13, 0 }; + +u8 D_801BC410[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +s32 EnHy_ChangeAnim(SkelAnime* skelAnime, s16 animIndex) { + s16 frameCount; + s32 isChanged = false; + + if (animIndex >= 0 && animIndex <= 20) { + isChanged = true; + frameCount = animations[animIndex].frameCount; + if (frameCount < 0) { + frameCount = Animation_GetLastFrame(&animations[animIndex].animationSeg->common); + } + Animation_Change(skelAnime, animations[animIndex].animationSeg, animations[animIndex].playbackSpeed, + animations[animIndex].frame, frameCount, animations[animIndex].mode, + animations[animIndex].transitionRate); + } + return isChanged; +} + +//! @TODO: Return Door instance when c and h files are split +Actor* EnHy_FindNearestDoor(Actor* actor, GlobalContext* globalCtx) { + Actor* nearestDoor = NULL; + Actor* doorIter = NULL; + Actor* door; + f32 dist; + s32 isSetup = false; + f32 minDist = 0.0f; + + do { + doorIter = SubS_FindActor(globalCtx, doorIter, ACTORCAT_DOOR, ACTOR_EN_DOOR); + door = doorIter; + dist = Actor_DistanceBetweenActors(actor, door); + if (!isSetup || (dist < minDist)) { + nearestDoor = door; + minDist = dist; + isSetup = true; + } + doorIter = door->next; + } while (doorIter != NULL); + + if (1) {} + + return nearestDoor; +} + +void EnHy_ChangeObjectAndAnim(EnHy* enHy, GlobalContext* globalCtx, s16 animIndex) { + gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[enHy->animObjIndex].segment); + EnHy_ChangeAnim(&enHy->skelAnime, animIndex); +} + +s32 EnHy_UpdateSkelAnime(EnHy* enHy, GlobalContext* globalCtx) { + s32 isUpdated = false; + + if (enHy->actor.draw != NULL) { + gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[enHy->animObjIndex].segment); + SkelAnime_Update(&enHy->skelAnime); + isUpdated = true; + } + return isUpdated; +} + +void EnHy_Blink(EnHy* enHy, s32 eyeTexMaxIndex) { + if (DECR(enHy->blinkTimer) == 0) { + enHy->eyeTexIndex++; + if (enHy->eyeTexIndex >= eyeTexMaxIndex) { + enHy->eyeTexIndex = 0; + enHy->blinkTimer = Rand_S16Offset(30, 30); + } + } +} + +s32 EnHy_Init(EnHy* enHy, GlobalContext* globalCtx, FlexSkeletonHeader* skeletonHeaderSeg, s16 animIndex) { + s32 isInitialized = false; + + if ((func_8013D8DC(enHy->animObjIndex, globalCtx) == 1) && (func_8013D8DC(enHy->unk190, globalCtx) == 1) && + (func_8013D8DC(enHy->unk191, globalCtx) == 1) && (func_8013D8DC(enHy->unk192, globalCtx) == 1)) { + enHy->actor.objBankIndex = enHy->unk192; + isInitialized = true; + ActorShape_Init(&enHy->actor.shape, 0.0f, NULL, 0.0f); + gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[enHy->actor.objBankIndex].segment); + SkelAnime_InitFlex(globalCtx, &enHy->skelAnime, skeletonHeaderSeg, NULL, enHy->jointTable, enHy->morphTable, + 16); + EnHy_ChangeObjectAndAnim(enHy, globalCtx, animIndex); + } + return isInitialized; +} + +//! @TODO: Should just take EnDoor instead of actor when c and h are split +void func_800F0BB4(EnHy* enHy, GlobalContext* globalCtx, Actor* door, s16 arg3, s16 arg4) { + s32 pad; + s8 sp3B; + Vec3f offset; + f32 phi_f0; + + Actor_CalcOffsetOrientedToDrawRotation(door, &offset, &enHy->actor.world.pos); + phi_f0 = (offset.z >= 0.0f) ? 1.0f : -1.0f; + sp3B = ((s8)phi_f0 < 0) ? 0 : 2; + EnHy_ChangeObjectAndAnim(enHy, globalCtx, (sp3B == 0) ? arg3 : arg4); + enHy->skelAnime.baseTransl = *enHy->skelAnime.jointTable; + enHy->skelAnime.prevTransl = *enHy->skelAnime.jointTable; + enHy->skelAnime.moveFlags |= 3; + AnimationContext_SetMoveActor(globalCtx, &enHy->actor, &enHy->skelAnime, 1.0f); + ((EnDoor*)door)->unk_1A1 = 1; + ((EnDoor*)door)->unk_1A0 = sp3B; +} + +s32 func_800F0CE4(EnHy* enHy, GlobalContext* globalCtx, ActorFunc draw, s16 arg3, s16 arg4, f32 arg5) { + s32 ret = false; + s16 yaw; + Actor* door; + s32 pad; + + if (func_8013D68C(enHy->path, enHy->curPoint, &enHy->actor.world.pos)) { + door = EnHy_FindNearestDoor(&enHy->actor, globalCtx); + if (door != NULL) { + ret = true; + func_800F0BB4(enHy, globalCtx, door, arg3, arg4); + yaw = Math_Vec3f_Yaw(&enHy->actor.world.pos, &door->world.pos); + enHy->actor.world.pos.x += arg5 * Math_SinS(yaw); + enHy->actor.world.pos.z += arg5 * Math_CosS(yaw); + enHy->actor.world.rot.y = -yaw; + enHy->actor.shape.rot.y = -yaw; + enHy->actor.draw = draw; + } + } + return ret; +} + +s32 func_800F0DD4(EnHy* enHy, GlobalContext* globalCtx, s16 arg2, s16 arg3) { + s32 ret = false; + s32 pad; + Actor* door; + + enHy->curPoint = 0; + if (func_8013D68C(enHy->path, enHy->curPoint, &enHy->actor.world.pos)) { + door = EnHy_FindNearestDoor(&enHy->actor, globalCtx); + if (door != NULL) { + ret = true; + func_800F0BB4(enHy, globalCtx, door, arg2, arg3); + enHy->actor.shape.rot.y = Math_Vec3f_Yaw(&enHy->actor.world.pos, &door->world.pos); + enHy->actor.world.rot.y = enHy->actor.shape.rot.y; + enHy->actor.gravity = 0.0f; + enHy->actor.flags &= ~1; + } + } + return ret; +} + +s32 EnHy_SetPointFowards(EnHy* enHy, GlobalContext* globalCtx, f32 gravity, s16 animIndex) { + enHy->actor.gravity = gravity; + enHy->actor.flags |= 1; + EnHy_ChangeObjectAndAnim(enHy, globalCtx, animIndex); + enHy->curPoint++; + return 0; +} + +s32 EnHy_SetPointBackwards(EnHy* enHy, GlobalContext* globalCtx, s16 animIndex) { + EnHy_ChangeObjectAndAnim(enHy, globalCtx, animIndex); + enHy->curPoint--; + return 0; +} + +s32 EnHy_MoveForwards(EnHy* enHy, f32 speedTarget) { + s16 rotStep; + s32 reachedEnd = false; + Vec3f curPointPos; + + Math_SmoothStepToF(&enHy->actor.speedXZ, speedTarget, 0.4f, 1000.0f, 0.0f); + rotStep = enHy->actor.speedXZ * 400.0f; + if (func_8013D68C(enHy->path, enHy->curPoint, &curPointPos) && func_8013D768(&enHy->actor, &curPointPos, rotStep)) { + enHy->curPoint++; + if (enHy->curPoint >= enHy->path->count) { + reachedEnd = true; + } + } + return reachedEnd; +} + +s32 EnHy_MoveBackwards(EnHy* enHy, f32 speedTarget) { + s16 rotStep; + s32 reachedEnd = false; + Vec3f curPointPos; + + Math_SmoothStepToF(&enHy->actor.speedXZ, speedTarget, 0.4f, 1000.0f, 0.0f); + rotStep = enHy->actor.speedXZ * 400.0f; + if (func_8013D68C(enHy->path, enHy->curPoint, &curPointPos) && func_8013D768(&enHy->actor, &curPointPos, rotStep)) { + enHy->curPoint--; + if (enHy->curPoint < 0) { + reachedEnd = true; + } + } + return reachedEnd; +} + +void EnHy_UpdateCollider(EnHy* enHy, GlobalContext* globalCtx) { + enHy->collider.dim.pos.x = enHy->actor.world.pos.x; + enHy->collider.dim.pos.y = enHy->actor.world.pos.y; + enHy->collider.dim.pos.z = enHy->actor.world.pos.z; + + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &enHy->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &enHy->collider.base); +} + +s32 EnHy_PlayWalkingSound(EnHy* enHy, GlobalContext* globalCtx, f32 distAboveThreshold) { + u8 wasLeftFootOnGround = enHy->isLeftFootOnGround; + u8 wasRightFootOnGround = enHy->isRightFootOnGround; + s32 waterSfxId; + u16 sfxId; + u8 isFootOnGround; + + if (enHy->actor.bgCheckFlags & 0x20) { + if (enHy->actor.depthInWater < 20.0f) { + waterSfxId = NA_SE_PL_WALK_WATER0 - SFX_FLAG; + } else { + waterSfxId = NA_SE_PL_WALK_WATER1 - SFX_FLAG; + } + sfxId = waterSfxId + SFX_FLAG; + } else { + sfxId = SurfaceType_GetSfx(&globalCtx->colCtx, enHy->actor.floorPoly, enHy->actor.floorBgId) + SFX_FLAG; + } + + enHy->isLeftFootOnGround = isFootOnGround = func_8013DB90(globalCtx, &enHy->leftFootPos, distAboveThreshold); + if (enHy->isLeftFootOnGround && !wasLeftFootOnGround && isFootOnGround) { + Audio_PlayActorSound2(&enHy->actor, sfxId); + } + + enHy->isRightFootOnGround = isFootOnGround = func_8013DB90(globalCtx, &enHy->rightFootPos, distAboveThreshold); + if (enHy->isRightFootOnGround && !wasRightFootOnGround && isFootOnGround) { + Audio_PlayActorSound2(&enHy->actor, sfxId); + } + return 0; +} diff --git a/src/code/z_en_item00.c b/src/code/z_en_item00.c index acd827f8e..f2fb0e45a 100644 --- a/src/code/z_en_item00.c +++ b/src/code/z_en_item00.c @@ -828,29 +828,22 @@ s16 func_800A7650(s16 dropId) { return dropId; } -#ifdef NON_MATCHING -// Reordering issues -EnItem00* Item_DropCollectible(GlobalContext* globalCtx, Vec3f* spawnPos, u32 params) { +Actor* Item_DropCollectible(GlobalContext* globalCtx, Vec3f* spawnPos, u32 params) { s32 pad; - EnItem00* spawnedActor = NULL; - s32 pad2; - s32 param10000; - s16 param8000; - s16 param7F00; - s32 param20000; - s32 paramFF; + Actor* spawnedActor = NULL; + s32 newParamFF; + s32 param10000 = params & 0x10000; + s16 param8000 = params & 0x8000; + s16 param7F00 = params & 0x7F00; + s32 param20000 = params & 0x20000; + s32 paramFF = params & 0xFF; s32 i; - param10000 = params & 0x10000; - param8000 = params & 0x8000; - param7F00 = params & 0x7F00; - param20000 = params & 0x20000; - paramFF = params & 0xFF; - params &= 0x7FFF; + newParamFF = params & 0xFF; if (paramFF == ITEM00_3_HEARTS) { - for (i = 0; i != 3; i++) { + for (i = 0; i < 3; i++) { spawnedActor = Item_DropCollectible(globalCtx, spawnPos, param7F00 | ITEM00_HEART | param8000); } } else if (paramFF == ITEM00_MUSHROOM_CLOUD) { @@ -859,20 +852,18 @@ EnItem00* Item_DropCollectible(GlobalContext* globalCtx, Vec3f* spawnPos, u32 pa Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_OBJ_KINOKO, spawnPos->x, spawnPos->y, spawnPos->z, 0, 0, 0, param7F00); } - } else if (((paramFF == ITEM00_FLEXIBLE) || ((params & 0xFF) == ITEM00_BIG_FAIRY)) && (param10000 == 0)) { - if ((params & 0xFF) == ITEM00_FLEXIBLE) { - // TODO: fix cast, this actor is not an EnItem00 - spawnedActor = - (EnItem00*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELF, spawnPos->x, spawnPos->y + 40.0f, + } else if (((paramFF == ITEM00_FLEXIBLE) || (newParamFF == ITEM00_BIG_FAIRY)) && (param10000 == 0)) { + newParamFF = params & 0xFF; + if (newParamFF == ITEM00_FLEXIBLE) { + spawnedActor = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELF, spawnPos->x, spawnPos->y + 40.0f, spawnPos->z, 0, 0, 0, ((((param7F00 >> 8) & 0x7F) << 9) & 0xFE00) | 0x102); if (!Actor_GetCollectibleFlag(globalCtx, (param7F00 >> 8) & 0x7F)) { Audio_PlaySoundAtPosition(globalCtx, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY); } } else { - // TODO: fix cast, this actor is not an EnItem00 - spawnedActor = (EnItem00*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELFORG, spawnPos->x, - spawnPos->y + 40.0f, spawnPos->z, 0, 0, 0, - ((((param7F00 >> 8) & 0x7F) & 0x7F) << 9) | 7); + spawnedActor = + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELFORG, spawnPos->x, spawnPos->y + 40.0f, + spawnPos->z, 0, 0, 0, ((((param7F00 >> 8) & 0x7F) & 0x7F) << 9) | 7); if (param20000 == 0) { if (!Actor_GetCollectibleFlag(globalCtx, (param7F00 >> 8) & 0x7F)) { Audio_PlaySoundAtPosition(globalCtx, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY); @@ -881,59 +872,50 @@ EnItem00* Item_DropCollectible(GlobalContext* globalCtx, Vec3f* spawnPos, u32 pa } } else { if (param8000 == 0) { - params = func_800A7650(params & 0xFF); + params = func_800A7650(newParamFF); } - if (params != (u32)ITEM00_NO_DROP) { - spawnedActor = (EnItem00*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ITEM00, spawnPos->x, - spawnPos->y, spawnPos->z, 0, 0, 0, params | param8000 | param7F00); + if ((s32)params != ITEM00_NO_DROP) { + spawnedActor = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ITEM00, spawnPos->x, spawnPos->y, + spawnPos->z, 0, 0, 0, (s32)params | param8000 | param7F00); if ((spawnedActor != NULL) && (param8000 == 0)) { if (param10000 == 0) { - spawnedActor->actor.velocity.y = 8.0f; + spawnedActor->velocity.y = 8.0f; } else { - spawnedActor->actor.velocity.y = -2.0f; + spawnedActor->velocity.y = -2.0f; } - spawnedActor->actor.speedXZ = 2.0f; - spawnedActor->actor.gravity = -0.9f; - spawnedActor->actor.world.rot.y = randPlusMinusPoint5Scaled(65536.0f); - Actor_SetScale(&spawnedActor->actor, 0.0f); - spawnedActor->actionFunc = func_800A6780; - spawnedActor->unk152 = 0xDC; - if ((spawnedActor->actor.params != ITEM00_SMALL_KEY) && - (spawnedActor->actor.params != ITEM00_HEART_PIECE) && - (spawnedActor->actor.params != ITEM00_HEART_CONTAINER)) { - spawnedActor->actor.room = -1; + spawnedActor->speedXZ = 2.0f; + spawnedActor->gravity = -0.9f; + spawnedActor->world.rot.y = randPlusMinusPoint5Scaled(65536.0f); + Actor_SetScale(spawnedActor, 0.0f); + ((EnItem00*)spawnedActor)->actionFunc = func_800A6780; + ((EnItem00*)spawnedActor)->unk152 = 0xDC; + if ((spawnedActor->params != ITEM00_SMALL_KEY) && (spawnedActor->params != ITEM00_HEART_PIECE) && + (spawnedActor->params != ITEM00_HEART_CONTAINER)) { + spawnedActor->room = -1; } - spawnedActor->actor.flags |= 0x0010; + spawnedActor->flags |= 0x0010; } } } return spawnedActor; } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_en_item00/Item_DropCollectible.s") -#endif -#ifdef NON_MATCHING -// Regalloc, minor reordering -Actor* Item_DropCollectible2(GlobalContext* globalCtx, Vec3f* spawnPos, u32 params) { +Actor* Item_DropCollectible2(GlobalContext* globalCtx, Vec3f* spawnPos, s32 params) { Actor* spawnedActor = NULL; - u32 pad; - u32 param10000; - s16 param8000; - s16 param7F00; + s32 pad; + s32 param10000 = params & 0x10000; + s16 param8000 = params & 0x8000; + s16 param7F00 = params & 0x7F00; - param10000 = params & 0x10000; - param8000 = params & 0x8000; - param7F00 = params & 0x7F00; params &= 0xFF; - if (params == ITEM00_3_HEARTS) { + if ((params & 0xFF) == ITEM00_3_HEARTS) { return NULL; } - if (((params == ITEM00_FLEXIBLE) || (params == ITEM00_BIG_FAIRY)) && (param10000 == 0)) { - if (params == ITEM00_FLEXIBLE) { + if ((((params & 0xFF) == ITEM00_FLEXIBLE) || ((params & 0xFF) == ITEM00_BIG_FAIRY)) && (param10000 == 0)) { + if ((params & 0xFF) == ITEM00_FLEXIBLE) { spawnedActor = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELF, spawnPos->x, spawnPos->y + 40.0f, spawnPos->z, 0, 0, 0, ((((param7F00 >> 8) & 0x7F) << 9) & 0xFE00) | 0x102); } else { @@ -945,10 +927,10 @@ Actor* Item_DropCollectible2(GlobalContext* globalCtx, Vec3f* spawnPos, u32 para Audio_PlaySoundAtPosition(globalCtx, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY); } } else { - params = func_800A7650(params); - if (params != (u32)ITEM00_NO_DROP) { + params = func_800A7650(params & 0xFF); + if (params != ITEM00_NO_DROP) { spawnedActor = Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ITEM00, spawnPos->x, spawnPos->y, - spawnPos->z, 0, 0, 0, params | param8000 | param7F00); + spawnPos->z, 0, 0, 0, (s32)params | param8000 | param7F00); if (spawnedActor != NULL) { if (param8000 == 0) { spawnedActor->velocity.y = 0.0f; @@ -967,9 +949,6 @@ Actor* Item_DropCollectible2(GlobalContext* globalCtx, Vec3f* spawnPos, u32 para return spawnedActor; } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_en_item00/Item_DropCollectible2.s") -#endif u8 sDropTable[DROP_TABLE_SIZE * DROP_TABLE_NUMBER] = { ITEM00_RUPEE_GREEN, ITEM00_RUPEE_GREEN, ITEM00_RUPEE_BLUE, ITEM00_NO_DROP, ITEM00_NO_DROP, @@ -1047,17 +1026,14 @@ u8 sDropTableAmounts[DROP_TABLE_SIZE * DROP_TABLE_NUMBER] = { 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, }; -#ifdef NON_MATCHING -// Many regalloc and reordering issues void Item_DropCollectibleRandom(GlobalContext* globalCtx, Actor* fromActor, Vec3f* spawnPos, s16 params) { EnItem00* spawnedActor; u8 dropId; s32 dropQuantity; - s16 dropTableIndex; - s16 param8000; + s16 dropTableIndex = Rand_ZeroOne() * 16.0f; + s16 param8000 = params & 0x8000; + u8 dropFlag; - dropTableIndex = Rand_ZeroOne() * 16.0f; - param8000 = params & 0x8000; params &= 0x1F0; if (params < 0x101) { @@ -1065,50 +1041,54 @@ void Item_DropCollectibleRandom(GlobalContext* globalCtx, Actor* fromActor, Vec3 dropQuantity = sDropTableAmounts[params + dropTableIndex]; if (dropId == ITEM00_MASK) { - dropQuantity = 1; - if (gSaveContext.playerForm != PLAYER_FORM_GORON) { - if (gSaveContext.playerForm != PLAYER_FORM_ZORA) { - if (gSaveContext.playerForm != PLAYER_FORM_HUMAN) { - dropId = ITEM00_RUPEE_GREEN; - } else { - dropId = ITEM00_ARROWS_10; - } - } else { + switch (gSaveContext.playerForm) { + case PLAYER_FORM_HUMAN: + dropId = ITEM00_ARROWS_10; + break; + case PLAYER_FORM_ZORA: dropId = ITEM00_HEART; - } - } else { - dropId = ITEM00_MAGIC_SMALL; + break; + case PLAYER_FORM_GORON: + dropId = ITEM00_MAGIC_SMALL; + break; + default: + dropId = ITEM00_RUPEE_GREEN; + break; } + dropQuantity = 1; } if (fromActor != NULL) { - if (fromActor->dropFlag != 0) { - if ((fromActor->dropFlag & 1) != 0) { + dropFlag = fromActor->dropFlag; + if (dropFlag != 0) { + if (fromActor->dropFlag & 1) { + params = 0x10; dropId = ITEM00_ARROWS_30; + dropQuantity = 1; + } else if (fromActor->dropFlag & 2) { params = 0x10; - } else if ((fromActor->dropFlag & 2) != 0) { dropId = ITEM00_HEART; - params = 0x10; - } else if ((fromActor->dropFlag & 0x20) != 0) { + dropQuantity = 1; + } else if (fromActor->dropFlag & 0x20) { dropId = ITEM00_RUPEE_PURPLE; + dropQuantity = 1; } - dropQuantity = 1; } } if (dropId == ITEM00_FLEXIBLE) { - if (gSaveContext.health < 0x11) { + if (gSaveContext.health <= 0x10) { Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELF, spawnPos->x, spawnPos->y + 40.0f, spawnPos->z, 0, 0, 0, 2); Audio_PlaySoundAtPosition(globalCtx, spawnPos, 40, NA_SE_EV_BUTTERFRY_TO_FAIRY); return; } - if (gSaveContext.health < 0x31) { + if (gSaveContext.health <= 0x30) { params = 0x10; dropId = ITEM00_HEART; dropQuantity = 3; - } else if (gSaveContext.health < 0x51) { + } else if (gSaveContext.health <= 0x50) { params = 0x10; dropId = ITEM00_HEART; dropQuantity = 1; @@ -1132,6 +1112,8 @@ void Item_DropCollectibleRandom(GlobalContext* globalCtx, Actor* fromActor, Vec3 params = 0xA0; dropId = ITEM00_RUPEE_RED; dropQuantity = 1; + } else { + return; } } @@ -1167,18 +1149,16 @@ void Item_DropCollectibleRandom(GlobalContext* globalCtx, Actor* fromActor, Vec3 } } } -#else -#pragma GLOBAL_ASM("asm/non_matchings/code/z_en_item00/Item_DropCollectibleRandom.s") -#endif -s32 D_801AE194[32] = { ITEM00_NO_DROP, ITEM00_RUPEE_GREEN, ITEM00_RUPEE_BLUE, ITEM00_NO_DROP, - ITEM00_RUPEE_RED, ITEM00_RUPEE_PURPLE, ITEM00_NO_DROP, ITEM00_RUPEE_HUGE, - ITEM00_COMPASS, ITEM00_MUSHROOM_CLOUD, ITEM00_HEART, ITEM00_3_HEARTS, - ITEM00_HEART_PIECE, ITEM00_HEART_CONTAINER, ITEM00_MAGIC_SMALL, ITEM00_MAGIC_LARGE, - ITEM00_FLEXIBLE, ITEM00_BIG_FAIRY, ITEM00_NO_DROP, ITEM00_NUTS_10, - ITEM00_NO_DROP, ITEM00_BOMBS_A, ITEM00_NO_DROP, ITEM00_NO_DROP, - ITEM00_NO_DROP, ITEM00_STICK, ITEM00_NO_DROP, ITEM00_NO_DROP, - ITEM00_NO_DROP, ITEM00_NO_DROP, ITEM00_ARROWS_10, ITEM00_ARROWS_30 }; +s32 D_801AE194[32] = { + ITEM00_NO_DROP, ITEM00_RUPEE_GREEN, ITEM00_RUPEE_BLUE, ITEM00_NO_DROP, ITEM00_RUPEE_RED, + ITEM00_RUPEE_PURPLE, ITEM00_NO_DROP, ITEM00_RUPEE_HUGE, ITEM00_COMPASS, ITEM00_MUSHROOM_CLOUD, + ITEM00_HEART, ITEM00_3_HEARTS, ITEM00_HEART_PIECE, ITEM00_HEART_CONTAINER, ITEM00_MAGIC_SMALL, + ITEM00_MAGIC_LARGE, ITEM00_FLEXIBLE, ITEM00_BIG_FAIRY, ITEM00_NO_DROP, ITEM00_NUTS_10, + ITEM00_NO_DROP, ITEM00_BOMBS_A, ITEM00_NO_DROP, ITEM00_NO_DROP, ITEM00_NO_DROP, + ITEM00_STICK, ITEM00_NO_DROP, ITEM00_NO_DROP, ITEM00_NO_DROP, ITEM00_NO_DROP, + ITEM00_ARROWS_10, ITEM00_ARROWS_30, +}; s32 func_800A8150(s32 index) { if ((index < 0) || (index >= ARRAY_COUNT(D_801AE194))) { @@ -1188,9 +1168,7 @@ s32 func_800A8150(s32 index) { return D_801AE194[index]; } -u8 D_801AE214[32] = { - 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; +u8 D_801AE214[32] = { 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; s32 func_800A817C(s32 index) { if ((index < 0) || (index >= ARRAY_COUNT(D_801AE214))) { diff --git a/src/code/z_face_reaction.c b/src/code/z_face_reaction.c index a6a6da5b3..d54561fdd 100644 --- a/src/code/z_face_reaction.c +++ b/src/code/z_face_reaction.c @@ -3,7 +3,7 @@ /** * Indices of the columns of this array: * - index 0x00: PLAYER_MASK_TRUTH - * - index 0x01: PLAYER_MASK_KAFEI + * - index 0x01: PLAYER_MASK_KAFEIS_MASK * - index 0x02: PLAYER_MASK_ALL_NIGHT * - index 0x03: PLAYER_MASK_BUNNY * - index 0x04: PLAYER_MASK_KEATON diff --git a/src/code/z_fireobj.c b/src/code/z_fireobj.c index 6e543d115..7c5de646a 100644 --- a/src/code/z_fireobj.c +++ b/src/code/z_fireobj.c @@ -1,5 +1,6 @@ #include "global.h" #include "overlays/actors/ovl_En_Arrow/z_en_arrow.h" +#include "objects/gameplay_keep/gameplay_keep.h" typedef enum { FIRE_STATE_0, @@ -162,7 +163,7 @@ void FireObj_Draw(GlobalContext* globalCtx, FireObj* fire) { Matrix_Scale(fire->xScale, fire->yScale, 1.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, D_0407D590); + gSPDisplayList(POLY_XLU_DISP++, gGameplayKeepDrawFlameDL); CLOSE_DISPS(globalCtx->state.gfxCtx); } } diff --git a/src/code/z_game_over.c b/src/code/z_game_over.c index 979b28cba..15f3a6693 100644 --- a/src/code/z_game_over.c +++ b/src/code/z_game_over.c @@ -44,7 +44,7 @@ void GameOver_Update(GlobalContext* globalCtx) { } gSaveContext.unk_3DC0 = 2000; - gSaveContext.naviTimer = 0; + gSaveContext.tatlTimer = 0; gSaveContext.seqIndex = (u8)NA_BGM_DISABLED; gSaveContext.nightSeqIndex = 0xFF; gSaveContext.eventInf[0] = 0; diff --git a/src/code/z_kaleido_manager.c b/src/code/z_kaleido_manager.c index c79b0067f..318b033f6 100644 --- a/src/code/z_kaleido_manager.c +++ b/src/code/z_kaleido_manager.c @@ -1,15 +1,104 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kaleido_manager/D_801DF9C0.s") +#define KALEIDO_OVERLAY(name) \ + { \ + NULL, SEGMENT_ROM_START(ovl_##name), SEGMENT_ROM_END(ovl_##name), SEGMENT_START(ovl_##name), \ + SEGMENT_END(ovl_##name), 0, #name, \ + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kaleido_manager/func_80163700.s") +KaleidoMgrOverlay gKaleidoMgrOverlayTable[] = { + KALEIDO_OVERLAY(kaleido_scope), + KALEIDO_OVERLAY(player_actor), +}; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kaleido_manager/func_80163758.s") +void* sKaleidoAreaPtr = NULL; +KaleidoMgrOverlay* gKaleidoMgrCurOvl = NULL; +FaultAddrConvClient sKaleidoAreaFaultClient; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kaleido_manager/func_801637B4.s") +void* KaleidoManager_FaultAddrConvFunc(void* address, void* param) { + u8* ptr = address; + KaleidoMgrOverlay* ovl = &gKaleidoMgrCurOvl[0]; + u8* ramStart; + u8* ramEnd; + size_t size; + uintptr_t offset; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kaleido_manager/func_80163804.s") + if (ovl != NULL) { + size = (u8*)ovl->vramEnd - (u8*)ovl->vramStart; + ramStart = ovl->loadedRamAddr; + ramEnd = ramStart + size; + offset = (u8*)ovl->vramStart - ramStart; + if (ramStart != NULL) { + if (ptr >= ramStart && ptr < ramEnd) { + return ptr + offset; + } + } + } + return NULL; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kaleido_manager/func_8016388C.s") +void KaleidoManager_LoadOvl(KaleidoMgrOverlay* ovl) { + ovl->loadedRamAddr = sKaleidoAreaPtr; + Load2_LoadOverlay(ovl->vromStart, ovl->vromEnd, ovl->vramStart, ovl->vramEnd, ovl->loadedRamAddr); + ovl->offset = (uintptr_t)ovl->loadedRamAddr - (uintptr_t)ovl->vramStart; + gKaleidoMgrCurOvl = ovl; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kaleido_manager/func_801638D8.s") +void KaleidoManager_ClearOvl(KaleidoMgrOverlay* ovl) { + if (ovl->loadedRamAddr != NULL) { + ovl->offset = 0; + bzero(ovl->loadedRamAddr, (uintptr_t)ovl->vramEnd - (uintptr_t)ovl->vramStart); + ovl->loadedRamAddr = NULL; + gKaleidoMgrCurOvl = NULL; + } +} + +void KaleidoManager_Init(GlobalContext* globalCtx) { + s32 largestSize = 0; + s32 size; + u32 i; + + for (i = 0; i < ARRAY_COUNT(gKaleidoMgrOverlayTable); i++) { + size = (uintptr_t)gKaleidoMgrOverlayTable[i].vramEnd - (uintptr_t)gKaleidoMgrOverlayTable[i].vramStart; + if (size > largestSize) { + largestSize = size; + } + } + + sKaleidoAreaPtr = THA_AllocEndAlign16(&globalCtx->state.heap, largestSize); + gKaleidoMgrCurOvl = NULL; + Fault_AddAddrConvClient(&sKaleidoAreaFaultClient, KaleidoManager_FaultAddrConvFunc, NULL); +} + +void KaleidoManager_Destroy() { + Fault_RemoveAddrConvClient(&sKaleidoAreaFaultClient); + + if (gKaleidoMgrCurOvl != NULL) { + KaleidoManager_ClearOvl(gKaleidoMgrCurOvl); + gKaleidoMgrCurOvl = NULL; + } + + sKaleidoAreaPtr = NULL; +} + +void* KaleidoManager_GetRamAddr(void* vram) { + if (gKaleidoMgrCurOvl == NULL) { + s32 pad[2]; + KaleidoMgrOverlay* ovl = &gKaleidoMgrOverlayTable[0]; + + do { + if (((uintptr_t)vram >= (uintptr_t)ovl->vramStart) && ((uintptr_t)ovl->vramEnd >= (uintptr_t)vram)) { + KaleidoManager_LoadOvl(ovl); + return (void*)((uintptr_t)vram + ovl->offset); + } + ovl++; + } while (ovl != (KaleidoMgrOverlay*)&sKaleidoAreaPtr); + + return NULL; + } else if (((uintptr_t)vram < (uintptr_t)gKaleidoMgrCurOvl->vramStart) || + ((uintptr_t)vram >= (uintptr_t)gKaleidoMgrCurOvl->vramEnd)) { + return NULL; + } + + return (void*)((uintptr_t)vram + gKaleidoMgrCurOvl->offset); +} diff --git a/src/code/z_kaleido_scope_call.c b/src/code/z_kaleido_scope_call.c index 58f30ae16..b6d46eba1 100644 --- a/src/code/z_kaleido_scope_call.c +++ b/src/code/z_kaleido_scope_call.c @@ -1,11 +1,84 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kaleido_scope_call/func_801639A0.s") +void (*sKaleidoScopeUpdateFunc)(GlobalContext* globalCtx); +void (*sKaleidoScopeDrawFunc)(GlobalContext* globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kaleido_scope_call/func_801639EC.s") +extern void KaleidoScope_Update(GlobalContext* globalCtx); +extern void KaleidoScope_Draw(GlobalContext* globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kaleido_scope_call/func_80163A38.s") +void KaleidoScopeCall_LoadPlayer() { + KaleidoMgrOverlay* playerActorOvl = &gKaleidoMgrOverlayTable[KALEIDO_OVL_PLAYER_ACTOR]; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kaleido_scope_call/func_80163A58.s") + if (gKaleidoMgrCurOvl != playerActorOvl) { + if (gKaleidoMgrCurOvl != NULL) { + KaleidoManager_ClearOvl(gKaleidoMgrCurOvl); + } -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kaleido_scope_call/func_80163C0C.s") + KaleidoManager_LoadOvl(playerActorOvl); + } +} + +void KaleidoScopeCall_Init(GlobalContext* globalCtx) { + sKaleidoScopeUpdateFunc = KaleidoManager_GetRamAddr(KaleidoScope_Update); + sKaleidoScopeDrawFunc = KaleidoManager_GetRamAddr(KaleidoScope_Draw); + KaleidoSetup_Init(globalCtx); +} + +void KaleidoScopeCall_Destroy(GlobalContext* globalCtx) { + KaleidoSetup_Destroy(globalCtx); +} + +void KaleidoScopeCall_Update(GlobalContext* globalCtx) { + PauseContext* pauseCtx = &globalCtx->pauseCtx; + KaleidoMgrOverlay* kaleidoScopeOvl = &gKaleidoMgrOverlayTable[KALEIDO_OVL_KALEIDO_SCOPE]; + + if ((globalCtx->pauseCtx.state != 0) || (globalCtx->pauseCtx.debugState != 0)) { + if (pauseCtx->state == 1 || pauseCtx->state == 19) { + if (ShrinkWindow_GetLetterboxMagnitude() == 0) { + R_PAUSE_MENU_MODE = 1; + pauseCtx->unk_200 = 0; + pauseCtx->unk_208 = 0; + pauseCtx->state = (pauseCtx->state & 0xFFFF) + 1; + } + } else if (pauseCtx->state == 8) { + R_PAUSE_MENU_MODE = 1; + pauseCtx->unk_200 = 0; + pauseCtx->unk_208 = 0; + pauseCtx->state = (pauseCtx->state & 0xFFFF) + 1; + } else if ((pauseCtx->state == 2) || (pauseCtx->state == 9) || (pauseCtx->state == 20)) { + if (R_PAUSE_MENU_MODE == 3) { + pauseCtx->state++; + } + } else if (pauseCtx->state != 0) { + if (gKaleidoMgrCurOvl != kaleidoScopeOvl) { + if (gKaleidoMgrCurOvl != NULL) { + KaleidoManager_ClearOvl(gKaleidoMgrCurOvl); + } + + KaleidoManager_LoadOvl(kaleidoScopeOvl); + } + + if (gKaleidoMgrCurOvl == kaleidoScopeOvl) { + sKaleidoScopeUpdateFunc(globalCtx); + + if ((globalCtx->pauseCtx.state == 0) && (globalCtx->pauseCtx.debugState == 0)) { + KaleidoManager_ClearOvl(kaleidoScopeOvl); + KaleidoScopeCall_LoadPlayer(); + } + } + } + } +} + +void KaleidoScopeCall_Draw(GlobalContext* globalCtx) { + KaleidoMgrOverlay* kaleidoScopeOvl = &gKaleidoMgrOverlayTable[KALEIDO_OVL_KALEIDO_SCOPE]; + + if (R_PAUSE_MENU_MODE == 3) { + if (((globalCtx->pauseCtx.state >= 4) && (globalCtx->pauseCtx.state <= 7)) || + ((globalCtx->pauseCtx.state >= 11) && (globalCtx->pauseCtx.state <= 26))) { + if (gKaleidoMgrCurOvl == kaleidoScopeOvl) { + sKaleidoScopeDrawFunc(globalCtx); + } + } + } +} diff --git a/src/code/z_kaleido_setup.c b/src/code/z_kaleido_setup.c index 8065a9a6b..7f4d43784 100644 --- a/src/code/z_kaleido_setup.c +++ b/src/code/z_kaleido_setup.c @@ -4,6 +4,6 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_kaleido_setup/func_800F4C0C.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kaleido_setup/func_800F4E20.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_kaleido_setup/KaleidoSetup_Init.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_kaleido_setup/func_800F4F28.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_kaleido_setup/KaleidoSetup_Destroy.s") diff --git a/src/code/z_lights.c b/src/code/z_lights.c index fb88fbc77..4d649da2d 100644 --- a/src/code/z_lights.c +++ b/src/code/z_lights.c @@ -131,7 +131,7 @@ void Lights_BindPoint(Lights* lights, LightParams* params, GlobalContext* global posF.x = params->point.x; posF.y = params->point.y; posF.z = params->point.z; - SkinMatrix_Vec3fMtxFMultXYZ(&globalCtx->projectionMatrix, &posF, &adjustedPos); + SkinMatrix_Vec3fMtxFMultXYZ(&globalCtx->viewProjectionMtxF, &posF, &adjustedPos); if ((adjustedPos.z > -radiusF) && (600 + radiusF > adjustedPos.z) && (400 > fabsf(adjustedPos.x) - radiusF) && (400 > fabsf(adjustedPos.y) - radiusF)) { light = Lights_FindSlot(lights); diff --git a/src/code/z_pause.c b/src/code/z_pause.c index 44be6238a..bb5b33cf2 100644 --- a/src/code/z_pause.c +++ b/src/code/z_pause.c @@ -1,5 +1,39 @@ +/* + * File: z_pause.c + * Description: Frame Advance debug feature + * + * This allows you to advance through the game one frame at a time on command. + * To advance a frame, hold Z and press R on the specified controller (see z_play). + * Holding Z and R will advance a frame every half second. + * + * Note: While the system is fully hooked up, there is no way to enable it in game + * Instead one would have to add something like: + * + * if (CHECK_BTN_ALL(input->cur.button, BTN_R) && CHECK_BTN_ALL(input->press.button, BTN_DDOWN)) { + * frameAdvCtx->enabled = !frameAdvCtx->enabled; + * } + * + * to the start of FrameAdvance_Update, which would allow the system to be toggled on and off by holding R + * and pressing Dpad Down on the specified controller. + * + * Note2: Controllers 2-4's inputs are normally zeroed out, so this would also need to be fixed to use frame advance + */ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_pause/func_80122660.s") +void FrameAdvance_Init(FrameAdvanceContext* frameAdvCtx) { + frameAdvCtx->timer = 0; + frameAdvCtx->enabled = false; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_pause/func_80122670.s") +/* + * Returns true when frame advance is not active (game will run normally) + */ +s32 FrameAdvance_Update(FrameAdvanceContext* frameAdvCtx, Input* input) { + if (!frameAdvCtx->enabled || (CHECK_BTN_ALL(input->cur.button, BTN_Z) && + (CHECK_BTN_ALL(input->press.button, BTN_R) || + (CHECK_BTN_ALL(input->cur.button, BTN_R) && (++frameAdvCtx->timer >= 9))))) { + frameAdvCtx->timer = 0; + return true; + } + return false; +} diff --git a/src/code/z_play.c b/src/code/z_play.c index 8f15c577a..7e0e018c7 100644 --- a/src/code/z_play.c +++ b/src/code/z_play.c @@ -52,7 +52,7 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80167F0C.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80168090.s") +#pragma GLOBAL_ASM("asm/non_matchings/code/z_play/Play_Draw.s") #pragma GLOBAL_ASM("asm/non_matchings/code/z_play/func_80168DAC.s") diff --git a/src/code/z_room.c b/src/code/z_room.c index fe4b51d68..1685acc80 100644 --- a/src/code/z_room.c +++ b/src/code/z_room.c @@ -18,14 +18,14 @@ void Room_DrawType0Mesh(GlobalContext* globalCtx, Room* room, u32 flags) { func_800BCBF4(&D_801C1D10, globalCtx); gSPSegment(gfxCtx->polyOpa.p++, 0x03, room->segment); func_8012C268(globalCtx); - gSPMatrix(gfxCtx->polyOpa.p++, &D_801D1DE0, G_MTX_MODELVIEW | G_MTX_LOAD); + gSPMatrix(gfxCtx->polyOpa.p++, &gIdentityMtx, G_MTX_MODELVIEW | G_MTX_LOAD); } if (flags & 2) { func_800BCC68(&D_801C1D10, globalCtx); gSPSegment(gfxCtx->polyXlu.p++, 0x03, room->segment); func_8012C2DC(globalCtx->state.gfxCtx); - gSPMatrix(gfxCtx->polyXlu.p++, &D_801D1DE0, G_MTX_MODELVIEW | G_MTX_LOAD); + gSPMatrix(gfxCtx->polyXlu.p++, &gIdentityMtx, G_MTX_MODELVIEW | G_MTX_LOAD); } mesh = &room->mesh->type0; diff --git a/src/code/z_sub_s.c b/src/code/z_sub_s.c index 1ab44acc1..3255b86d8 100644 --- a/src/code/z_sub_s.c +++ b/src/code/z_sub_s.c @@ -1,6 +1,40 @@ -#include "global.h" +/* + * File: z_sub_s.c + * Description: Various miscellaneous helpers + */ -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013A7C0.s") +#include "global.h" +#include "overlays/actors/ovl_En_Door/z_en_door.h" + +/** + * Finds the first EnDoor instance with unk_1A4 == 5 and the specified unk_1A5. + */ +EnDoor* SubS_FindDoor(GlobalContext* globalCtx, s32 unk_1A5) { + Actor* actor = NULL; + EnDoor* door; + + while (true) { + actor = SubS_FindActor(globalCtx, actor, ACTORCAT_DOOR, ACTOR_EN_DOOR); + door = (EnDoor*)actor; + + if (actor == NULL) { + break; + } + + if ((door->unk_1A4 == 5) && (door->unk_1A5 == (u8)unk_1A5)) { + break; + } + + if (actor->next == NULL) { + door = NULL; + break; + } + + actor = actor->next; + } + + return door; +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013A860.s") @@ -26,7 +60,40 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013BB34.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013BB7C.s") +/** + * Finds the nearest actor instance of a specified Id and category to an actor. + */ +Actor* SubS_FindNearestActor(Actor* actor, GlobalContext* globalCtx, u8 actorCategory, s16 actorId) { + Actor* actorIter = NULL; + Actor* actorTmp; + f32 dist; + Actor* closestActor = NULL; + f32 minDist = 99999.0f; + s32 isSetup = false; + + do { + actorIter = SubS_FindActor(globalCtx, actorIter, actorCategory, actorId); + + actorTmp = actorIter; + if (actorTmp == NULL) { + break; + } + actorIter = actorTmp; + + if (actorIter != actor) { + dist = Actor_DistanceBetweenActors(actor, actorIter); + if (!isSetup || dist < minDist) { + closestActor = actorIter; + minDist = dist; + isSetup = true; + } + } + + actorIter = actorIter->next; + } while (actorIter != NULL); + + return closestActor; +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013BC6C.s") @@ -68,7 +135,22 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013D924.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_ActorCategoryIterateById.s") +/** + * Finds the first actor instance of a specified Id and category. + */ +Actor* SubS_FindActor(GlobalContext* globalCtx, Actor* actorListStart, u8 actorCategory, s16 actorId) { + Actor* actor = actorListStart; + + if (actor == NULL) { + actor = globalCtx->actorCtx.actorList[actorCategory].first; + } + + while (actor != NULL && actorId != actor->id) { + actor = actor->next; + } + + return actor; +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013D9C8.s") @@ -100,7 +182,27 @@ #pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E5CC.s") -#pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E640.s") +/** + * Finds the first actor instance of a specified Id and category verified with a custom callback. + * The callback should return `true` when the actor is succesfully verified. + */ +Actor* SubS_FindActorCustom(GlobalContext* globalCtx, Actor* actor, Actor* actorListStart, u8 actorCategory, + s16 actorId, void* verifyData, VerifyActor verifyActor) { + Actor* actorIter = actorListStart; + + if (actorListStart == NULL) { + actorIter = globalCtx->actorCtx.actorList[actorCategory].first; + } + + while (actorIter != NULL && (actorId != actorIter->id || + (actorId == actorIter->id && + (verifyActor == NULL || + (verifyActor != NULL && !verifyActor(globalCtx, actor, actorIter, verifyData)))))) { + actorIter = actorIter->next; + } + + return actorIter; +} #pragma GLOBAL_ASM("asm/non_matchings/code/z_sub_s/func_8013E748.s") diff --git a/src/code/z_view.c b/src/code/z_view.c index c325fd563..da2e3593b 100644 --- a/src/code/z_view.c +++ b/src/code/z_view.c @@ -259,11 +259,11 @@ s32 View_StepQuake(View* view, Mtx* matrix) { Matrix_FromRSPMatrix(matrix, &mf); Matrix_SetCurrentState(&mf); Matrix_RotateStateAroundXAxis(view->currQuakeRot.x); - Matrix_InsertYRotation_f(view->currQuakeRot.y, 1); - Matrix_InsertZRotation_f(view->currQuakeRot.z, 1); + Matrix_InsertYRotation_f(view->currQuakeRot.y, MTXMODE_APPLY); + Matrix_InsertZRotation_f(view->currQuakeRot.z, MTXMODE_APPLY); Matrix_Scale(view->currQuakeScale.x, view->currQuakeScale.y, view->currQuakeScale.z, MTXMODE_APPLY); - Matrix_InsertZRotation_f(-view->currQuakeRot.z, 1); - Matrix_InsertYRotation_f(-view->currQuakeRot.y, 1); + Matrix_InsertZRotation_f(-view->currQuakeRot.z, MTXMODE_APPLY); + Matrix_InsertYRotation_f(-view->currQuakeRot.y, MTXMODE_APPLY); Matrix_RotateStateAroundXAxis(-view->currQuakeRot.x); Matrix_ToMtx(matrix); diff --git a/src/code/z_vr_box.c b/src/code/z_vr_box.c index 724bc5971..29d1a1aca 100644 --- a/src/code/z_vr_box.c +++ b/src/code/z_vr_box.c @@ -140,7 +140,7 @@ void func_801434E4(GameState* gameState, SkyboxContext* skyboxCtx, s16 skyType) func_801431E8(gameState, skyboxCtx, skyType); if (skyType != 0) { - skyboxCtx->unk17C = THA_AllocEndAlign16(&gameState->heap, 0x3840); + skyboxCtx->dListBuf = THA_AllocEndAlign16(&gameState->heap, 0x3840); if (skyType == 5) { // Allocate enough space for the vertices for a 6 sided skybox (cube) diff --git a/src/code/z_vr_box_draw.c b/src/code/z_vr_box_draw.c index 27142c944..d7f99eed9 100644 --- a/src/code/z_vr_box_draw.c +++ b/src/code/z_vr_box_draw.c @@ -1,9 +1,67 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/code/z_vr_box_draw/func_801435A0.s") +Mtx* sSkyboxDrawMatrix; -#pragma GLOBAL_ASM("asm/non_matchings/code/z_vr_box_draw/func_80143624.s") +Mtx* SkyboxDraw_UpdateMatrix(SkyboxContext* skyboxCtx, f32 x, f32 y, f32 z) { + Matrix_InsertTranslation(x, y, z, MTXMODE_NEW); + Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY); + Matrix_RotateStateAroundXAxis(skyboxCtx->rotX); + Matrix_InsertYRotation_f(skyboxCtx->rotY, MTXMODE_APPLY); + Matrix_InsertZRotation_f(skyboxCtx->rotZ, MTXMODE_APPLY); + return Matrix_ToMtx(sSkyboxDrawMatrix); +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_vr_box_draw/func_80143668.s") +void SkyboxDraw_SetColors(SkyboxContext* skyboxCtx, u8 primR, u8 primG, u8 primB, u8 envR, u8 envG, u8 envB) { + skyboxCtx->primR = primR; + skyboxCtx->primG = primG; + skyboxCtx->primB = primB; + skyboxCtx->envR = envR; + skyboxCtx->envG = envG; + skyboxCtx->envB = envB; +} -#pragma GLOBAL_ASM("asm/non_matchings/code/z_vr_box_draw/func_80143A04.s") +void SkyboxDraw_Draw(SkyboxContext* skyboxCtx, GraphicsContext* gfxCtx, s16 skyboxId, s16 blend, f32 x, f32 y, f32 z) { + OPEN_DISPS(gfxCtx); + + func_8012C6AC(gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x0B, skyboxCtx->skyboxPaletteStaticSegment); + gSPTexture(POLY_OPA_DISP++, 0x8000, 0x8000, 0, G_TX_RENDERTILE, G_ON); + + sSkyboxDrawMatrix = GRAPH_ALLOC(gfxCtx, sizeof(Mtx)); + + Matrix_InsertTranslation(x, y, z, MTXMODE_NEW); + Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY); + Matrix_RotateStateAroundXAxis(skyboxCtx->rotX); + Matrix_InsertYRotation_f(skyboxCtx->rotY, MTXMODE_APPLY); + Matrix_InsertZRotation_f(skyboxCtx->rotZ, MTXMODE_APPLY); + Matrix_ToMtx(sSkyboxDrawMatrix); + + gSPMatrix(POLY_OPA_DISP++, sSkyboxDrawMatrix, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetColorDither(POLY_OPA_DISP++, G_CD_MAGICSQ); + gDPSetTextureFilter(POLY_OPA_DISP++, G_TF_BILERP); + gDPLoadTLUT_pal256(POLY_OPA_DISP++, skyboxCtx->skyboxPaletteStaticSegment); + gDPSetTextureLUT(POLY_OPA_DISP++, G_TT_RGBA16); + gDPSetTextureConvert(POLY_OPA_DISP++, G_TC_FILT); + gDPSetCombineLERP(POLY_OPA_DISP++, TEXEL1, TEXEL0, PRIMITIVE_ALPHA, TEXEL0, TEXEL1, TEXEL0, PRIMITIVE, TEXEL0, + PRIMITIVE, ENVIRONMENT, COMBINED, ENVIRONMENT, 0, 0, 0, COMBINED); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, skyboxCtx->primR, skyboxCtx->primG, skyboxCtx->primB, blend); + gDPSetEnvColor(POLY_OPA_DISP++, skyboxCtx->envR, skyboxCtx->envG, skyboxCtx->envB, 0); + + gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[0]); + gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[300]); + gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[600]); + gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[900]); + gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[1200]); + + if (skyboxId == SKYBOX_CUTSCENE_MAP) { + gSPDisplayList(POLY_OPA_DISP++, &skyboxCtx->dListBuf[1500]); + } + + gDPPipeSync(POLY_OPA_DISP++); + + CLOSE_DISPS(gfxCtx); +} + +void SkyboxDraw_Noop(SkyboxContext* skyboxCtx) { +} diff --git a/src/libultra/io/contchannelreset.c b/src/libultra/io/contchannelreset.c index 841dad738..d0f1fbd9b 100644 --- a/src/libultra/io/contchannelreset.c +++ b/src/libultra/io/contchannelreset.c @@ -1,3 +1,27 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/contchannelreset/__osContChannelReset.s") +s32 __osContChannelReset(OSMesgQueue* mq, s32 channel) { + s32 i; + s32 ret; + u8* bufptr = (u8*)&__osPfsPifRam; + + __osSiGetAccess(); + + __osPfsPifRam.status = 1; + + for (i = 0; i < channel; i++) { + *bufptr++ = 0; + } + + *bufptr++ = 0xFD; + *bufptr = CONT_CMD_END; + + __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam); + osRecvMesg(mq, NULL, OS_MESG_BLOCK); + + __osSiRelAccess(); + + return ret; +} diff --git a/src/libultra/io/contpfs.c b/src/libultra/io/contpfs.c index 3dd0c96ca..fd4c4e459 100644 --- a/src/libultra/io/contpfs.c +++ b/src/libultra/io/contpfs.c @@ -1,6 +1,42 @@ #include "ultra64.h" #include "global.h" +__OSInode __osPfsInodeCache; +OSViMode osViModeNtscHpn1 = { + 8, // type + { + // comRegs + 0x324E, // ctrl + 0x500, // width + 0x3E52239, // burst + 0x20C, // vSync + 0xC15, // hSync + 0xC150C15, // leap + 0x6C02EC, // hStart + 0x400, // xScale + 0, // vCurrent + }, + { // fldRegs + { + // [0] + 0x500, // origin + 0x400, // yScale + 0x2301FD, // vStart + 0xE0204, // vBurst + 2, // vIntr + }, + { + // [1] + 0xA00, // origin + 0x400, // yScale + 0x2501FF, // vStart + 0xE0204, // vBurst + 2, // vIntr + } }, +}; +s32 __osPfsInodeCacheChannel = -1; +u8 __osPfsInodeCacheBank = 250; + u16 __osSumcalc(u8* ptr, s32 length) { s32 i; u32 sum = 0; diff --git a/src/libultra/io/contreaddata.c b/src/libultra/io/contreaddata.c index 04ad77ee7..915ce9753 100644 --- a/src/libultra/io/contreaddata.c +++ b/src/libultra/io/contreaddata.c @@ -47,7 +47,7 @@ void __osPackReadData() { __osContPifRam.ramarray[i] = 0; } - __osContPifRam.pifstatus = CONT_CMD_READ_BUTTON; + __osContPifRam.status = CONT_CMD_READ_BUTTON; readformat.dummy = 255; readformat.txsize = 1; readformat.rxsize = 4; diff --git a/src/libultra/io/controller.c b/src/libultra/io/controller.c index 8e750499e..198b0f136 100644 --- a/src/libultra/io/controller.c +++ b/src/libultra/io/controller.c @@ -43,7 +43,7 @@ s32 osContInit(OSMesgQueue* mq, u8* bitpattern, OSContStatus* data) { __osContGetInitData(bitpattern, data); __osContLastPoll = 0; __osSiCreateAccessQueue(); - osCreateMesgQueue(&D_8009CF38, D_8009CF50, 1); + osCreateMesgQueue(&D_8009CF38, D_8009CF50, ARRAY_COUNT(D_8009CF50)); return ret; } @@ -78,7 +78,7 @@ void __osPackRequestData(u8 poll) { __osContPifRam.ramarray[i] = 0; } - __osContPifRam.pifstatus = CONT_CMD_READ_BUTTON; + __osContPifRam.status = CONT_CMD_READ_BUTTON; ptr = (u8*)__osContPifRam.ramarray; requestHeader.align = 255; requestHeader.txsize = 1; diff --git a/src/libultra/io/motor.c b/src/libultra/io/motor.c index 94651bf1b..a780117ea 100644 --- a/src/libultra/io/motor.c +++ b/src/libultra/io/motor.c @@ -20,7 +20,7 @@ s32 __osMotorAccess(OSPfs* pfs, u32 vibrate) { } __osSiGetAccess(); - osPifBuffers[pfs->channel].pifstatus = CONT_CMD_READ_BUTTON; + osPifBuffers[pfs->channel].status = CONT_CMD_READ_BUTTON; buf += pfs->channel; for (i = 0; i < BLOCKSIZE; i++) { ((__OSContRamReadFormat*)buf)->data[i] = vibrate; diff --git a/src/libultra/io/pfsfreeblocks.c b/src/libultra/io/pfsfreeblocks.c index af10a5b88..b90979c59 100644 --- a/src/libultra/io/pfsfreeblocks.c +++ b/src/libultra/io/pfsfreeblocks.c @@ -1,3 +1,37 @@ #include "global.h" +#include "PR/pfs.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsfreeblocks/osPfsFreeBlocks.s") +s32 osPfsFreeBlocks(OSPfs* pfs, s32* leftoverBytes) { + s32 j; + s32 pages = 0; + __OSInode inode; + s32 ret = 0; + u8 bank; + s32 offset; + + if (!(pfs->status & PFS_INITIALIZED)) { + return PFS_ERR_INVALID; + } + + ret = __osCheckId(pfs); + if (ret != 0) { + return ret; + } + + for (bank = PFS_ID_BANK_256K; bank < pfs->banks; bank++) { + ret = __osPfsRWInode(pfs, &inode, PFS_READ, bank); + if (ret != 0) { + return ret; + } + + offset = ((bank > PFS_ID_BANK_256K) ? 1 : pfs->inodeStartPage); + for (j = offset; j < PFS_INODE_SIZE_PER_PAGE; j++) { + if (inode.inodePage[j].ipage == PFS_PAGE_NOT_USED) { + pages++; + } + } + } + + *leftoverBytes = pages * PFS_ONE_PAGE * BLOCKSIZE; + return 0; +} diff --git a/src/libultra/io/pfsgetstatus.c b/src/libultra/io/pfsgetstatus.c index 8127dde21..1d8e6dcf5 100644 --- a/src/libultra/io/pfsgetstatus.c +++ b/src/libultra/io/pfsgetstatus.c @@ -1,7 +1,75 @@ +#include "ultra64.h" #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsgetstatus/__osPfsGetStatus.s") +void __osPfsRequestOneChannel(s32 channel, u8 poll); +void __osPfsGetOneChannelData(s32 channel, OSContStatus* contData); -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsgetstatus/__osPfsRequestOneChannel.s") +s32 __osPfsGetStatus(OSMesgQueue* queue, s32 channel) { + s32 ret = 0; + OSMesg msg; + OSContStatus data; -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsgetstatus/__osPfsGetOneChannelData.s") + __osPfsInodeCacheBank = 250; + + __osPfsRequestOneChannel(channel, CONT_CMD_REQUEST_STATUS); + ret = __osSiRawStartDma(OS_WRITE, &__osPfsPifRam); + osRecvMesg(queue, &msg, OS_MESG_BLOCK); + + ret = __osSiRawStartDma(OS_READ, &__osPfsPifRam); + osRecvMesg(queue, &msg, OS_MESG_BLOCK); + + __osPfsGetOneChannelData(channel, &data); + if (((data.status & CONT_CARD_ON) != 0) && ((data.status & CONT_CARD_PULL) != 0)) { + return PFS_ERR_NEW_PACK; + } else if (data.errno || ((data.status & CONT_CARD_ON) == 0)) { + return PFS_ERR_NOPACK; + } else if ((data.status & CONT_ADDR_CRC_ER) != 0) { + return PFS_ERR_CONTRFAIL; + } + return ret; +} + +void __osPfsRequestOneChannel(s32 channel, u8 poll) { + u8* bufptr; + __OSContRequestHeaderAligned req; + s32 idx; + + __osContLastPoll = CONT_CMD_END; + __osPfsPifRam.status = CONT_CMD_READ_BUTTON; + + bufptr = (u8*)&__osPfsPifRam; + + req.txsize = 1; + req.rxsize = 3; + req.poll = poll; + req.typeh = 0xFF; + req.typel = 0xFF; + req.status = 0xFF; + + for (idx = 0; idx < channel; idx++) { + *bufptr++ = 0; + } + + *((__OSContRequestHeaderAligned*)bufptr) = req; + bufptr += sizeof(req); + *((u8*)bufptr) = CONT_CMD_END; +} + +void __osPfsGetOneChannelData(s32 channel, OSContStatus* contData) { + u8* bufptr = (u8*)&__osPfsPifRam; + __OSContRequestHeaderAligned req; + s32 idx; + + for (idx = 0; idx < channel; idx++) { + bufptr++; + } + + req = *((__OSContRequestHeaderAligned*)bufptr); + contData->errno = (req.rxsize & 0xC0) >> 4; + if (contData->errno) { + return; + } + + contData->type = (req.typel << 8) | req.typeh; + contData->status = req.status; +} diff --git a/src/libultra/io/pfsisplug.c b/src/libultra/io/pfsisplug.c index 358af0c98..474c7f914 100644 --- a/src/libultra/io/pfsisplug.c +++ b/src/libultra/io/pfsisplug.c @@ -55,7 +55,7 @@ void __osPfsRequestData(u8 poll) { __osContLastPoll = poll; - __osPfsPifRam.pifstatus = 1; + __osPfsPifRam.status = 1; req.align = 0xFF; req.txsize = 1; diff --git a/src/libultra/io/pfsreadwritefile.c b/src/libultra/io/pfsreadwritefile.c index bc2b9741c..b5ab6e4b4 100644 --- a/src/libultra/io/pfsreadwritefile.c +++ b/src/libultra/io/pfsreadwritefile.c @@ -1,5 +1,124 @@ +#include "ultra64.h" #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsreadwritefile/__osPfsGetNextPage.s") +#define CHECK_IPAGE(p, pfs) \ + (((p).ipage >= (pfs).inodeStartPage) && ((p).inode_t.bank < (pfs).banks) && ((p).inode_t.page >= 0x01) && \ + ((p).inode_t.page < 0x80)) -#pragma GLOBAL_ASM("asm/non_matchings/boot/pfsreadwritefile/osPfsReadWriteFile.s") +s32 __osPfsGetNextPage(OSPfs* pfs, u8* bank, __OSInode* inode, __OSInodeUnit* page) { + s32 ret; + + if (page->inode_t.bank != *bank) { + *bank = page->inode_t.bank; + if ((ret = __osPfsRWInode(pfs, inode, PFS_READ, *bank)) != 0) { + return ret; + } + } + *page = inode->inodePage[page->inode_t.page]; + + if (!CHECK_IPAGE(*page, *pfs)) { + if (page->ipage == PFS_EOF) { + return PFS_ERR_INVALID; + } + return PFS_ERR_INCONSISTENT; + } + return 0; +} + +s32 osPfsReadWriteFile(OSPfs* pfs, s32 fileNo, u8 flag, s32 offset, s32 size, u8* data) { + s32 ret; + __OSDir dir; + __OSInode inode; + __OSInodeUnit curPage; + s32 curBlock; + s32 blockSize; + u8* buffer; + u8 bank; + u16 blockno; + + if ((fileNo >= pfs->dir_size) || (fileNo < 0)) { + return PFS_ERR_INVALID; + } + if ((size <= 0) || ((size % BLOCKSIZE) != 0)) { + return PFS_ERR_INVALID; + } + if ((offset < 0) || ((offset % BLOCKSIZE) != 0)) { + return PFS_ERR_INVALID; + } + if (!(pfs->status & PFS_INITIALIZED)) { + return PFS_ERR_INVALID; + } + if (__osCheckId(pfs) == PFS_ERR_NEW_PACK) { + return PFS_ERR_NEW_PACK; + } + if (pfs->activebank != PFS_ID_BANK_256K && (ret = __osPfsSelectBank(pfs, PFS_ID_BANK_256K)) != 0) { + return ret; + } + if ((ret = __osContRamRead(pfs->queue, pfs->channel, pfs->dir_table + fileNo, (u8*)&dir)) != 0) { + return ret; + } + if ((dir.company_code == 0) || (dir.game_code == 0)) { + return PFS_ERR_INVALID; + } + if (!CHECK_IPAGE(dir.start_page, *pfs)) { + if (dir.start_page.ipage == PFS_EOF) { + return PFS_ERR_INVALID; + } + return PFS_ERR_INCONSISTENT; + } + if ((flag == PFS_READ) && ((dir.status & PFS_WRITTEN) == 0)) { + return PFS_ERR_BAD_DATA; + } + + bank = 255; + curBlock = offset / BLOCKSIZE; + curPage = dir.start_page; + + while (curBlock >= 8) { + if ((ret = __osPfsGetNextPage(pfs, &bank, &inode, &curPage)) != 0) { + return ret; + } + curBlock -= 8; + } + + blockSize = size / BLOCKSIZE; + buffer = data; + + while (blockSize > 0) { + if (curBlock == 8) { + if ((ret = __osPfsGetNextPage(pfs, &bank, &inode, &curPage)) != 0) { + return ret; + } + curBlock = 0; + } + if (pfs->activebank != curPage.inode_t.bank && (ret = __osPfsSelectBank(pfs, curPage.inode_t.bank)) != 0) { + return ret; + } + + blockno = curPage.inode_t.page * PFS_ONE_PAGE + curBlock; + if (flag == PFS_READ) { + ret = __osContRamRead(pfs->queue, pfs->channel, blockno, buffer); + } else { + ret = __osContRamWrite(pfs->queue, pfs->channel, blockno, buffer, 0); + } + if (ret != 0) { + return ret; + } + + buffer += BLOCKSIZE; + curBlock++; + blockSize--; + } + + if (flag == PFS_WRITE && !(dir.status & PFS_WRITTEN)) { + dir.status |= PFS_WRITTEN; + if (pfs->activebank != PFS_ID_BANK_256K && (ret = __osPfsSelectBank(pfs, PFS_ID_BANK_256K)) != 0) { + return ret; + } + if ((ret = __osContRamWrite(pfs->queue, pfs->channel, pfs->dir_table + fileNo, (u8*)&dir, 0)) != 0) { + return ret; + } + } + + return __osPfsGetStatus(pfs->queue, pfs->channel); +} diff --git a/src/libultra/io/piacs.c b/src/libultra/io/piacs.c index 9689aaf67..532b149e2 100644 --- a/src/libultra/io/piacs.c +++ b/src/libultra/io/piacs.c @@ -7,7 +7,7 @@ OSMesgQueue __osPiAccessQueue; void __osPiCreateAccessQueue(void) { __osPiAccessQueueEnabled = 1; - osCreateMesgQueue(&__osPiAccessQueue, D_8009E3F0, 1); + osCreateMesgQueue(&__osPiAccessQueue, D_8009E3F0, ARRAY_COUNT(D_8009E3F0)); osSendMesg(&__osPiAccessQueue, NULL, OS_MESG_NOBLOCK); } diff --git a/src/libultra/io/pimgr.c b/src/libultra/io/pimgr.c index 74b1075a1..3d618de74 100644 --- a/src/libultra/io/pimgr.c +++ b/src/libultra/io/pimgr.c @@ -14,7 +14,7 @@ void osCreatePiManager(OSPri pri, OSMesgQueue* cmdQ, OSMesg* cmdBuf, s32 cmdMsgC if (!__osPiDevMgr.active) { osCreateMesgQueue(cmdQ, cmdBuf, cmdMsgCnt); - osCreateMesgQueue(&D_8009E3D0, D_8009E3E8, 1); + osCreateMesgQueue(&D_8009E3D0, D_8009E3E8, ARRAY_COUNT(D_8009E3E8)); if (!__osPiAccessQueueEnabled) { __osPiCreateAccessQueue(); } diff --git a/src/libultra/io/siacs.c b/src/libultra/io/siacs.c index 5bddc63c8..7a221408e 100644 --- a/src/libultra/io/siacs.c +++ b/src/libultra/io/siacs.c @@ -7,7 +7,7 @@ OSMesgQueue __osSiAccessQueue; void __osSiCreateAccessQueue() { __osSiAccessQueueEnabled = 1; - osCreateMesgQueue(&__osSiAccessQueue, siAccessBuf, 1); + osCreateMesgQueue(&__osSiAccessQueue, siAccessBuf, ARRAY_COUNT(siAccessBuf)); osSendMesg(&__osSiAccessQueue, NULL, OS_MESG_NOBLOCK); } diff --git a/src/libultra/io/sptask.c b/src/libultra/io/sptask.c index 0ec16a4c3..aeaaf0f82 100644 --- a/src/libultra/io/sptask.c +++ b/src/libultra/io/sptask.c @@ -32,29 +32,23 @@ void osSpTaskLoad(OSTask* intp) { intp->t.flags &= ~OS_TASK_YIELDED; if (tp->t.flags & OS_TASK_LOADABLE) { - tp->t.ucode = HW_REG((u32)intp->t.yieldDataPtr + OS_YIELD_DATA_SIZE - 4, u32); + tp->t.ucode = HW_REG((uintptr_t)intp->t.yieldDataPtr + OS_YIELD_DATA_SIZE - 4, u32); } } osWritebackDCache(tp, sizeof(OSTask)); __osSpSetStatus(SP_CLR_SIG0 | SP_CLR_SIG1 | SP_CLR_SIG2 | SP_SET_INTR_BREAK); - while (__osSpSetPc((void*)SP_IMEM_START) == -1) { - ; - } - while (__osSpRawStartDma(1, (void*)(SP_IMEM_START - sizeof(*tp)), tp, sizeof(OSTask)) == -1) { - ; - } - while (__osSpDeviceBusy()) { - ; - } - while (__osSpRawStartDma(1, (void*)SP_IMEM_START, tp->t.ucodeBoot, tp->t.ucodeBootSize) == -1) { - ; - } + while (__osSpSetPc((void*)SP_IMEM_START) == -1) {} + + while (__osSpRawStartDma(1, (void*)(SP_IMEM_START - sizeof(*tp)), tp, sizeof(OSTask)) == -1) {} + + while (__osSpDeviceBusy()) {} + + while (__osSpRawStartDma(1, (void*)SP_IMEM_START, tp->t.ucodeBoot, tp->t.ucodeBootSize) == -1) {} } void osSpTaskStartGo(OSTask* tp) { - while (__osSpDeviceBusy()) { - ; - } + while (__osSpDeviceBusy()) {} + __osSpSetStatus(SP_SET_INTR_BREAK | SP_CLR_SSTEP | SP_CLR_BROKE | SP_CLR_HALT); } diff --git a/src/libultra/io/viswapcontext.c b/src/libultra/io/viswapcontext.c index 014fbbfeb..514e3aa1d 100644 --- a/src/libultra/io/viswapcontext.c +++ b/src/libultra/io/viswapcontext.c @@ -1,3 +1,66 @@ #include "global.h" -#pragma GLOBAL_ASM("asm/non_matchings/boot/viswapcontext/__osViSwapContext.s") +void __osViSwapContext(void) { + register OSViMode* viMode; + register __OSViContext* viNext; + u32 origin; + u32 hStart; + u32 vstart; + u32 sp34; + u32 field; + register u32 s2; + + field = 0; + viNext = __osViNext; + viMode = viNext->modep; + field = HW_REG(VI_V_CURRENT_LINE_REG, u32) & 1; + s2 = osVirtualToPhysical(viNext->buffer); + origin = (viMode->fldRegs[field].origin) + s2; + if (viNext->state & 2) { + viNext->x.scale |= viMode->comRegs.xScale & ~0xFFF; + } else { + viNext->x.scale = viMode->comRegs.xScale; + } + if (viNext->state & 4) { + sp34 = (u32)(viMode->fldRegs[field].yScale & 0xFFF); + viNext->y.scale = viNext->y.factor * sp34; + viNext->y.scale |= viMode->fldRegs[field].yScale & ~0xFFF; + } else { + viNext->y.scale = viMode->fldRegs[field].yScale; + } + + vstart = (viMode->fldRegs[field].vStart - (__additional_scanline << 0x10)) + __additional_scanline; + hStart = viMode->comRegs.hStart; + + if (viNext->state & 0x20) { + hStart = 0; + } + + if (viNext->state & 0x40) { + viNext->y.scale = 0; + origin = osVirtualToPhysical(viNext->buffer); + } + + if (viNext->state & 0x80) { + viNext->y.scale = (viNext->y.offset << 0x10) & 0x3FF0000; + origin = osVirtualToPhysical(viNext->buffer); + } + + HW_REG(VI_ORIGIN_REG, u32) = origin; + HW_REG(VI_WIDTH_REG, u32) = viMode->comRegs.width; + HW_REG(VI_BURST_REG, u32) = viMode->comRegs.burst; + HW_REG(VI_V_SYNC_REG, u32) = viMode->comRegs.vSync; + HW_REG(VI_H_SYNC_REG, u32) = viMode->comRegs.hSync; + HW_REG(VI_LEAP_REG, u32) = viMode->comRegs.leap; + HW_REG(VI_H_START_REG, u32) = hStart; + HW_REG(VI_V_START_REG, u32) = vstart; + HW_REG(VI_V_BURST_REG, u32) = viMode->fldRegs[field].vBurst; + HW_REG(VI_INTR_REG, u32) = viMode->fldRegs[field].vIntr; + HW_REG(VI_X_SCALE_REG, u32) = viNext->x.scale; + HW_REG(VI_Y_SCALE_REG, u32) = viNext->y.scale; + HW_REG(VI_CONTROL_REG, u32) = viNext->features; + + __osViNext = __osViCurr; + __osViCurr = viNext; + *__osViNext = *__osViCurr; +} diff --git a/src/libultra/rmon/xprintf.c b/src/libultra/rmon/xprintf.c index 313adc2e6..6c538a2a8 100644 --- a/src/libultra/rmon/xprintf.c +++ b/src/libultra/rmon/xprintf.c @@ -7,7 +7,7 @@ #define _PROUT(fmt, _size) \ if (_size > 0) { \ arg = (void*)pfn(arg, fmt, _size); \ - if (arg != 0) \ + if (arg != NULL) \ x.nchar += _size; \ else \ return x.nchar; \ diff --git a/src/libultra/voice/voicecontread2.c b/src/libultra/voice/voicecontread2.c index a5c2e19ae..f7e11fe69 100644 --- a/src/libultra/voice/voicecontread2.c +++ b/src/libultra/voice/voicecontread2.c @@ -21,7 +21,7 @@ s32 __osVoiceContRead2(OSMesgQueue* mq, s32 port, u16 arg2, u8 dst[2]) { ; } - __osPfsPifRam.pifstatus = CONT_CMD_READ_BUTTON; + __osPfsPifRam.status = CONT_CMD_READ_BUTTON; ptr[0] = 0xFF; ptr[1] = 3; diff --git a/src/libultra/voice/voicecontread36.c b/src/libultra/voice/voicecontread36.c index 24df268ee..90e6104b1 100644 --- a/src/libultra/voice/voicecontread36.c +++ b/src/libultra/voice/voicecontread36.c @@ -21,7 +21,7 @@ s32 __osVoiceContRead36(OSMesgQueue* mq, s32 port, u16 arg2, u8 dst[36]) { ; } - __osPfsPifRam.pifstatus = CONT_CMD_READ_BUTTON; + __osPfsPifRam.status = CONT_CMD_READ_BUTTON; ptr[0] = 0xFF; ptr[1] = 3; diff --git a/src/libultra/voice/voicecontwrite20.c b/src/libultra/voice/voicecontwrite20.c index 62bf68594..acd3c6cd3 100644 --- a/src/libultra/voice/voicecontwrite20.c +++ b/src/libultra/voice/voicecontwrite20.c @@ -22,7 +22,7 @@ s32 __osVoiceContWrite20(OSMesgQueue* mq, s32 port, u16 arg2, u8 dst[20]) { ; } - __osPfsPifRam.pifstatus = CONT_CMD_READ_BUTTON; + __osPfsPifRam.status = CONT_CMD_READ_BUTTON; ptr[0] = 0xFF; ptr[1] = 0x17; diff --git a/src/libultra/voice/voicecontwrite4.c b/src/libultra/voice/voicecontwrite4.c index d63c8d45f..414b5cb00 100644 --- a/src/libultra/voice/voicecontwrite4.c +++ b/src/libultra/voice/voicecontwrite4.c @@ -22,7 +22,7 @@ s32 __osVoiceContWrite4(OSMesgQueue* mq, s32 port, u16 arg2, u8 dst[4]) { ; } - __osPfsPifRam.pifstatus = CONT_CMD_READ_BUTTON; + __osPfsPifRam.status = CONT_CMD_READ_BUTTON; ptr[0] = 0xFF; ptr[1] = 7; diff --git a/src/libultra/voice/voicegetstatus.c b/src/libultra/voice/voicegetstatus.c index 52d694730..f073e953b 100644 --- a/src/libultra/voice/voicegetstatus.c +++ b/src/libultra/voice/voicegetstatus.c @@ -12,7 +12,7 @@ s32 __osVoiceGetStatus(OSMesgQueue* mq, s32 port, u8* status) { do { if (errorCode != CONT_ERR_CONTRFAIL) { - __osContPifRam.pifstatus = CONT_CMD_READ_BUTTON; + __osContPifRam.status = CONT_CMD_READ_BUTTON; for (i = 0; i < port; i++, *ptr++ = 0) { ; diff --git a/src/libultra/voice/voicesetadconverter.c b/src/libultra/voice/voicesetadconverter.c index b59420b8b..a2b680345 100644 --- a/src/libultra/voice/voicesetadconverter.c +++ b/src/libultra/voice/voicesetadconverter.c @@ -24,7 +24,7 @@ s32 __osVoiceSetADConverter(OSMesgQueue* mq, s32 port, u8 arg2) { ; } - __osPfsPifRam.pifstatus = CONT_CMD_READ_BUTTON; + __osPfsPifRam.status = CONT_CMD_READ_BUTTON; ptr[0] = 3; ptr[1] = 1; diff --git a/src/overlays/actors/ovl_Bg_Ctower_Gear/z_bg_ctower_gear.c b/src/overlays/actors/ovl_Bg_Ctower_Gear/z_bg_ctower_gear.c index ff11631ef..5b47f8e4e 100644 --- a/src/overlays/actors/ovl_Bg_Ctower_Gear/z_bg_ctower_gear.c +++ b/src/overlays/actors/ovl_Bg_Ctower_Gear/z_bg_ctower_gear.c @@ -89,9 +89,9 @@ void BgCtowerGear_Splash(BgCtowerGear* this, GlobalContext* globalCtx) { flags = this->dyna.actor.flags & 0x40; rotZ = this->dyna.actor.shape.rot.z & 0x1FFF; if ((flags != 0) && (rotZ < 0x1B58) && (rotZ >= 0x1388)) { - Matrix_RotateY(this->dyna.actor.home.rot.y, 0); - Matrix_InsertXRotation_s(this->dyna.actor.home.rot.x, 1); - Matrix_InsertZRotation_s(this->dyna.actor.home.rot.z, 1); + Matrix_RotateY(this->dyna.actor.home.rot.y, MTXMODE_NEW); + Matrix_InsertXRotation_s(this->dyna.actor.home.rot.x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->dyna.actor.home.rot.z, MTXMODE_APPLY); for (i = 0; i < 4; i++) { if ((u32)Rand_Next() >= 0x40000000) { splashOffset.x = D_80AD3270[i].x - (Rand_ZeroOne() * 30.0f); @@ -107,9 +107,9 @@ void BgCtowerGear_Splash(BgCtowerGear* this, GlobalContext* globalCtx) { } if ((rotZ < 0x1F4) && (rotZ >= 0)) { if (flags != 0) { - Matrix_RotateY(this->dyna.actor.home.rot.y, 0); - Matrix_InsertXRotation_s(this->dyna.actor.home.rot.x, 1); - Matrix_InsertZRotation_s(this->dyna.actor.home.rot.z, 1); + Matrix_RotateY(this->dyna.actor.home.rot.y, MTXMODE_NEW); + Matrix_InsertXRotation_s(this->dyna.actor.home.rot.x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->dyna.actor.home.rot.z, MTXMODE_APPLY); for (i = 0; i < 3; i++) { for (j = 0; j < 2; j++) { splashOffset.x = D_80AD32A0[i].x + (Rand_ZeroOne() * 10.0f); diff --git a/src/overlays/actors/ovl_Bg_Dkjail_Ivy/z_bg_dkjail_ivy.c b/src/overlays/actors/ovl_Bg_Dkjail_Ivy/z_bg_dkjail_ivy.c index 9071dd520..c5757ad0d 100644 --- a/src/overlays/actors/ovl_Bg_Dkjail_Ivy/z_bg_dkjail_ivy.c +++ b/src/overlays/actors/ovl_Bg_Dkjail_Ivy/z_bg_dkjail_ivy.c @@ -1,7 +1,7 @@ /* * File: z_bg_dkjail_ivy.c * Overlay: ovl_Bg_Dkjail_Ivy - * Description: Ivy in Deku Jail + * Description: Cuttable Ivy wall (beneath Woodfall Temple, Swamp Spider House) */ #include "z_bg_dkjail_ivy.h" diff --git a/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h b/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h index 5eac10d0b..4a0e14d2f 100644 --- a/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h +++ b/src/overlays/actors/ovl_Bg_Dy_Yoseizo/z_bg_dy_yoseizo.h @@ -10,7 +10,7 @@ typedef void (*BgDyYoseizoActionFunc)(struct BgDyYoseizo*, GlobalContext*); typedef struct BgDyYoseizo { /* 0x0000 */ Actor actor; /* 0x0144 */ BgDyYoseizoActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x33BC]; + /* 0x0148 */ char unk_148[0x33BC]; } BgDyYoseizo; // size = 0x3504 extern const ActorInit Bg_Dy_Yoseizo_InitVars; diff --git a/src/overlays/actors/ovl_Bg_F40_Swlift/z_bg_f40_swlift.c b/src/overlays/actors/ovl_Bg_F40_Swlift/z_bg_f40_swlift.c index a4e20816b..672ba1f46 100644 --- a/src/overlays/actors/ovl_Bg_F40_Swlift/z_bg_f40_swlift.c +++ b/src/overlays/actors/ovl_Bg_F40_Swlift/z_bg_f40_swlift.c @@ -1,7 +1,7 @@ /* * File: z_bg_f40_swlift.c * Overlay: ovl_Bg_F40_Swlift - * Description: + * Description: Unused Stone Tower vertically-oscillating platform */ #include "z_bg_f40_swlift.h" diff --git a/src/overlays/actors/ovl_Bg_Fire_Wall/z_bg_fire_wall.h b/src/overlays/actors/ovl_Bg_Fire_Wall/z_bg_fire_wall.h index 8bbcb45bf..b4d176d9e 100644 --- a/src/overlays/actors/ovl_Bg_Fire_Wall/z_bg_fire_wall.h +++ b/src/overlays/actors/ovl_Bg_Fire_Wall/z_bg_fire_wall.h @@ -10,7 +10,7 @@ typedef void (*BgFireWallActionFunc)(struct BgFireWall*, GlobalContext*); typedef struct BgFireWall { /* 0x0000 */ Actor actor; /* 0x0144 */ BgFireWallActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x68]; + /* 0x0148 */ char unk_148[0x68]; } BgFireWall; // size = 0x1B0 extern const ActorInit Bg_Fire_Wall_InitVars; diff --git a/src/overlays/actors/ovl_Bg_Fu_Mizu/z_bg_fu_mizu.c b/src/overlays/actors/ovl_Bg_Fu_Mizu/z_bg_fu_mizu.c index dbfe2eaf4..15ac358ca 100644 --- a/src/overlays/actors/ovl_Bg_Fu_Mizu/z_bg_fu_mizu.c +++ b/src/overlays/actors/ovl_Bg_Fu_Mizu/z_bg_fu_mizu.c @@ -1,7 +1,7 @@ /* * File: z_bg_fu_mizu.c * Overlay: ovl_Bg_Fu_Mizu - * Description: + * Description: Water in Honey and Darling's Second Day game */ #include "z_bg_fu_mizu.h" diff --git a/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.c b/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.c index b0e79b3db..3d0f5c204 100644 --- a/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.c +++ b/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.c @@ -15,7 +15,13 @@ void BgGoronOyu_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgGoronOyu_Update(Actor* thisx, GlobalContext* globalCtx); void BgGoronOyu_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80B40100(BgGoronOyu* this, GlobalContext* globalCtx); +void func_80B400C8(BgGoronOyu* this, GlobalContext* globalCtx); +void func_80B401F8(BgGoronOyu* this, GlobalContext* globalCtx); +void BgGoronOyu_UpdateWaterBoxInfo(BgGoronOyu* this, GlobalContext* globalCtx); +void BgGoronOyu_SpawnParticles(BgGoronOyu* this, GlobalContext* globalCtx); +void func_80B40160(BgGoronOyu* this, GlobalContext* globalCtx); + const ActorInit Bg_Goron_Oyu_InitVars = { ACTOR_BG_GORON_OYU, ACTORCAT_BG, @@ -28,31 +34,163 @@ const ActorInit Bg_Goron_Oyu_InitVars = { (ActorFunc)BgGoronOyu_Draw, }; -#endif +extern Gfx D_06000080; +extern Gfx D_06000158; +extern AnimatedMaterial D_06000968; +extern CollisionHeader D_06000988; -extern UNK_TYPE D_06000968; -extern UNK_TYPE D_06000988; +void func_80B40080(BgGoronOyu* this) { + this->unk_17E = 1; + this->actionFunc = func_80B400C8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/func_80B40080.s") +void func_80B4009C(BgGoronOyu* this) { + this->unk_17E = 0; + this->initialActorCutscene = this->dyna.actor.cutscene; + this->actionFunc = func_80B40100; + this->unk_164 = 20.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/func_80B4009C.s") +void func_80B400C8(BgGoronOyu* this, GlobalContext* globalCtx) { + BgGoronOyu_UpdateWaterBoxInfo(this, globalCtx); + func_80B401F8(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/func_80B400C8.s") +void func_80B40100(BgGoronOyu* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->initialActorCutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->initialActorCutscene, &this->dyna.actor); + this->actionFunc = func_80B40160; + } else { + ActorCutscene_SetIntentToPlay(this->initialActorCutscene); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/func_80B40100.s") +void func_80B40160(BgGoronOyu* this, GlobalContext* globalCtx) { + static Vec3f D_80B40780 = { 0, 0, 0 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/func_80B40160.s") + Math_StepToF(&this->unk_164, 0.0f, 0.2f); + this->dyna.actor.world.pos.y = this->dyna.actor.home.pos.y - this->unk_164; + BgGoronOyu_UpdateWaterBoxInfo(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/func_80B401F8.s") + if (this->unk_164 <= 0.0f) { + ActorCutscene_Stop(this->initialActorCutscene); + this->unk_164 = 0.0f; + func_80B40080(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/func_80B40308.s") + func_8019F1C0(&D_80B40780, NA_SE_EV_WATER_LEVEL_DOWN - SFX_FLAG); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/func_80B40394.s") +void func_80B401F8(BgGoronOyu* this, GlobalContext* globalCtx) { + Player* player; + Vec3f dist; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/BgGoronOyu_Init.s") + if (Actor_HasParent(&this->dyna.actor, globalCtx)) { + this->dyna.actor.parent = NULL; + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/BgGoronOyu_Destroy.s") + player = GET_PLAYER(globalCtx); + Math_Vec3f_DistXYZAndStoreDiff(&this->waterBoxPos, &player->actor.world.pos, &dist); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/BgGoronOyu_Update.s") + if (dist.x >= 0.0f && dist.x <= this->waterBoxXLength && dist.z >= 0.0f && dist.z <= this->waterBoxZLength && + fabsf(dist.y) < 100.0f && player->actor.depthInWater > 12.0f) { + func_800B8A1C(&this->dyna.actor, globalCtx, 0xBA, this->dyna.actor.xzDistToPlayer, + fabsf(this->dyna.actor.playerHeightRel)); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Goron_Oyu/BgGoronOyu_Draw.s") +void BgGoronOyu_UpdateWaterBoxInfo(BgGoronOyu* this, GlobalContext* globalCtx) { + WaterBox* waterBox; + f32 ySurface; + + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.z, + &ySurface, &waterBox)) { + Math_Vec3s_ToVec3f(&this->waterBoxPos, &waterBox->minPos); + this->waterBoxXLength = waterBox->xLength; + this->waterBoxZLength = waterBox->zLength; + } +} + +void BgGoronOyu_SpawnParticles(BgGoronOyu* this, GlobalContext* globalCtx) { + s16 scale; + Vec3f pos1; + Vec3f pos2; + CollisionPoly* poly; + s32 pad; + + if ((globalCtx->state.frames % 4) == 0) { + Vec3f vel1; + Vec3f vel2; + + pos1.x = this->dyna.actor.world.pos.x; + pos1.y = this->dyna.actor.world.pos.y + 100.0f; + pos1.z = this->dyna.actor.world.pos.z; + vel1.x = 0.0f; + vel1.y = 2.5f; + vel1.z = 0.0f; + scale = -200 - (s32)(Rand_ZeroOne() * 50.0f); + + if (BgCheck_EntityRaycastFloor2(globalCtx, &globalCtx->colCtx, &poly, &pos1) < this->waterBoxPos.y) { + pos1.y = this->waterBoxPos.y + 10.0f; + EffectSsIceSmoke_Spawn(globalCtx, &pos1, &vel1, &gZeroVec3f, scale); + } + pos2.x = (Rand_ZeroOne() * this->waterBoxXLength) + this->waterBoxPos.x; + pos2.y = this->waterBoxPos.y + 100.0f; + pos2.z = (Rand_ZeroOne() * this->waterBoxZLength) + this->waterBoxPos.z; + vel2.x = 0.0f; + vel2.y = 0.5f; + vel2.z = 0.0f; + scale = -200 - (s32)(Rand_ZeroOne() * 50.0f); + + if (BgCheck_EntityRaycastFloor2(globalCtx, &globalCtx->colCtx, &poly, &pos2) < this->waterBoxPos.y) { + pos2.y = this->waterBoxPos.y + 10.0f; + EffectSsIceSmoke_Spawn(globalCtx, &pos2, &vel2, &gZeroVec3f, scale); + } + } +} + +void BgGoronOyu_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + BgGoronOyu* this = THIS; + CollisionHeader* colHeader = NULL; + + Actor_SetScale(&this->dyna.actor, 0.1f); + DynaPolyActor_Init(&this->dyna, 1); + CollisionHeader_GetVirtual(&D_06000988, &colHeader); + + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader); + + BgGoronOyu_UpdateWaterBoxInfo(this, globalCtx); + + if (thisx->params != 0) { + thisx->world.pos.y = thisx->home.pos.y; + func_80B40080(this); + } else { + thisx->world.pos.y = thisx->home.pos.y - 20.0f; + func_80B4009C(this); + } +} + +void BgGoronOyu_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgGoronOyu* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} + +void BgGoronOyu_Update(Actor* thisx, GlobalContext* globalCtx) { + BgGoronOyu* this = THIS; + + this->actionFunc(this, globalCtx); + BgGoronOyu_SpawnParticles(this, globalCtx); +} + +void BgGoronOyu_Draw(Actor* thisx, GlobalContext* globalCtx) { + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_06000968)); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, &D_06000158); + gSPDisplayList(POLY_XLU_DISP++, &D_06000080); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.h b/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.h index e60a42af2..dba8bb044 100644 --- a/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.h +++ b/src/overlays/actors/ovl_Bg_Goron_Oyu/z_bg_goron_oyu.h @@ -8,12 +8,15 @@ struct BgGoronOyu; typedef void (*BgGoronOyuActionFunc)(struct BgGoronOyu*, GlobalContext*); typedef struct BgGoronOyu { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x18]; - /* 0x015C */ BgGoronOyuActionFunc actionFunc; - /* 0x0160 */ char unk_160[0x20]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ BgGoronOyuActionFunc actionFunc; + /* 0x160 */ UNK_TYPE unk_160; + /* 0x164 */ f32 unk_164; + /* 0x168 */ Vec3f waterBoxPos; + /* 0x174 */ f32 waterBoxXLength; + /* 0x178 */ f32 waterBoxZLength; + /* 0x17C */ s16 initialActorCutscene; + /* 0x17E */ u16 unk_17E; } BgGoronOyu; // size = 0x180 -extern const ActorInit Bg_Goron_Oyu_InitVars; - #endif // Z_BG_GORON_OYU_H diff --git a/src/overlays/actors/ovl_Bg_Hakugin_Post/z_bg_hakugin_post.c b/src/overlays/actors/ovl_Bg_Hakugin_Post/z_bg_hakugin_post.c index 77a0cb2ee..cf628cc95 100644 --- a/src/overlays/actors/ovl_Bg_Hakugin_Post/z_bg_hakugin_post.c +++ b/src/overlays/actors/ovl_Bg_Hakugin_Post/z_bg_hakugin_post.c @@ -362,7 +362,7 @@ void func_80A9B554(BgHakuginPost* this, GlobalContext* globalCtx, BgHakuginPostU spA0.x = Math_SinS(val) * temp_f20 + spB8.x; spA0.y = (Rand_ZeroOne() * 1.2f - 0.1f) * spE4 + spB8.y; spA0.z = Math_CosS(val) * temp_f20 + spB8.z; - func_800B0E48(globalCtx, &spA0, &D_801D15B0, &D_80A9D8EC, &D_80A9D8E4, &D_80A9D8E8, + func_800B0E48(globalCtx, &spA0, &gZeroVec3f, &D_80A9D8EC, &D_80A9D8E4, &D_80A9D8E8, (Rand_Next() >> 0x1A) + 0x82, (Rand_Next() >> 0x1A) + 0x6E); } diff --git a/src/overlays/actors/ovl_Bg_Ikana_Dharma/z_bg_ikana_dharma.c b/src/overlays/actors/ovl_Bg_Ikana_Dharma/z_bg_ikana_dharma.c index 8821fc5f4..1b222a2f8 100644 --- a/src/overlays/actors/ovl_Bg_Ikana_Dharma/z_bg_ikana_dharma.c +++ b/src/overlays/actors/ovl_Bg_Ikana_Dharma/z_bg_ikana_dharma.c @@ -1,7 +1,7 @@ /* * File: z_bg_ikana_dharma.c * Overlay: ovl_Bg_Ikana_Dharma - * Description: Ikana Castle - Punchable Pillar Segments + * Description: Stone Tower Temple - Punchable Pillar Segments */ #include "z_bg_ikana_dharma.h" diff --git a/src/overlays/actors/ovl_Bg_Inibs_Movebg/z_bg_inibs_movebg.c b/src/overlays/actors/ovl_Bg_Inibs_Movebg/z_bg_inibs_movebg.c index 817cda67e..c75db5306 100644 --- a/src/overlays/actors/ovl_Bg_Inibs_Movebg/z_bg_inibs_movebg.c +++ b/src/overlays/actors/ovl_Bg_Inibs_Movebg/z_bg_inibs_movebg.c @@ -14,7 +14,6 @@ void BgInibsMovebg_Init(Actor* thisx, GlobalContext* globalCtx); void BgInibsMovebg_Destroy(Actor* thisx, GlobalContext* globalCtx); void BgInibsMovebg_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Bg_Inibs_Movebg_InitVars = { ACTOR_BG_INIBS_MOVEBG, ACTORCAT_BG, @@ -27,17 +26,56 @@ const ActorInit Bg_Inibs_Movebg_InitVars = { (ActorFunc)BgInibsMovebg_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B96578[] = { +extern Gfx D_06001C10[]; +extern Gfx D_06001DC0[]; +extern AnimatedMaterial D_06002598; +extern Gfx D_06006140[]; +extern Gfx D_060062D8[]; +extern AnimatedMaterial D_06006858; +Gfx* D_80B96560[] = { D_060062D8, D_06001DC0 }; +Gfx* D_80B96568[] = { D_06006140, D_06001C10 }; +AnimatedMaterial* D_80B96570[] = { &D_06006858, &D_06002598 }; + +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 1000, ICHAIN_STOP), }; -#endif +void BgInibsMovebg_Init(Actor* thisx, GlobalContext* globalCtx) { + BgInibsMovebg* this = THIS; -extern InitChainEntry D_80B96578[]; + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + DynaPolyActor_Init(&this->dyna, 1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Inibs_Movebg/BgInibsMovebg_Init.s") + this->unk_15C = D_80B96560[BGINIBSMOVEBG_GET_F(thisx)]; + this->unk_160 = D_80B96568[BGINIBSMOVEBG_GET_F(thisx)]; + this->unk_164 = D_80B96570[BGINIBSMOVEBG_GET_F(thisx)]; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Inibs_Movebg/BgInibsMovebg_Destroy.s") +void BgInibsMovebg_Destroy(Actor* thisx, GlobalContext* globalCtx) { + BgInibsMovebg* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Bg_Inibs_Movebg/BgInibsMovebg_Draw.s") + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); +} + +void BgInibsMovebg_Draw(Actor* thisx, GlobalContext* globalCtx) { + BgInibsMovebg* this = THIS; + + AnimatedMaterial* animMat; + Gfx* dl1; + Gfx* dl2; + + animMat = this->unk_164; + if (animMat != NULL) { + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(this->unk_164)); + } + + dl1 = this->unk_15C; + if (dl1 != NULL) { + func_800BDFC0(globalCtx, this->unk_15C); + } + + dl2 = this->unk_160; + if (dl2 != NULL) { + func_800BE03C(globalCtx, this->unk_160); + } +} diff --git a/src/overlays/actors/ovl_Bg_Inibs_Movebg/z_bg_inibs_movebg.h b/src/overlays/actors/ovl_Bg_Inibs_Movebg/z_bg_inibs_movebg.h index fea6c8a67..92494a35f 100644 --- a/src/overlays/actors/ovl_Bg_Inibs_Movebg/z_bg_inibs_movebg.h +++ b/src/overlays/actors/ovl_Bg_Inibs_Movebg/z_bg_inibs_movebg.h @@ -5,9 +5,13 @@ struct BgInibsMovebg; +#define BGINIBSMOVEBG_GET_F(thisx) ((u16)((thisx)->params) & 0xF) + typedef struct BgInibsMovebg { - /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x24]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ Gfx* unk_15C; + /* 0x160 */ Gfx* unk_160; + /* 0x164 */ AnimatedMaterial* unk_164; } BgInibsMovebg; // size = 0x168 extern const ActorInit Bg_Inibs_Movebg_InitVars; diff --git a/src/overlays/actors/ovl_Bg_Kin2_Fence/z_bg_kin2_fence.c b/src/overlays/actors/ovl_Bg_Kin2_Fence/z_bg_kin2_fence.c index cc92791fc..ac5672238 100644 --- a/src/overlays/actors/ovl_Bg_Kin2_Fence/z_bg_kin2_fence.c +++ b/src/overlays/actors/ovl_Bg_Kin2_Fence/z_bg_kin2_fence.c @@ -149,7 +149,7 @@ void BgKin2Fence_SpawnEyeSparkles(BgKin2Fence* this, GlobalContext* globalCtx, s for (i = 0; i < 2; i++) { Matrix_MultiplyVector3fByState(&eyeSparkleSpawnPositions[mask][i], &sp58); - EffectSsKiraKira_SpawnDispersed(globalCtx, &sp58, &D_801D15B0, &D_801D15B0, &primColor, &envColor, 6000, -10); + EffectSsKiraKira_SpawnDispersed(globalCtx, &sp58, &gZeroVec3f, &gZeroVec3f, &primColor, &envColor, 6000, -10); } } diff --git a/src/overlays/actors/ovl_Bg_Market_Step/z_bg_market_step.c b/src/overlays/actors/ovl_Bg_Market_Step/z_bg_market_step.c index b5b13cd7c..b5f8e9c49 100644 --- a/src/overlays/actors/ovl_Bg_Market_Step/z_bg_market_step.c +++ b/src/overlays/actors/ovl_Bg_Market_Step/z_bg_market_step.c @@ -1,7 +1,7 @@ /* * File: z_bg_market_step.c * Overlay: ovl_Bg_Market_Step - * Description: West Clocktown - Stairs + * Description: West Clocktown - most scenery */ #include "z_bg_market_step.h" diff --git a/src/overlays/actors/ovl_Bg_Open_Shutter/z_bg_open_shutter.c b/src/overlays/actors/ovl_Bg_Open_Shutter/z_bg_open_shutter.c index 94a148c17..ecfc8ad02 100644 --- a/src/overlays/actors/ovl_Bg_Open_Shutter/z_bg_open_shutter.c +++ b/src/overlays/actors/ovl_Bg_Open_Shutter/z_bg_open_shutter.c @@ -1,7 +1,7 @@ /* * File: z_bg_open_shutter.c * Overlay: ovl_Bg_Open_Shutter - * Description: + * Description: Sliding doors in opening dungeon */ #include "z_bg_open_shutter.h" diff --git a/src/overlays/actors/ovl_Bg_Spout_Fire/z_bg_spout_fire.h b/src/overlays/actors/ovl_Bg_Spout_Fire/z_bg_spout_fire.h index e2ae36112..6fc19e4ca 100644 --- a/src/overlays/actors/ovl_Bg_Spout_Fire/z_bg_spout_fire.h +++ b/src/overlays/actors/ovl_Bg_Spout_Fire/z_bg_spout_fire.h @@ -10,7 +10,7 @@ typedef void (*BgSpoutFireActionFunc)(struct BgSpoutFire*, GlobalContext*); typedef struct BgSpoutFire { /* 0x0000 */ Actor actor; /* 0x0144 */ BgSpoutFireActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x50]; + /* 0x0148 */ char unk_148[0x50]; } BgSpoutFire; // size = 0x198 extern const ActorInit Bg_Spout_Fire_InitVars; diff --git a/src/overlays/actors/ovl_Boss_02/z_boss_02.c b/src/overlays/actors/ovl_Boss_02/z_boss_02.c index 32d75abba..f0455bb05 100644 --- a/src/overlays/actors/ovl_Boss_02/z_boss_02.c +++ b/src/overlays/actors/ovl_Boss_02/z_boss_02.c @@ -555,8 +555,8 @@ void func_809DA460(Boss02Effects* effects, Vec3f* vec) { if ((effects->unk_24 == 0) || (effects->unk_24 == 3)) { effects->unk_24 = 4; effects->unk_00 = *vec; - Math_Vec3f_Copy(&effects->unk_0C, &D_801D15B0); - Math_Vec3f_Copy(&effects->unk_18, &D_801D15B0); + Math_Vec3f_Copy(&effects->unk_0C, &gZeroVec3f); + Math_Vec3f_Copy(&effects->unk_18, &gZeroVec3f); effects->unk_2C = 0xFF; effects->unk_34 = 0.0f; break; @@ -680,8 +680,6 @@ void func_809DAAA8(Boss02* this, GlobalContext* globalCtx) { this->actor.world.pos.y = -500.0f; } -#ifdef NON_MATCHING -// Saving to spC8 rather than spC4 at line 18dc void func_809DAB78(Boss02* this, GlobalContext* globalCtx) { static Color_RGBA8 D_809DFA98 = { 185, 140, 70, 255 }; s32 pad; @@ -992,15 +990,15 @@ void func_809DAB78(Boss02* this, GlobalContext* globalCtx) { this->actor.minVelocityY = -1000.0f * D_809DF5B0; this->unk_0164 = randPlusMinusPoint5Scaled(0.05f); - spC4 = player->actor.world.pos.x - this->actor.world.pos.x; - spC8 = player->actor.world.pos.z - this->actor.world.pos.z; - if (sqrtf(SQ(spC4) + SQ(spC8)) < (400.0f * D_809DF5B0)) { + spCC = player->actor.world.pos.x - this->actor.world.pos.x; + spC4 = player->actor.world.pos.z - this->actor.world.pos.z; + if (sqrtf(SQ(spCC) + SQ(spC4)) < (400.0f * D_809DF5B0)) { this->actor.speedXZ = 15.0f * D_809DF5B0; } - spC4 = this->actor.world.pos.x; - spC8 = this->actor.world.pos.z; - if (sqrtf(SQ(spC4) + SQ(spC8)) < (400.0f * D_809DF5B0)) { + spCC = this->actor.world.pos.x; + spC4 = this->actor.world.pos.z; + if (sqrtf(SQ(spCC) + SQ(spC4)) < (400.0f * D_809DF5B0)) { this->actor.speedXZ = 15.0f * D_809DF5B0; } @@ -1051,7 +1049,7 @@ void func_809DAB78(Boss02* this, GlobalContext* globalCtx) { sp9C = Rand_ZeroFloat(M_PI); for (i = 0; i < 15; i++) { - Matrix_InsertYRotation_f(((2.0f * (i * M_PI)) / 15.0f) + sp9C, 0); + Matrix_InsertYRotation_f(((2.0f * (i * M_PI)) / 15.0f) + sp9C, MTXMODE_NEW); Matrix_GetStateTranslationAndScaledZ((10 - this->unk_0146[0]) * (D_809DF5B0 * 300.0f) * 0.1f, &sp90); spD0.x = this->unk_0170.x + sp90.x; @@ -1081,10 +1079,6 @@ void func_809DAB78(Boss02* this, GlobalContext* globalCtx) { Collider_UpdateCylinder(&this->actor, &this->colliderCylinder); CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base); } -#else -static Color_RGBA8 D_809DFA98 = { 185, 140, 70, 255 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_02/func_809DAB78.s") -#endif void func_809DBFB4(Boss02* this, GlobalContext* globalCtx) { Boss02* temp_s6 = this->unk_1674; @@ -1477,7 +1471,7 @@ void Boss02_Draw(Actor* thisx, GlobalContext* globalCtx2) { } func_809DA50C(1, &this->colliderSphere2, &this->unk_147C[i + 1]); - SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->projectionMatrix, &this->unk_147C[i + 1], &this->unk_167C, + SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, &this->unk_147C[i + 1], &this->unk_167C, &this->actor.projectedW); } else { func_809DA50C(i, &this->colliderSphere1, &this->unk_147C[i + 1]); @@ -1584,7 +1578,7 @@ void func_809DD2F8(GlobalContext* globalCtx) { (effect->unk_26 + (i * 3)) * 5, 32, 64, 1, 0, 0, 32, 32)); Matrix_InsertTranslation(effect->unk_00.x, effect->unk_00.y, effect->unk_00.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(effect->unk_34 * D_809DF5B0, effect->unk_34 * D_809DF5B0, 1.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), @@ -1625,7 +1619,7 @@ void func_809DD2F8(GlobalContext* globalCtx) { gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 200, (u8)effect->unk_2C); Matrix_InsertTranslation(effect->unk_00.x, effect->unk_00.y, effect->unk_00.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(effect->unk_34 * D_809DF5B0, effect->unk_34 * D_809DF5B0, 1.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), @@ -1649,7 +1643,7 @@ void func_809DD2F8(GlobalContext* globalCtx) { (effect->unk_26 + (i * 3)) * 5, 32, 64, 1, 0, 0, 32, 32)); Matrix_InsertTranslation(effect->unk_00.x, effect->unk_00.y, effect->unk_00.z, 0); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(effect->unk_34 * D_809DF5B0, effect->unk_34 * D_809DF5B0, 1.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), @@ -1826,7 +1820,7 @@ void func_809DD934(Boss02* this, GlobalContext* globalCtx) { if (D_809E0434 != NULL) { D_809E0434->unk_203 = 0; D_809E0434->unk_204 = 1.0f; - D_809E0434->actor.world.pos.y = 60.0f; + D_809E0434->dyna.actor.world.pos.y = 60.0f; } player->actor.world.pos.x *= 10.0f; @@ -1898,7 +1892,7 @@ void func_809DD934(Boss02* this, GlobalContext* globalCtx) { if (D_809E0434 != 0) { D_809E0434->unk_203 = 1; D_809E0434->unk_204 = 0.1f; - D_809E0434->actor.world.pos.y = 3155.0f; + D_809E0434->dyna.actor.world.pos.y = 3155.0f; } player->actor.world.pos.x *= 0.1f; diff --git a/src/overlays/actors/ovl_Boss_02/z_boss_02.h b/src/overlays/actors/ovl_Boss_02/z_boss_02.h index d630acb8f..babf40b76 100644 --- a/src/overlays/actors/ovl_Boss_02/z_boss_02.h +++ b/src/overlays/actors/ovl_Boss_02/z_boss_02.h @@ -40,7 +40,7 @@ typedef struct Boss02 { /* 0x016C */ s16 unk_016C; /* 0x0170 */ Vec3f unk_0170; /* 0x017C */ Vec3f unk_017C; - /* 0x018C */ Vec3f unk_0188; + /* 0x0188 */ Vec3f unk_0188; /* 0x0194 */ u8 unk_0194; /* 0x0195 */ u8 unk_0195; /* 0x0196 */ s16 unk_0196; @@ -53,7 +53,7 @@ typedef struct Boss02 { /* 0x01AC */ f32 unk_01AC; /* 0x01B0 */ Vec3f unk_01B0; /* 0x01BC */ Vec3f unk_01BC[200]; - /* 0x0B1c */ Vec3f unk_0B1C[200]; + /* 0x0B1C */ Vec3f unk_0B1C[200]; /* 0x147C */ Vec3f unk_147C[23]; /* 0x1590 */ SkelAnime skelAnime; /* 0x15D4 */ Vec3s jointTable[13]; diff --git a/src/overlays/actors/ovl_Boss_03/z_boss_03.h b/src/overlays/actors/ovl_Boss_03/z_boss_03.h index e93baca0b..ca8a92328 100644 --- a/src/overlays/actors/ovl_Boss_03/z_boss_03.h +++ b/src/overlays/actors/ovl_Boss_03/z_boss_03.h @@ -9,9 +9,13 @@ typedef void (*Boss03ActionFunc)(struct Boss03*, GlobalContext*); typedef struct Boss03 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1E4]; + /* 0x0144 */ UNK_TYPE1 unk_144[0x10E]; + /* 0x0252 */ s8 unk_252; // number of Tanron3 fish that are currently alive, maybe "numSmallFishAlive"? + /* 0x0253 */ UNK_TYPE1 unk_253[0xD1]; + /* 0x0324 */ s16 unk_324; + /* 0x0326 */ UNK_TYPE1 unk_326[0x2]; /* 0x0328 */ Boss03ActionFunc actionFunc; - /* 0x032C */ char unk_32C[0x250]; + /* 0x032C */ UNK_TYPE1 unk_32C[0x250]; } Boss03; // size = 0x57C extern const ActorInit Boss_03_InitVars; diff --git a/src/overlays/actors/ovl_Boss_04/z_boss_04.c b/src/overlays/actors/ovl_Boss_04/z_boss_04.c index 3e3ca12c1..ace591bb9 100644 --- a/src/overlays/actors/ovl_Boss_04/z_boss_04.c +++ b/src/overlays/actors/ovl_Boss_04/z_boss_04.c @@ -5,6 +5,7 @@ */ #include "z_boss_04.h" +#include "objects/object_boss04/object_boss04.h" #define FLAGS 0x00000035 @@ -15,14 +16,18 @@ void Boss04_Destroy(Actor* thisx, GlobalContext* globalCtx); void Boss04_Update(Actor* thisx, GlobalContext* globalCtx); void Boss04_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_809EC544(Boss04* this); void func_809EC568(Boss04* this, GlobalContext* globalCtx); +void func_809ECD00(Boss04* this, GlobalContext* globalCtx); void func_809ECD18(Boss04* this, GlobalContext* globalCtx); +void func_809ECEF4(Boss04* this); void func_809ECF58(Boss04* this, GlobalContext* globalCtx); +void func_809ED224(Boss04* this); void func_809ED2A0(Boss04* this, GlobalContext* globalCtx); -#if 0 -// static DamageTable sDamageTable = { -static DamageTable D_809EE150 = { +static u8 D_809EE4D0; + +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(1, 0xF), /* Deku Stick */ DMG_ENTRY(1, 0xF), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -69,75 +74,777 @@ const ActorInit Boss_04_InitVars = { (ActorFunc)Boss04_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_809EE190[1] = { +static ColliderJntSphElementInit sJntSphElementsInit1[1] = { { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 50 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_809EE1B4 = { - { COLTYPE_HIT3, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 1, D_809EE190, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit1 = { + { + COLTYPE_HIT3, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit1, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_809EE1C4[1] = { +static ColliderJntSphElementInit sJntSphElementsInit2[1] = { { - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x08 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x08 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 70 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_809EE1E8 = { - { COLTYPE_METAL, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 1, D_809EE1C4, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit2 = { + { + COLTYPE_METAL, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit2, }; -#endif +void func_809EC040(s32 index, ColliderJntSph* collider, Vec3f* arg2) { + collider->elements[index].dim.worldSphere.center.x = arg2->x; + collider->elements[index].dim.worldSphere.center.y = arg2->y; + collider->elements[index].dim.worldSphere.center.z = arg2->z; + collider->elements[index].dim.worldSphere.radius = + collider->elements[index].dim.modelSphere.radius * collider->elements[index].dim.scale; +} -extern DamageTable D_809EE150; -extern ColliderJntSphElementInit D_809EE190[1]; -extern ColliderJntSphInit D_809EE1B4; -extern ColliderJntSphElementInit D_809EE1C4[1]; -extern ColliderJntSphInit D_809EE1E8; +void Boss04_Init(Actor* thisx, GlobalContext* globalCtx2) { + static Vec3f D_809EE1F8[] = { + { -1000.0f, 0.0f, 0.0f }, + { 1000.0f, 0.0f, 0.0f }, + { 0.0f, 0.0f, -1000.0f }, + { 0.0f, 0.0f, 1000.0f }, + }; + GlobalContext* globalCtx = globalCtx2; + Boss04* this = THIS; + s32 i; + CollisionPoly* spC0; + Vec3f spB4; + Vec3f spA8; + s32 spA4; + f32 phi_f20; + f32 phi_f24; + Vec3f sp90; + s16 phi_s0_2; + s32 pad; -extern UNK_TYPE D_0600004C; -extern UNK_TYPE D_06004510; + if (Actor_GetRoomCleared(globalCtx, globalCtx->roomCtx.currRoom.num)) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809EC040.s") + this->actor.params = 0x64; + Actor_SetScale(&this->actor, 0.1f); + this->actor.targetMode = 5; + this->actor.hintId = 0x19; + this->actor.colChkInfo.health = 20; + this->actor.colChkInfo.damageTable = &sDamageTable; + this->unk_700 = 1.0f; + this->unk_6FC = 1.0f; + this->unk_6F8 = 1.0f; + Collider_InitAndSetJntSph(globalCtx, &this->collider1, &this->actor, &sJntSphInit1, this->collider1Elements); + Collider_InitAndSetJntSph(globalCtx, &this->collider2, &this->actor, &sJntSphInit2, this->collider2Elements); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_boss04_Skel_0045E8, &object_boss04_Anim_00004C, + this->jointTable, this->morphtable, 9); + spA8.y = this->actor.world.pos.y + 200.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/Boss04_Init.s") + for (i = 0; i < ARRAY_COUNT(D_809EE1F8); i++) { + spA8.x = D_809EE1F8[i].x + this->actor.world.pos.x; + spA8.z = D_809EE1F8[i].z + this->actor.world.pos.z; + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.world.pos, &spA8, &spB4, &spC0, 1, 0, 0, 1, + &spA4)) { + if (i == 0) { + this->unk_6D8 = spB4.x; + } else if (i == 1) { + this->unk_6DC = spB4.x; + } else if (i == 2) { + this->unk_6E0 = spB4.z; + } else if (i == 3) { + this->unk_6E4 = spB4.z; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/Boss04_Destroy.s") + this->unk_6E8 = this->unk_6D8 + ((this->unk_6DC - this->unk_6D8) * 0.5f); + this->unk_6F0 = this->unk_6E0 + ((this->unk_6E4 - this->unk_6E0) * 0.5f); + this->actor.world.pos.x = this->unk_6E8; + this->actor.world.pos.z = this->unk_6F0; + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 35.0f, 60.0f, 60.0f, 4); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809EC544.s") + if ((KREG(64) != 0) || (gSaveContext.eventInf[6] & 1)) { + func_809ECD00(this, globalCtx); + this->actor.world.pos.y = this->actor.floorHeight + 160.0f; + phi_f24 = this->actor.floorHeight; + D_809EE4D0 = KREG(41) + 50; + } else { + func_809EC544(this); + this->actor.world.pos.y = KREG(70) + (this->actor.floorHeight + 590.0f); + phi_f24 = KREG(71) + (this->actor.floorHeight + 550.0f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809EC568.s") + phi_f20 = 110.0f; + this->unk_6F6 = 82; + phi_s0_2 = 0; + for (i = 0; i < 82; i++) { + Matrix_RotateY(phi_s0_2, MTXMODE_NEW); + Matrix_GetStateTranslationAndScaledZ(phi_f20, &sp90); + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_TANRON2, this->unk_6E8 + sp90.x, + phi_f24, this->unk_6F0 + sp90.z, 0, 0, 0, i); + phi_f20 += 2.5f; + phi_s0_2 += 0x1300; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809ECD00.s") + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_TANRON2, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 100); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809ECD18.s") +void Boss04_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809ECEF4.s") +void func_809EC544(Boss04* this) { + this->actionFunc = func_809EC568; + this->actor.flags &= ~1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809ECF58.s") +void func_809EC568(Boss04* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 x; + f32 y; + f32 z; + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809ED224.s") + this->unk_704++; + this->unk_1FE = 15; + if ((this->unk_708 != 0) && (this->unk_708 < 10)) { + this->actor.world.pos.y = (Math_SinS(this->unk_1F4 * 512) * 10.0f) + (this->actor.floorHeight + 160.0f); + Matrix_RotateY(this->actor.yawTowardsPlayer, MTXMODE_NEW); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809ED2A0.s") + switch (this->unk_708) { + case 0: + this->unk_2C8 = 50; + this->unk_2D0 = 2000.0f; + if ((player->stateFlags1 & 0x100000) && (this->actor.projectedPos.z > 0.0f) && + (fabsf(this->actor.projectedPos.x) < 300.0f) && (fabsf(this->actor.projectedPos.y) < 300.0f)) { + if ((this->unk_704 >= 15) && (ActorCutscene_GetCurrentIndex() == -1)) { + Actor* boss; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809ED45C.s") + this->unk_708 = 10; + this->unk_704 = 0; + func_800EA0D4(globalCtx, &globalCtx->csCtx); + this->unk_70A = func_801694DC(globalCtx); + func_80169590(globalCtx, 0, 1); + func_80169590(globalCtx, this->unk_70A, 7); + func_800B7298(globalCtx, &this->actor, 7); + player->actor.world.pos.x = this->unk_6E8; + player->actor.world.pos.z = this->unk_6F0 + 410.0f; + player->actor.shape.rot.y = 0x7FFF; + player->actor.world.rot.y = player->actor.shape.rot.y; + Math_Vec3f_Copy(&this->unk_70C, &player->actor.world.pos); + this->unk_70C.y += 100.0f; + Math_Vec3f_Copy(&this->unk_718, &this->actor.world.pos); + func_8016566C(150); + this->unk_744 = 60.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809ED50C.s") + boss = globalCtx->actorCtx.actorList[ACTORCAT_BOSS].first; + while (boss != NULL) { + if (boss->id == ACTOR_EN_WATER_EFFECT) { + Actor_MarkForDeath(boss); + } + boss = boss->next; + } + } + } else { + this->unk_704 = 0; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/Boss04_Update.s") + case 10: + if (this->unk_704 == 3) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_EYEGOLE_DEMO_EYE); + this->unk_74A = 1; + } + this->unk_2D0 = 10000.0f; + this->unk_2C8 = 300; + Math_ApproachF(&this->unk_744, 20.0f, 0.3f, 11.0f); + if (this->unk_704 == 40) { + this->unk_708 = 11; + this->unk_704 = 0; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809EDCCC.s") + case 11: + if (this->unk_704 > 50) { + this->unk_708 = 12; + this->unk_704 = 0; + this->actor.gravity = -3.0f; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/func_809EDECC.s") + case 13: + if (this->unk_704 == 45) { + this->unk_708 = 1; + this->unk_704 = 0; + func_800B7298(globalCtx, &this->actor, 0x15); + this->actor.gravity = 0.0f; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Boss_04/Boss04_Draw.s") + case 12: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_ME_ATTACK - SFX_FLAG); + Math_ApproachF(&this->unk_718.x, this->actor.world.pos.x, 0.5f, 1000.0f); + Math_ApproachF(&this->unk_718.y, this->actor.world.pos.y, 0.5f, 1000.0f); + Math_ApproachF(&this->unk_718.z, this->actor.world.pos.z, 0.5f, 1000.0f); + if (this->actor.bgCheckFlags & 2) { + play_sound(NA_SE_IT_BIG_BOMB_EXPLOSION); + this->unk_6F4 = 15; + this->unk_708 = 13; + this->unk_704 = 0; + this->unk_2DA = 10; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, CLEAR_TAG_SPLASH); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KONB_JUMP_LEV_OLD - SFX_FLAG); + this->unk_748 = 20; + } + break; + + case 1: + player->actor.shape.rot.y = 0x7FFF; + player->actor.world.rot.y = player->actor.shape.rot.y; + Matrix_GetStateTranslationAndScaledZ(-100.0f, &this->unk_70C); + + this->unk_70C.x += player->actor.world.pos.x; + this->unk_70C.y = func_800B6FC8(player) + player->actor.world.pos.y + 36.0f; + this->unk_70C.z += player->actor.world.pos.z; + + this->unk_718.x = player->actor.world.pos.x; + this->unk_718.y = (func_800B6FC8(player) + player->actor.world.pos.y) - 4.0f; + this->unk_718.z = player->actor.world.pos.z; + + if (this->unk_704 >= 35) { + this->unk_704 = 0; + this->unk_708 = 2; + this->unk_728 = -200.0f; + } + break; + + case 2: + case 3: + Matrix_GetStateTranslationAndScaledZ(500.0f, &this->unk_70C); + this->unk_70C.x += this->actor.world.pos.x; + this->unk_70C.y += this->actor.world.pos.y - 50.0f; + this->unk_70C.z += this->actor.world.pos.z; + this->unk_718.x = this->actor.world.pos.x; + this->unk_718.z = this->actor.world.pos.z; + this->unk_718.y = (this->actor.world.pos.y - 70.0f) + this->unk_728; + Math_ApproachZeroF(&this->unk_728, 0.05f, this->unk_73C); + Math_ApproachF(&this->unk_73C, 3.0f, 1.0f, 0.05f); + if (this->unk_704 == 20) { + this->unk_708 = 3; + } + + if (this->unk_704 == 70) { + this->unk_2C8 = 300; + this->unk_2D0 = 0.0f; + D_809EE4D0 = 1; + this->unk_2E2 = 60; + this->unk_2E0 = 93; + } + + if (this->unk_704 > 140) { + Camera* sp5C = Play_GetCamera(globalCtx, MAIN_CAM); + + this->unk_708 = 0; + func_809ECD00(this, globalCtx); + sp5C->eye = this->unk_70C; + sp5C->eyeNext = this->unk_70C; + sp5C->at = this->unk_718; + func_80169AFC(globalCtx, this->unk_70A, 0); + this->unk_70A = 0; + func_800EA0EC(globalCtx, &globalCtx->csCtx); + func_800B7298(globalCtx, &this->actor, 6); + func_80165690(); + gSaveContext.eventInf[6] |= 1; + } + break; + } + + if (this->unk_70A != 0) { + Vec3f sp50; + + ShrinkWindow_SetLetterboxTarget(0x1B); + if (this->unk_748 != 0) { + this->unk_748--; + } + Math_Vec3f_Copy(&sp50, &this->unk_718); + sp50.y += Math_SinS(this->unk_748 * 0x4000) * this->unk_748 * 1.5f; + Play_CameraSetAtEye(globalCtx, this->unk_70A, &sp50, &this->unk_70C); + func_80169940(globalCtx, this->unk_70A, this->unk_744); + Math_ApproachF(&this->unk_744, 60.0f, 0.1f, 1.0f); + } + this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + x = player->actor.world.pos.x - this->actor.world.pos.x; + y = player->actor.world.pos.y - this->actor.world.pos.y; + z = player->actor.world.pos.z - this->actor.world.pos.z; + this->actor.shape.rot.x = Math_Atan2S(-y, sqrtf(SQ(x) + SQ(z))); +} + +void func_809ECD00(Boss04* this, GlobalContext* globalCtx) { + this->actionFunc = func_809ECD18; +} + +void func_809ECD18(Boss04* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (this->unk_1F4 >= 0x500) { + this->unk_1F4 -= 0x300; + this->unk_1F7 += 1; + } + + Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 10, 0x200); + this->actor.world.pos.y = (this->actor.floorHeight + KREG(17) + 160.0f) + (Math_SinS(this->unk_1F4 * 512) * 10.0f); + Math_ApproachF(&this->actor.speedXZ, this->unk_6D4, 1.0f, 0.5f); + + if (this->unk_1F8 == 0) { + this->unk_1F8 = Rand_ZeroFloat(100.0f) + 50.0f; + this->unk_6D4 = Rand_ZeroFloat(3.0f); + if (Rand_ZeroOne() < 0.1f) { + Math_Vec3f_Copy(&this->unk_6C8, &player->actor.world.pos); + } else { + this->unk_6C8.x = randPlusMinusPoint5Scaled(600.0f) + this->unk_6E8; + this->unk_6C8.z = randPlusMinusPoint5Scaled(600.0f) + this->unk_6F0; + } + } + + Math_ApproachS(&this->actor.world.rot.y, + Math_Atan2S(this->unk_6C8.x - this->actor.world.pos.x, this->unk_6C8.z - this->actor.world.pos.z), 5, + 0x200); + + if (((s8)this->actor.colChkInfo.health <= 10) || (KREG(88) != 0)) { + KREG(88) = 0; + func_809ECEF4(this); + } +} + +void func_809ECEF4(Boss04* this) { + this->actionFunc = func_809ECF58; + Math_Vec3s_Copy(&this->actor.world.rot, &this->actor.shape.rot); + this->unk_1F8 = 0; + this->unk_1F6 = 1; + this->unk_1FA = 60; + this->actor.speedXZ = 0.0f; + this->actor.gravity = -3.0f; +} + +void func_809ECF58(Boss04* this, GlobalContext* globalCtx) { + Vec3f sp3C; + + if ((this->unk_1FE == 14) || ((this->actor.bgCheckFlags & 8) && (this->unk_1F8 == 0))) { + this->unk_1F8 = 20; + if ((Rand_ZeroOne() < 0.2f) && (this->unk_1FE == 0)) { + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + this->unk_2D0 = 10000.0f; + this->unk_2C8 = 100; + } else { + this->actor.world.rot.y = BINANG_ROT180((s16)Rand_ZeroFloat(8000.0f) + this->actor.world.rot.y); + } + + this->actor.speedXZ = 0.0f; + + if (this->actor.bgCheckFlags & 8) { + play_sound(NA_SE_IT_BIG_BOMB_EXPLOSION); + func_800BC848(&this->actor, globalCtx, 15, 10); + this->unk_6F4 = 15; + sp3C.x = this->actor.focus.pos.x; + sp3C.y = this->actor.focus.pos.y; + sp3C.z = this->actor.focus.pos.z; + func_800BBFB0(globalCtx, &sp3C, 100.0f, 40, 500, 10, 0); + } + } + + Math_ApproachS(&this->actor.shape.rot.x, Math_SinS(this->unk_1F4 * 0xFB8) * 5000.0f, 5, 0x800); + Math_ApproachS(&this->actor.shape.rot.z, Math_SinS(this->unk_1F4 * 0xCD0) * 3000.0f, 5, 0x800); + + if (this->unk_6F4 == 0) { + Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 5, 0x1000); + if (this->unk_1FA == 0) { + Math_ApproachF(&this->actor.speedXZ, 20.0f, 1.0f, 1.0f); + sp3C.x = this->actor.world.pos.x; + sp3C.y = this->actor.floorHeight + 2.0f; + sp3C.z = this->actor.world.pos.z; + EffectSsGRipple_Spawn(globalCtx, &sp3C, 1400, 500, 0); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_ME_ATTACK - SFX_FLAG); + } + } + + if (KREG(88) != 0) { + KREG(88) = 0; + func_809ED224(this); + this->unk_1FE = 100; + this->unk_200 = 100; + } +} + +void func_809ED224(Boss04* this) { + this->actionFunc = func_809ED2A0; + this->unk_1F8 = 60; + this->unk_1FA = 100; + this->actor.speedXZ = 0.0f; + this->unk_2D0 = 10000.0f; + this->unk_2C8 = 200; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_ME_DEAD); + this->actor.flags &= ~1; + func_801A2ED8(); + this->unk_1F6 = 10; +} + +void func_809ED2A0(Boss04* this, GlobalContext* globalCtx) { + this->unk_2DA = 10; + + if (this->unk_1F8 >= 5) { + this->unk_6FC = (Math_SinS(this->unk_1F8 * 0x3000) * 10.0f * 0.01f) + 1.0f; + this->unk_700 = (Math_CosS(this->unk_1F8 * 0x3000) * 10.0f * 0.01f) + 1.0f; + this->unk_6F8 = this->unk_700; + } + + if (this->unk_1F8 == 5) { + this->unk_6F8 *= 1.3f; + this->unk_6FC *= 1.3f; + this->unk_700 *= 1.3f; + } + + if (this->unk_1F8 == 3) { + this->actor.flags &= ~1; + this->unk_700 = 0.0f; + this->unk_6FC = 0.0f; + this->unk_6F8 = 0.0f; + } + + if ((this->unk_1F8 == 2) || (this->unk_1F8 == 5)) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, CLEAR_TAG_LARGE_EXPLOSION); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_IT_BIG_BOMB_EXPLOSION); + } + + if (this->unk_1FA == 3) { + this->unk_1F6 = 11; + } + + if (this->unk_1FA == 0) { + Actor_MarkForDeath(&this->actor); + } +} + +void func_809ED45C(Boss04* this, GlobalContext* globalCtx) { + ColliderJntSphElement* temp_v0; + u8 damage; + + if ((this->unk_1FE == 0) && (this->collider1.elements[0].info.bumperFlags & BUMP_HIT)) { + this->collider1.elements[0].info.bumperFlags &= ~BUMP_HIT; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_ME_DAMAGE); + damage = this->actor.colChkInfo.damage; + this->actor.colChkInfo.health = this->actor.colChkInfo.health - damage; + if ((s8)this->actor.colChkInfo.health <= 0) { + func_809ED224(this); + this->unk_1FE = 100; + this->unk_200 = 100; + Enemy_StartFinishingBlow(globalCtx, &this->actor); + } else { + this->unk_2DA = 15; + this->unk_1FE = 15; + this->unk_200 = 15; + } + } +} + +void func_809ED50C(Boss04* this) { + s32 i; + + this->unk_2DE += this->unk_2E2; + this->unk_2DC += this->unk_2E0; + + Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, 0.0f, 10.0f, MTXMODE_APPLY); + Matrix_GetStateTranslation(&this->unk_6BC); + Matrix_Scale(this->actor.scale.x * 13.0f, this->actor.scale.y * 13.0f, this->actor.scale.z * 16.0f, MTXMODE_APPLY); + Matrix_RotateY(this->unk_2DC, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->unk_2DE, MTXMODE_APPLY); + Matrix_StatePush(); + + for (i = 0; i < ARRAY_COUNT(this->unk_2E4); i++) { + Matrix_RotateStateAroundXAxis(0.3926991f); + Matrix_GetStateTranslationAndScaledZ(100.0f, &this->unk_2E4[i]); + } + + Matrix_StatePop(); + Matrix_StatePush(); + Matrix_InsertTranslation(38.0f, 0.0f, 0.0f, MTXMODE_APPLY); + + for (i = 0; i < ARRAY_COUNT(this->unk_3A4); i++) { + Matrix_RotateStateAroundXAxis(0.41887903f); + Matrix_GetStateTranslationAndScaledZ(92.0f, &this->unk_3A4[i]); + } + + Matrix_StatePop(); + Matrix_StatePush(); + Matrix_InsertTranslation(-38.0f, 0.0f, 0.0f, MTXMODE_APPLY); + + for (i = 0; i < ARRAY_COUNT(this->unk_458); i++) { + Matrix_RotateStateAroundXAxis(0.41887903f); + Matrix_GetStateTranslationAndScaledZ(92.0f, &this->unk_458[i]); + } + + Matrix_StatePop(); + Matrix_StatePush(); + Matrix_InsertTranslation(71.0f, 0.0f, 0.0f, MTXMODE_APPLY); + + for (i = 0; i < ARRAY_COUNT(this->unk_50C); i++) { + Matrix_RotateStateAroundXAxis(0.5711987f); + Matrix_GetStateTranslationAndScaledZ(71.0f, &this->unk_50C[i]); + } + + Matrix_StatePop(); + Matrix_StatePush(); + Matrix_InsertTranslation(-71.0f, 0.0f, 0.0f, MTXMODE_APPLY); + + for (i = 0; i < ARRAY_COUNT(this->unk_590); i++) { + Matrix_RotateStateAroundXAxis(0.5711987f); + Matrix_GetStateTranslationAndScaledZ(71.0f, &this->unk_590[i]); + } + + Matrix_StatePop(); + Matrix_StatePush(); + Matrix_InsertTranslation(92.0f, 0.0f, 0.0f, MTXMODE_APPLY); + + for (i = 0; i < ARRAY_COUNT(this->unk_614); i++) { + Matrix_RotateStateAroundXAxis(1.0471976f); + Matrix_GetStateTranslationAndScaledZ(38.0f, &this->unk_614[i]); + } + + Matrix_StatePop(); + Matrix_StatePush(); + Matrix_InsertTranslation(-92.0f, 0.0f, 0.0f, MTXMODE_APPLY); + + for (i = 0; i < ARRAY_COUNT(this->unk_65C); i++) { + Matrix_RotateStateAroundXAxis(1.0471976f); + Matrix_GetStateTranslationAndScaledZ(38.0f, &this->unk_65C[i]); + } + + Matrix_StatePop(); + Matrix_StatePush(); + Matrix_InsertTranslation(100.0f, 0.0f, 0.0f, MTXMODE_APPLY); + + Matrix_GetStateTranslation(&this->unk_6A4); + Matrix_StatePop(); + Matrix_InsertTranslation(-100.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_GetStateTranslation(&this->unk_6B0); +} + +void Boss04_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + Boss04* this = THIS; + s16 temp_v0_8; + s32 pad; + + this->unk_1F4++; + if (KREG(63) == 0) { + if (this->unk_1F8 != 0) { + this->unk_1F8--; + } + + if (this->unk_1FA != 0) { + this->unk_1FA--; + } + + if (this->unk_2C8 != 0) { + this->unk_2C8--; + } + if (this->unk_1FE != 0) { + this->unk_1FE--; + } + + if (this->unk_200 != 0) { + this->unk_200--; + } + + if (this->unk_2DA != 0) { + this->unk_2DA--; + } + + if (this->unk_6F4 != 0) { + this->unk_6F4--; + } + + this->actionFunc(this, globalCtx); + + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + this->actor.world.pos.y -= 100.0f; + this->actor.prevPos.y -= 100.0f; + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 100.0f, 120.0f, 200.0f, 5); + this->actor.world.pos.y += 100.0f; + this->actor.prevPos.y += 100.0f; + } + + if (this->unk_200 == 10) { + this->unk_2D0 = 0.0f; + this->unk_2C8 = Rand_ZeroFloat(100.0f) + 60.0f; + } + + if (this->unk_2C8 == 0) { + this->unk_2C8 = Rand_ZeroFloat(100.0f) + 60.0f; + this->unk_2D0 = 10000.0f - this->unk_2D0; + } + + Math_ApproachF(&this->unk_2CC, this->unk_2D0, 0.2f, 1000.0f); + if (this->actionFunc != func_809ED2A0) { + temp_v0_8 = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + if (ABS_ALT(temp_v0_8) < 0x6000) { + if (temp_v0_8 > 0x2500) { + this->unk_2D6 = 0x2500; + } else if (temp_v0_8 < -0x2500) { + this->unk_2D6 = -0x2500; + } else { + this->unk_2D6 = temp_v0_8; + } + } else { + this->unk_2D6 = 0; + } + Math_ApproachS(&this->unk_2D4, this->unk_2D6, 5, 0x800); + this->unk_2D8 = 2000; + this->unk_700 = (Math_SinS(this->unk_6F4 * 0x3000) * this->unk_6F4 * 0.02f) + 1.0f; + this->unk_6FC = (Math_CosS(this->unk_6F4 * 0x3000) * this->unk_6F4 * 0.02f) + 1.0f; + this->unk_6F8 = this->unk_6FC; + this->actor.shape.yOffset = (this->unk_6FC - 1.0f) * 1000.0f; + func_809ED45C(this, globalCtx); + if (this->unk_2CC > 3000.0f) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + this->actor.flags |= 1; + } else { + this->actor.flags &= ~1; + } + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + func_809ED50C(this); + } + + if (D_809EE4D0 != 0) { + D_809EE4D0--; + if (D_809EE4D0 == 0) { + func_801A2E54(0x38); + } + } + + if (this->unk_74A != 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_ME_EXIST - SFX_FLAG); + } +} + +s32 Boss04_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + Boss04* this = THIS; + + if (limbIndex == KREG(32)) { + if (!(this->unk_1F4 & 3)) { + *dList = NULL; + } + rot->x += KREG(33) * 256; + rot->y += KREG(34) * 256; + rot->z += KREG(35) * 256; + } + + if ((limbIndex == 5) || (limbIndex == 7)) { + rot->y = (rot->y + (s16)this->unk_2CC) - 0x500; + } + + if (limbIndex == 4) { + rot->y += this->unk_2D8; + rot->z += this->unk_2D4; + if (this->unk_2DA != 0) { + rot->y = (s16)(Math_SinS(this->unk_1F4 * 0x3000) * (this->unk_2DA * 500)) + rot->y; + rot->z = (s16)(Math_SinS(this->unk_1F4 * 0x3500) * (this->unk_2DA * 300)) + rot->z; + } + } + + return false; +} + +void Boss04_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Vec3f D_809EE228 = { 0.0f, -200.0f, 0.0f }; + static Vec3f D_809EE234 = { 0.0f, 720.0f, 0.0f }; + Boss04* this = THIS; + Vec3f sp18; + + if (limbIndex == 1) { + Matrix_GetStateTranslationAndScaledY(-500.0f, &this->actor.focus.pos); + Matrix_MultiplyVector3fByState(&D_809EE228, &sp18); + func_809EC040(0, &this->collider1, &sp18); + Matrix_MultiplyVector3fByState(&D_809EE234, &sp18); + func_809EC040(0, &this->collider2, &sp18); + } +} + +void Boss04_Draw(Actor* thisx, GlobalContext* globalCtx) { + Boss04* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + if (this->unk_200 & 1) { + POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 255, 0, 0, 255, 900, 1099); + } + + Matrix_InsertTranslation(0.0f, 0.0f, 800.0f, MTXMODE_APPLY); + Matrix_Scale(this->unk_6F8, this->unk_6FC, this->unk_700, MTXMODE_APPLY); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + Boss04_OverrideLimbDraw, Boss04_PostLimbDraw, &this->actor); + + POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP); + + if (this->actionFunc != func_809EC568) { + func_8012C448(globalCtx->state.gfxCtx); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 0, 0, 0, 150); + gSPDisplayList(POLY_XLU_DISP++, object_boss04_DL_004510); + + Matrix_InsertTranslation(this->unk_6BC.x, this->actor.floorHeight, this->unk_6BC.z, MTXMODE_NEW); + Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, 0.0f, -20.0f, MTXMODE_APPLY); + Matrix_Scale(this->unk_6F8 * 1.8f, 0.0f, this->unk_700 * 2.8f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_boss04_DL_004550); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Boss_04/z_boss_04.h b/src/overlays/actors/ovl_Boss_04/z_boss_04.h index 7dec60d9c..f4542cf3a 100644 --- a/src/overlays/actors/ovl_Boss_04/z_boss_04.h +++ b/src/overlays/actors/ovl_Boss_04/z_boss_04.h @@ -9,9 +9,70 @@ typedef void (*Boss04ActionFunc)(struct Boss04*, GlobalContext*); typedef struct Boss04 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xC0]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[9]; + /* 0x01BE */ Vec3s morphtable[9]; + /* 0x01F4 */ s16 unk_1F4; + /* 0x01F6 */ s8 unk_1F6; + /* 0x01F7 */ u8 unk_1F7; + /* 0x01F8 */ s16 unk_1F8; + /* 0x01FA */ s16 unk_1FA; + /* 0x01FC */ UNK_TYPE1 unk_1FC[2]; + /* 0x01FE */ s16 unk_1FE; + /* 0x0200 */ s16 unk_200; /* 0x0204 */ Boss04ActionFunc actionFunc; - /* 0x0208 */ char unk_208[0x544]; + /* 0x0208 */ ColliderJntSph collider1; + /* 0x0228 */ ColliderJntSphElement collider1Elements[1]; + /* 0x0268 */ ColliderJntSph collider2; + /* 0x0288 */ ColliderJntSphElement collider2Elements[1]; + /* 0x02C8 */ s16 unk_2C8; + /* 0x02CC */ f32 unk_2CC; + /* 0x02D0 */ f32 unk_2D0; + /* 0x02D4 */ s16 unk_2D4; + /* 0x02D6 */ s16 unk_2D6; + /* 0x02D8 */ s16 unk_2D8; + /* 0x02DA */ s16 unk_2DA; + /* 0x02DC */ s16 unk_2DC; + /* 0x02DE */ s16 unk_2DE; + /* 0x02E0 */ s16 unk_2E0; + /* 0x02E2 */ s16 unk_2E2; + /* 0x02E4 */ Vec3f unk_2E4[16]; + /* 0x02E4 */ Vec3f unk_3A4[15]; + /* 0x02E4 */ Vec3f unk_458[15]; + /* 0x02E4 */ Vec3f unk_50C[11]; + /* 0x02E4 */ Vec3f unk_590[11]; + /* 0x02E4 */ Vec3f unk_614[6]; + /* 0x02E4 */ Vec3f unk_65C[6]; + /* 0x02E4 */ Vec3f unk_6A4; + /* 0x02E4 */ Vec3f unk_6B0; + /* 0x06BC */ Vec3f unk_6BC; + /* 0x06C8 */ Vec3f unk_6C8; + /* 0x06D4 */ f32 unk_6D4; + /* 0x06D8 */ f32 unk_6D8; + /* 0x06DC */ f32 unk_6DC; + /* 0x06E0 */ f32 unk_6E0; + /* 0x06E4 */ f32 unk_6E4; + /* 0x06E8 */ f32 unk_6E8; + /* 0x06EC */ UNK_TYPE1 unk_6EC[4]; + /* 0x06F0 */ f32 unk_6F0; + /* 0x06F4 */ s16 unk_6F4; + /* 0x06F6 */ s16 unk_6F6; + /* 0x06F8 */ f32 unk_6F8; + /* 0x06FC */ f32 unk_6FC; + /* 0x0700 */ f32 unk_700; + /* 0x0704 */ u32 unk_704; + /* 0x0708 */ s16 unk_708; + /* 0x070A */ s16 unk_70A; + /* 0x070C */ Vec3f unk_70C; + /* 0x0718 */ Vec3f unk_718; + /* 0x0724 */ UNK_TYPE1 unk_724[4]; + /* 0x0728 */ f32 unk_728; + /* 0x072C */ UNK_TYPE1 unk_72C[0x10]; + /* 0x073C */ f32 unk_73C; + /* 0x0740 */ UNK_TYPE1 unk_740[4]; + /* 0x0744 */ f32 unk_744; + /* 0x0748 */ s16 unk_748; + /* 0x074A */ u8 unk_74A; } Boss04; // size = 0x74C extern const ActorInit Boss_04_InitVars; diff --git a/src/overlays/actors/ovl_Boss_07/z_boss_07.h b/src/overlays/actors/ovl_Boss_07/z_boss_07.h index 21e30eb92..b8ace3f9c 100644 --- a/src/overlays/actors/ovl_Boss_07/z_boss_07.h +++ b/src/overlays/actors/ovl_Boss_07/z_boss_07.h @@ -10,7 +10,7 @@ typedef void (*Boss07ActionFunc)(struct Boss07*, GlobalContext*); typedef struct Boss07 { /* 0x0000 */ Actor actor; /* 0x0144 */ Boss07ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0xAAD8]; + /* 0x0148 */ char unk_148[0xAAD8]; } Boss07; // size = 0xAC20 extern const ActorInit Boss_07_InitVars; diff --git a/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.h b/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.h index 5e29a3815..3b5882692 100644 --- a/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.h +++ b/src/overlays/actors/ovl_Boss_Hakugin/z_boss_hakugin.h @@ -13,16 +13,16 @@ typedef struct BossHakuginParticle { /* 0x18 */ s16 unk_18; /* 0x1A */ s16 unk_1A; /* 0x1C */ Vec3s unk_1C; - /* 0x22 */ f32 unk_24; + /* 0x24 */ f32 unk_24; } BossHakuginParticle; // size = 0x28 typedef struct BossHakugin { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ char unk_0144[0x44]; /* 0x0188 */ BossHakuginActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x86C]; + /* 0x018C */ char unk_018C[0x86C]; /* 0x09F8 */ BossHakuginParticle unk_9F8[180]; - /* 0x0A14 */ char unk_A04[0x2DFC]; + /* 0x2618 */ char unk_2618[0x11F8]; } BossHakugin; // size = 0x3810 extern const ActorInit Boss_Hakugin_InitVars; diff --git a/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c b/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c index 17435de3d..94bbef096 100644 --- a/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c +++ b/src/overlays/actors/ovl_Demo_Effect/z_demo_effect.c @@ -1,7 +1,7 @@ /* * File: z_demo_effect.c * Overlay: ovl_Demo_Effect - * Description: Obtaining Masks (?) + * Description: Various cutscene effects (blue warp in, Great Fairy vanish, etc.) */ #include "z_demo_effect.h" diff --git a/src/overlays/actors/ovl_Demo_Getitem/z_demo_getitem.c b/src/overlays/actors/ovl_Demo_Getitem/z_demo_getitem.c index 1d39dc022..71f0d9204 100644 --- a/src/overlays/actors/ovl_Demo_Getitem/z_demo_getitem.c +++ b/src/overlays/actors/ovl_Demo_Getitem/z_demo_getitem.c @@ -1,7 +1,7 @@ /* * File: z_demo_getitem.c * Overlay: ovl_Demo_Getitem - * Description: + * Description: Cutscene object for Great Fairy's Mask and Great Fairy's Sword */ #include "z_demo_getitem.h" diff --git a/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c b/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c index 6ff4f9096..9cc359c9e 100644 --- a/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c +++ b/src/overlays/actors/ovl_Demo_Kankyo/z_demo_kankyo.c @@ -588,7 +588,7 @@ void DemoKakyo_DrawLostWoodsSparkle(Actor* thisx, GlobalContext* globalCtx2) { break; } - Matrix_InsertMatrix(&globalCtx->mf_187FC, MTXMODE_APPLY); + Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_APPLY); Matrix_InsertZRotation_f(DEGF_TO_RADF(globalCtx->state.frames * 20.0f), MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), @@ -659,7 +659,7 @@ void DemoKankyo_DrawMoonAndGiant(Actor* thisx, GlobalContext* globalCtx2) { gSPDisplayList(POLY_XLU_DISP++, &D_04023348); - Matrix_InsertMatrix(&globalCtx->mf_187FC, MTXMODE_APPLY); + Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_APPLY); Matrix_InsertZRotation_f(DEGF_TO_RADF(globalCtx->state.frames * 20.0f), MTXMODE_APPLY); diff --git a/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.c b/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.c index 2fb5a86da..a22d0f8c6 100644 --- a/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.c +++ b/src/overlays/actors/ovl_Demo_Syoten/z_demo_syoten.c @@ -1,7 +1,7 @@ /* * File: z_demo_syoten.c * Overlay: ovl_Demo_Syoten - * Description: + * Description: Ikana Canyon Cleansing Cutscene Effects */ #include "z_demo_syoten.h" diff --git a/src/overlays/actors/ovl_Dm_Char00/z_dm_char00.c b/src/overlays/actors/ovl_Dm_Char00/z_dm_char00.c index db345ab3a..596945272 100644 --- a/src/overlays/actors/ovl_Dm_Char00/z_dm_char00.c +++ b/src/overlays/actors/ovl_Dm_Char00/z_dm_char00.c @@ -1,7 +1,7 @@ /* * File: z_dm_char00.c * Overlay: ovl_Dm_Char00 - * Description: Tatl (cutscene) + * Description: Tatl and Tael (cutscene) */ #include "z_dm_char00.h" diff --git a/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.c b/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.c index b98ad4329..cf2d8b03b 100644 --- a/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.c +++ b/src/overlays/actors/ovl_Dm_Char01/z_dm_char01.c @@ -1,7 +1,7 @@ /* * File: z_dm_char01.c * Overlay: ovl_Dm_Char01 - * Description: Tatl and Tael (cutscene) + * Description: Woodfall scene objects (temple, water, walls, etc) */ #include "z_dm_char01.h" diff --git a/src/overlays/actors/ovl_Dm_Char02/z_dm_char02.c b/src/overlays/actors/ovl_Dm_Char02/z_dm_char02.c index 46ed5e619..116b2732d 100644 --- a/src/overlays/actors/ovl_Dm_Char02/z_dm_char02.c +++ b/src/overlays/actors/ovl_Dm_Char02/z_dm_char02.c @@ -1,7 +1,7 @@ /* * File: z_dm_char02.c * Overlay: ovl_Dm_Char02 - * Description: + * Description: Ocarina of Time (dropped from Skull Kid's hand) */ #include "z_dm_char02.h" diff --git a/src/overlays/actors/ovl_Dm_Char04/z_dm_char04.c b/src/overlays/actors/ovl_Dm_Char04/z_dm_char04.c index 6a09de8b5..e2c72238e 100644 --- a/src/overlays/actors/ovl_Dm_Char04/z_dm_char04.c +++ b/src/overlays/actors/ovl_Dm_Char04/z_dm_char04.c @@ -1,7 +1,7 @@ /* * File: z_dm_char04.c * Overlay: ovl_Dm_Char04 - * Description: + * Description: Unused(?) Tatl and Tael actors */ #include "z_dm_char04.h" diff --git a/src/overlays/actors/ovl_Dm_Char06/z_dm_char06.c b/src/overlays/actors/ovl_Dm_Char06/z_dm_char06.c index 6dd180e21..1518cd4b4 100644 --- a/src/overlays/actors/ovl_Dm_Char06/z_dm_char06.c +++ b/src/overlays/actors/ovl_Dm_Char06/z_dm_char06.c @@ -1,7 +1,7 @@ /* * File: z_dm_char06.c * Overlay: ovl_Dm_Char06 - * Description: Some unseen Mountain Village cutscene actor? + * Description: Mountain Village Snowy landscape fadeout in post-Snowhead thawing cutscene */ #include "z_dm_char06.h" diff --git a/src/overlays/actors/ovl_Dm_Hina/z_dm_hina.h b/src/overlays/actors/ovl_Dm_Hina/z_dm_hina.h index 958608c65..00385a1d1 100644 --- a/src/overlays/actors/ovl_Dm_Hina/z_dm_hina.h +++ b/src/overlays/actors/ovl_Dm_Hina/z_dm_hina.h @@ -10,7 +10,10 @@ typedef void (*DmHinaActionFunc)(struct DmHina*, GlobalContext*); typedef struct DmHina { /* 0x0000 */ Actor actor; /* 0x0144 */ DmHinaActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x3C]; + /* 0x0148 */ char unk_148[0x10]; + /* 0x0158 */ f32 unk_158; + /* 0x015C */ f32 unk_15C; + /* 0x0160 */ char unk_160[0x24]; } DmHina; // size = 0x184 extern const ActorInit Dm_Hina_InitVars; diff --git a/src/overlays/actors/ovl_Dm_Sa/z_dm_sa.c b/src/overlays/actors/ovl_Dm_Sa/z_dm_sa.c index 9460d405a..ccda78a8e 100644 --- a/src/overlays/actors/ovl_Dm_Sa/z_dm_sa.c +++ b/src/overlays/actors/ovl_Dm_Sa/z_dm_sa.c @@ -1,7 +1,7 @@ /* * File: z_dm_sa.c * Overlay: ovl_Dm_Sa - * Description: + * Description: Glitched early version of Skull Kid stuck in a T-pose */ #include "z_dm_sa.h" diff --git a/src/overlays/actors/ovl_Dm_Statue/z_dm_statue.c b/src/overlays/actors/ovl_Dm_Statue/z_dm_statue.c index b3b3b3e28..8234deec6 100644 --- a/src/overlays/actors/ovl_Dm_Statue/z_dm_statue.c +++ b/src/overlays/actors/ovl_Dm_Statue/z_dm_statue.c @@ -1,7 +1,7 @@ /* * File: z_dm_statue.c * Overlay: ovl_Dm_Statue - * Description: Elegy of Emptiness - Beam of Light When Creating Statue + * Description: Pillars of water in Giant's Chamber */ #include "z_dm_statue.h" diff --git a/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.c b/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.c index 154b1dba0..bf934be08 100644 --- a/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.c +++ b/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.c @@ -30,7 +30,96 @@ void func_80AA1C64(DmStk* this, GlobalContext* globalCtx); void func_80AA2720(DmStk* this, GlobalContext* globalCtx); void func_80AA27EC(DmStk* this, GlobalContext* globalCtx); -#if 0 +extern AnimationHeader D_0600055C; +extern AnimationHeader D_06001030; +extern AnimationHeader D_0600130C; +extern AnimationHeader D_06001374; +extern AnimationHeader D_06001EDC; +extern AnimationHeader D_06002774; +extern AnimationHeader D_06002CD8; +extern AnimationHeader D_06003068; +extern AnimationHeader D_060035C8; +extern AnimationHeader D_060039F0; +extern AnimationHeader D_06004554; +extern AnimationHeader D_06004580; +extern Gfx D_060046B0[]; +extern AnimationHeader D_060049C8; +extern AnimationHeader D_060051C0; +extern Gfx D_060053C0[]; +extern Gfx D_06005870[]; +extern AnimationHeader D_06005F44; +extern Gfx D_06006BB0[]; +extern AnimationHeader D_060070DC; +extern Gfx D_06007840[]; +extern Gfx D_060079F0[]; +extern Gfx D_060084C0[]; +extern UNK_TYPE D_06008658; +extern Gfx D_060087B0[]; +extern Gfx D_06008A80[]; +extern Gfx D_060090C0[]; +extern Gfx D_06009710[]; +extern Gfx D_06009AC0[]; +extern Gfx D_06009DA0[]; +extern Gfx D_0600A530[]; +extern Gfx D_0600A5C0[]; +extern Gfx D_0600AE30[]; +extern Gfx D_0600AEC0[]; +extern AnimationHeader D_0600BB2C; +extern AnimationHeader D_0600C270; +extern AnimationHeader D_0600C964; +extern Gfx D_0600CAD0[]; +extern AnimationHeader D_0600CBB8; +extern AnimationHeader D_0600D830; +extern AnimationHeader D_0600E6EC; +extern AnimationHeader D_0600EEC0; +extern AnimationHeader D_060101A4; +extern AnimationHeader D_06010B60; +extern AnimationHeader D_060110B4; +extern AnimationHeader D_06011FB0; +extern AnimationHeader D_06012A58; +extern FlexSkeletonHeader D_06013328; +extern AnimationHeader D_060141E4; +extern AnimationHeader D_06014920; +extern AnimationHeader D_06015028; +extern AnimationHeader D_06015C14; +extern AnimationHeader D_06016508; +extern Gfx D_06016620[]; +extern AnimationHeader D_06016910; +extern AnimationHeader D_06018ED0; +extern AnimationHeader D_0601AA80; +extern AnimationHeader D_0601C114; +extern AnimationHeader D_0601C21C; +extern AnimationHeader D_0601D008; +extern AnimationHeader D_0601D07C; +extern AnimationHeader D_0601D3D0; +extern AnimationHeader D_0601DDE0; +extern AnimationHeader D_0601EF50; +extern AnimationHeader D_0601F9E4; +extern AnimationHeader D_06020CAC; +extern AnimationHeader D_0602200C; +extern AnimationHeader D_0602336C; +extern AnimationHeader D_060259F4; +extern AnimationHeader D_060266C8; +extern AnimationHeader D_06026CF4; +extern AnimationHeader D_06027CF4; +extern AnimationHeader D_06028F28; +extern AnimationHeader D_06029A04; +extern AnimationHeader D_0602A2D8; +extern AnimationHeader D_0602AD54; +extern AnimationHeader D_0602DC64; +extern AnimationHeader D_0602E9A0; +extern AnimationHeader D_0602FA70; +extern AnimationHeader D_0603021C; +extern AnimationHeader D_06031210; +extern AnimationHeader D_060322FC; +extern AnimationHeader D_06032AE0; +extern AnimationHeader D_0603323C; +extern AnimationHeader D_06034FD8; +extern AnimationHeader D_06036964; +extern AnimationHeader D_06037B94; +extern AnimationHeader D_0603967C; +extern AnimationHeader D_0603A8F8; + const ActorInit Dm_Stk_InitVars = { ACTOR_DM_STK, ACTORCAT_ITEMACTION, @@ -43,18 +132,29 @@ const ActorInit Dm_Stk_InitVars = { (ActorFunc)DmStk_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80AA35A0 = { - { COLTYPE_HIT1, AT_NONE, AC_ON | AC_HARD | AC_TYPE_PLAYER | AC_TYPE_ENEMY, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK1, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_HIT1, + AT_NONE, + AC_ON | AC_HARD | AC_TYPE_PLAYER | AC_TYPE_ENEMY, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK1, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 14, 38, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80AA35CC = { 1, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 1, 0, 0, 0, MASS_IMMOVABLE }; -// static DamageTable sDamageTable = { -static DamageTable D_80AA35D8 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(1, 0xF), /* Deku Stick */ DMG_ENTRY(1, 0xF), /* Horse trample */ DMG_ENTRY(1, 0xF), @@ -89,98 +189,1677 @@ static DamageTable D_80AA35D8 = { /* Powder Keg */ DMG_ENTRY(1, 0xF), }; -#endif +static ActorAnimationEntry sAnimations[] = { + { &D_0601C21C, 1.0f, 0.0f, -1.0f, 0, 0.0f }, { &D_0601D3D0, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_06001030, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_0601D008, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_0601D008, 1.0f, 0.0f, -1.0f, 0, 0.0f }, { &D_06015C14, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_060070DC, 1.0f, 0.0f, -1.0f, 0, 0.0f }, { &D_0600D830, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_0600055C, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_0600130C, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_0600C270, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_0600CBB8, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_0601AA80, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_0601D07C, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_06016910, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_06018ED0, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_0601DDE0, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_0601EF50, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_0602DC64, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_0602E9A0, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_0602DC64, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_0602E9A0, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_060035C8, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_060049C8, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_060259F4, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_060266C8, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_06026CF4, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_0601C114, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &D_06004580, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_06020CAC, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_0602200C, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_0602336C, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_06002774, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_06003068, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_060101A4, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_06010B60, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_0602A2D8, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_0601F9E4, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &D_06029A04, 1.0f, 0.0f, -1.0f, 0, 0.0f }, { &D_0602AD54, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &D_0600BB2C, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_0600C964, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_060110B4, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_06011FB0, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_06012A58, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_060141E4, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_0600E6EC, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_0600EEC0, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_06027CF4, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_06028F28, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_0603323C, 1.0f, 0.0f, -1.0f, 0, 0.0f }, { &D_06031210, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_060322FC, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_06032AE0, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_0603021C, 1.0f, 0.0f, -1.0f, 0, 0.0f }, { &D_06036964, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &D_06016508, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_06015028, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_06014920, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_0602FA70, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_06037B94, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_0603967C, 1.0f, 0.0f, -1.0f, 2, 0.0f }, + { &D_0603967C, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_0603A8F8, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_06034FD8, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_06005F44, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_06002CD8, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_060039F0, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_06004554, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_060051C0, 1.0f, 0.0f, -1.0f, 0, 0.0f }, + { &D_06001374, 1.0f, 0.0f, -1.0f, 2, 0.0f }, { &D_06001EDC, 1.0f, 0.0f, -1.0f, 0, 0.0f }, +}; -extern ColliderCylinderInit D_80AA35A0; -extern CollisionCheckInfoInit2 D_80AA35CC; -extern DamageTable D_80AA35D8; +void func_80A9FDB0(DmStk* this, GlobalContext* globalCtx) { + s32 objectIdx; -extern UNK_TYPE D_06006BB0; -extern UNK_TYPE D_0600AEC0; -extern UNK_TYPE D_06013328; + if (((this->unk_2E0 >= 0) && (this->unk_2E0 <= 5)) || (this->unk_2E0 == 32) || (this->unk_2E0 == 33) || + (this->unk_2E0 == 40) || (this->unk_2E0 == 41)) { + objectIdx = this->unk_336; + } else if (this->unk_2E0 > 64) { + objectIdx = this->unk_338; + } else { + objectIdx = this->unk_337; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80A9FDB0.s") + if (objectIdx >= 0) { + gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[objectIdx].segment); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80A9FE3C.s") +void func_80A9FE3C(DmStk* this, GlobalContext* globalCtx, SkelAnime* skelAnime, ActorAnimationEntry* animation, + u16 index) { + func_80A9FDB0(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80A9FED8.s") + animation += index; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA00CC.s") + Animation_Change(skelAnime, animation->animation, animation->playSpeed, animation->startFrame, + (animation->frameCount < 0.0f) ? Animation_GetLastFrame(&animation->animation->common) + : animation->frameCount, + animation->mode, animation->morphFrames); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA0100.s") +void func_80A9FED8(DmStk* this, GlobalContext* globalCtx) { + switch (globalCtx->csCtx.frames + 20) { + case 1195: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_APPEAR); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA0158.s") + case 1232: + case 1241: + case 1252: + case 1255: + case 1257: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_SHAKEHEAD); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA01C0.s") + case 1285: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STAL03_LAUGH_BIG); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA0264.s") + case 1343: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_MASK_OFF); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA0420.s") + case 1410: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_MASK_ON); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA05F0.s") + case 1603: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_WALK); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA0634.s") + case 1610: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_REVERSE); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA066C.s") + case 2095: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_SURPRISED); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA071C.s") + case 2190: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_JUMP); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA076C.s") + case 2212: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_ONGND); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA09DC.s") + case 2214: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STAL02_LAUGH_SHORT); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA0B08.s") + case 2250: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STAL06_SURPRISED); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_DOWN_K); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA0DA8.s") + case 2255: + case 2266: + case 2277: + case 2288: + case 2299: + case 2310: + case 2321: + case 2332: + case 2343: + case 2354: + case 2365: + case 2376: + case 2387: + case 2398: + case 2409: + case 2420: + case 2431: + case 2442: + case 2453: + case 2464: + case 2475: + case 2486: + case 2497: + case 2508: + case 2519: + case 2530: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_RIDE); + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA0E1C.s") +void func_80AA00CC(DmStk* this, GlobalContext* globalCtx) { + if (globalCtx->csCtx.frames == 535) { + func_8019F128(NA_SE_EV_CLOCK_TOWER_BELL); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA0E90.s") +void func_80AA0100(DmStk* this, GlobalContext* globalCtx) { + switch (globalCtx->csCtx.frames) { + case 78: + case 89: + case 100: + case 111: + case 122: + case 133: + case 144: + case 155: + case 166: + case 177: + case 188: + case 199: + case 210: + case 221: + case 232: + case 243: + case 254: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_RIDE); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/DmStk_Init.s") + case 173: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STAL03_LAUGH_BIG); + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/DmStk_Destroy.s") +void func_80AA0158(DmStk* this, GlobalContext* globalCtx) { + switch (globalCtx->csCtx.frames) { + case 18: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_GASAGOSO); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA16F4.s") + case 90: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_MASK_ON); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA1704.s") + case 142: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_EVIL_POWER); + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA1714.s") +void func_80AA01C0(DmStk* this, GlobalContext* globalCtx) { + switch (globalCtx->csCtx.frames) { + case 415: + func_801A479C(&this->actor.projectedPos, NA_SE_EN_STALKIDS_FLOAT, 100); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA17F8.s") + case 785: + func_8019F128(NA_SE_SY_STALKIDS_PSYCHO); + func_8019FE74(&D_801D6654, 0.0f, 150); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA18D8.s") + case 560: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STAL02_LAUGH_SHORT); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA192C.s") + case 890: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STAL21_PSYCHO_VOICE); + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA1998.s") +void func_80AA0264(DmStk* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA19EC.s") + switch (globalCtx->csCtx.frames) { + case 10: + func_801A479C(&this->actor.projectedPos, NA_SE_EN_STALKIDS_FLOAT, 50); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA1A50.s") + case 71: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_BODY); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA1AC8.s") + case 365: + func_801A0654(&this->actor.projectedPos, NA_SE_EN_STALKIDS_FLOAT, 0); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA1AF8.s") + case 650: + func_8019FE74(&D_801D6654, 0.0f, 80); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA1B9C.s") + case 265: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STAL03_LAUGH_BIG); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA1C64.s") + case 126: + Audio_PlayActorSound2(&player->actor, NA_SE_VO_DUMMY_150); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA1D1C.s") + case 197: + Audio_PlayActorSound2(&player->actor, NA_SE_VO_DUMMY_134); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA26CC.s") + case 207: + Audio_PlayActorSound2(&player->actor, NA_SE_VO_DUMMY_135); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA2720.s") + case 217: + Audio_PlayActorSound2(&player->actor, NA_SE_VO_DUMMY_136); + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA27EC.s") + if (player) {} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/DmStk_Update.s") + if ((globalCtx->csCtx.frames >= 263) && (globalCtx->csCtx.frames < 698)) { + Audio_PlayActorSound2(&player->actor, NA_SE_EN_STALKIDS_BODY_LEV - SFX_FLAG); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA2B14.s") +void func_80AA0420(DmStk* this, GlobalContext* globalCtx) { + static s32 D_80AA3CB8 = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA2BC0.s") + switch (globalCtx->csCtx.frames) { + case 140: + func_801A479C(&this->actor.projectedPos, NA_SE_EN_STALKIDS_FLOAT, 80); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/func_80AA33A4.s") + case 258: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_TURN); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Dm_Stk/DmStk_Draw.s") + case 524: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_TURN); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STAL04_ANGER); + break; + + case 534: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_ROLL); + break; + + case 678: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_STRETCH); + break; + } + + if ((this->unk_2E0 == 31) && (globalCtx->csCtx.frames < 700)) { + if (Animation_OnFrame(&this->skelAnime, 5.0f) || Animation_OnFrame(&this->skelAnime, 25.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_OTEDAMA1); + } else if (Animation_OnFrame(&this->skelAnime, 17.0f) || Animation_OnFrame(&this->skelAnime, 40.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_OTEDAMA2); + } + } + + if (globalCtx->csCtx.frames >= 700) { + if (D_80AA3CB8 < 128) { + if ((D_80AA3CB8 & 0x1F) == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STAL20_CALL_MOON); + } else if ((D_80AA3CB8 & 0x1F) == 16) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STAL20_CALL_MOON2); + } + D_80AA3CB8++; + } + } else { + D_80AA3CB8 = 0; + } +} + +void func_80AA05F0(DmStk* this, GlobalContext* globalCtx) { + if (globalCtx->csCtx.frames == 3) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STAL06_SURPRISED); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_DOWN_K); + } +} + +void func_80AA0634(DmStk* this, GlobalContext* globalCtx) { + if ((globalCtx->csCtx.frames >= 642) && (globalCtx->csCtx.frames < 845)) { + Audio_PlayActorSound2(&this->actor, NA_SE_NE_STAL23_COLD - SFX_FLAG); + } +} + +void func_80AA066C(DmStk* this, GlobalContext* globalCtx) { + switch (globalCtx->csCtx.frames) { + case 58: + case 61: + case 68: + case 72: + case 77: + case 79: + Audio_PlayActorSound2(&this->actor, NA_SE_PL_WALK_WATER2); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_WALK); + break; + + case 186: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_UP); + break; + + case 230: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STAL22_LAUGH_KID_L); + break; + } +} + +void func_80AA071C(DmStk* this, GlobalContext* globalCtx) { + switch (globalCtx->csCtx.frames) { + case 5: + func_801A4A28(12); + break; + + case 660: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_SHAKEHEAD); + break; + } +} + +void func_80AA076C(DmStk* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + switch (globalCtx->csCtx.frames) { + case 5: + func_801A4A28(12); + break; + + case 45: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_RIDE); + break; + + case 93: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_MASK_OFF); + break; + + case 245: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_RIDE); + break; + + case 269: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STAL11_LAUGH_SHY2); + break; + + case 327: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_SHAKEHEAD); + break; + + case 455: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_RIDE); + break; + + case 1730: + Audio_QueueSeqCmd(0x141400FF); + break; + + case 1395: + func_800B8E58(&player->actor, NA_SE_VO_DUMMY_34); + break; + + case 1850: + Audio_QueueSeqCmd(0x42320000); + break; + + case 2000: + func_801A5BD0(0x7F); + break; + } + + if (this->unk_2E0 == 0) { + if (Animation_OnFrame(&this->skelAnime, 8.0f) || Animation_OnFrame(&this->skelAnime, 17.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_MASK_OFF); + } + + if (Animation_OnFrame(&this->skelAnime, 28.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_RIDE); + } + } else if (this->unk_2E0 == 71) { + if (Animation_OnFrame(&this->skelAnime, 2.0f) || Animation_OnFrame(&this->skelAnime, 6.0f) || + Animation_OnFrame(&this->skelAnime, 12.0f) || Animation_OnFrame(&this->skelAnime, 18.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_MASK_OFF); + } + } else if ((this->unk_2E0 == 70) && + (Animation_OnFrame(&this->skelAnime, 16.0f) || Animation_OnFrame(&this->skelAnime, 23.0f))) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_NOSE); + } +} + +void func_80AA09DC(DmStk* this, GlobalContext* globalCtx) { + static s32 D_80AA3CBC = 0; + + switch (globalCtx->csCtx.frames) { + case 40: + func_801A479C(&this->actor.projectedPos, NA_SE_EN_STALKIDS_FLOAT, 80); + break; + + case 234: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_TURN); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STAL04_ANGER); + break; + + case 244: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PO_ROLL); + break; + + case 388: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_STRETCH); + break; + } + + if (globalCtx->csCtx.frames >= 408) { + if (D_80AA3CBC < 128) { + if ((D_80AA3CBC & 0x1F) == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STAL20_CALL_MOON); + } else if ((D_80AA3CBC & 0x1F) == 16) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STAL20_CALL_MOON2); + } + D_80AA3CBC++; + } + } else { + D_80AA3CBC = 0; + } +} + +void func_80AA0B08(DmStk* this, GlobalContext* globalCtx) { + this->unk_310.x = this->actor.projectedPos.x; + this->unk_310.y = this->actor.projectedPos.y; + this->unk_310.z = this->actor.projectedPos.z; + + switch (globalCtx->csCtx.frames) { + case 64: + func_8019F1C0(&this->unk_310, NA_SE_EN_STAL06_SURPRISED); + break; + + case 327: + case 332: + case 335: + case 344: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_MASK_OFF); + break; + + case 367: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_BODY_LEV); + break; + + case 470: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_HEADACHE); + break; + + case 486: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_MASK_OFF); + func_8019F1C0(&this->unk_310, NA_SE_EN_STAL08_CRY_BIG); + break; + + case 496: + func_8019F1C0(&this->unk_310, NA_SE_EN_STAL09_SCREAM); + break; + + case 590: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_MASK_OFF); + break; + + case 592: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_RIDE); + break; + + case 594: + func_8019F1C0(&this->unk_310, NA_SE_EN_STAL24_SCREAM2); + break; + } + + if (1) {} + + if ((globalCtx->csCtx.frames >= 62) && (globalCtx->csCtx.frames < 273)) { + if ((Rand_ZeroOne() < 0.75f) && ((globalCtx->state.frames % 2) != 0)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_EARTHQUAKE); + } + } + + if ((globalCtx->csCtx.frames >= 498) && (globalCtx->csCtx.frames < 577)) { + if ((globalCtx->state.frames % 4) == 0) { + if ((globalCtx->state.frames & 4) != 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_BODY_LEV); + } else { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_MASK_OFF); + } + } + } + + if (globalCtx->csCtx.frames >= 290) { + func_8019F128(NA_SE_EV_KYOJIN_VOICE_SUCCESS - SFX_FLAG); + } +} + +void func_80AA0DA8(DmStk* this, GlobalContext* globalCtx) { + switch (globalCtx->csCtx.frames) { + case 551: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_PULLED); + break; + + case 711: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_MASK_OFF); + break; + + case 716: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_MASK_ON); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_ONGND); + break; + } +} + +void func_80AA0E1C(DmStk* this, GlobalContext* globalCtx) { + switch (globalCtx->csCtx.frames) { + case 311: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_PULLED); + break; + + case 365: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_MASK_OFF); + break; + + case 372: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_MASK_ON); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_ONGND); + break; + } +} + +void func_80AA0E90(DmStk* this, GlobalContext* globalCtx) { + if (globalCtx->csCtx.state != 0) { + switch (globalCtx->sceneNum) { + case SCENE_LOST_WOODS: + if (gSaveContext.sceneSetupIndex == 1) { + func_80A9FED8(this, globalCtx); + } else if (gSaveContext.sceneSetupIndex == 0) { + func_80AA0100(this, globalCtx); + } else if ((gSaveContext.sceneSetupIndex == 2) && (globalCtx->csCtx.unk_12 == 0)) { + func_80AA0158(this, globalCtx); + } + break; + + case SCENE_CLOCKTOWER: + if (gSaveContext.sceneSetupIndex == 1) { + func_80AA00CC(this, globalCtx); + } + break; + + case SCENE_OPENINGDAN: + if (gSaveContext.sceneSetupIndex == 0) { + if (globalCtx->csCtx.unk_12 == 0) { + func_80AA01C0(this, globalCtx); + } else if (globalCtx->csCtx.unk_12 == 1) { + func_80AA0264(this, globalCtx); + } + } + break; + + case SCENE_OKUJOU: + if (gSaveContext.sceneSetupIndex == 0) { + if (globalCtx->csCtx.unk_12 == 0) { + func_80AA0420(this, globalCtx); + } else if (globalCtx->csCtx.unk_12 == 1) { + func_80AA05F0(this, globalCtx); + } else if (globalCtx->csCtx.unk_12 == 2) { + func_80AA09DC(this, globalCtx); + } else if (globalCtx->csCtx.unk_12 == 3) { + func_80AA0B08(this, globalCtx); + } + } else if (gSaveContext.sceneSetupIndex == 2) { + if (globalCtx->csCtx.unk_12 == 0) { + func_80AA0DA8(this, globalCtx); + } else if (globalCtx->csCtx.unk_12 == 1) { + func_80AA0E1C(this, globalCtx); + } + } + break; + + case SCENE_00KEIKOKU: + if (gSaveContext.sceneSetupIndex == 3) { + if (globalCtx->csCtx.unk_12 == 0) { + func_80AA0634(this, globalCtx); + } else if (globalCtx->csCtx.unk_12 == 2) { + func_80AA066C(this, globalCtx); + } + } else if (gSaveContext.sceneSetupIndex == 7) { + if (globalCtx->csCtx.unk_12 == 0) { + func_80AA071C(this, globalCtx); + } else if (globalCtx->csCtx.unk_12 == 1) { + func_80AA076C(this, globalCtx); + } + } + break; + } + } + + if (this->unk_2E0 == 1) { + if (Animation_OnFrame(&this->skelAnime, 2.0f) || Animation_OnFrame(&this->skelAnime, 6.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_WALK); + } + } else if (this->unk_2E0 == 19) { + if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 13.0f) || + Animation_OnFrame(&this->skelAnime, 20.0f) || Animation_OnFrame(&this->skelAnime, 27.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_PL_CALM_HIT); + } + } else if (this->unk_2E0 == 14) { + if (Animation_OnFrame(&this->skelAnime, 3.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_PL_PUT_OUT_ITEM); + } + } else if (this->unk_2E0 == 15) { + if (Animation_OnFrame(&this->skelAnime, 14.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_UNSKILLFUL_OCARINA); + } + + if (Animation_OnFrame(&this->skelAnime, 45.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STAL01_LAUGH); + } + } +} + +void DmStk_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + DmStk* this = THIS; + + this->unk_33B = 1; + if (this->actor.params != 1) { + this->unk_33A = 0; + this->unk_336 = Object_GetIndex(&globalCtx->objectCtx, OBJECT_STK); + this->unk_337 = Object_GetIndex(&globalCtx->objectCtx, OBJECT_STK2); + this->unk_338 = Object_GetIndex(&globalCtx->objectCtx, OBJECT_STK3); + if (this->unk_336 < 0) { + Actor_MarkForDeath(&this->actor); + } + + this->unk_328 = 0; + this->unk_339 = 0; + this->unk_32C = 1; + this->unk_2E0 = 3; + this->unk_2E8 = globalCtx->lightCtx.unk7; + this->unk_2EC = globalCtx->lightCtx.unk8; + this->unk_2F0 = globalCtx->lightCtx.unk9; + + if ((globalCtx->sceneNum == SCENE_LOST_WOODS) && (gSaveContext.sceneSetupIndex == 1)) { + this->unk_2E4 = 0; + this->unk_2F8 = 0; + this->unk_2FC = 1000; + this->unk_300 = 1.0f; + this->actionFunc = func_80AA1704; + } else if (globalCtx->sceneNum == SCENE_OKUJOU) { + this->unk_2E4 = 255; + this->unk_2F8 = 996; + this->unk_2FC = 1000; + this->unk_300 = 0.7f; + this->unk_335 = 0; + + Collider_InitCylinder(globalCtx, &this->collider); + + if (gSaveContext.entranceIndex == 0x2C00) { + if (gSaveContext.sceneSetupIndex == 0) { + if (gSaveContext.unk_3DD0[3] == 0) { + func_8010E9F0(3, 300); + XREG(80) = 200; + XREG(81) = 115; + } + + if (gSaveContext.inventory.items[SLOT_OCARINA] == ITEM_NONE) { + sCylinderInit.base.colType = COLTYPE_WOOD; + this->actionFunc = func_80AA18D8; + } else { + sCylinderInit.base.colType = COLTYPE_WOOD; + this->actionFunc = func_80AA1998; + } + + } else if (gSaveContext.sceneSetupIndex == 3) { + this->unk_2E0 = 38; + if (gSaveContext.unk_3DD0[3] == 0) { + func_8010E9F0(3, 60); + XREG(80) = 200; + XREG(81) = 115; + } + this->actor.world.pos.y = 120.0f; + sCylinderInit.base.colType = COLTYPE_WOOD; + this->actionFunc = func_80AA27EC; + } else { + this->unk_2E0 = 38; + this->actionFunc = func_80AA16F4; + } + } else { + this->unk_33A = 1; + this->unk_2E0 = 38; + this->actor.world.pos.y = 120.0f; + sCylinderInit.base.colType = COLTYPE_WOOD; + this->actionFunc = func_80AA27EC; + } + + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + + } else if ((globalCtx->sceneNum == SCENE_00KEIKOKU) && (gSaveContext.sceneSetupIndex == 0)) { + if (!(globalCtx->actorCtx.unk5 & 2)) { + Actor_MarkForDeath(&this->actor); + } + this->unk_32C = 2; + this->unk_2E4 = 255; + this->unk_2F8 = 996; + this->unk_2FC = 1000; + this->unk_300 = 0.7f; + this->unk_2E0 = 5; + this->actionFunc = func_80AA1714; + } else { + if ((globalCtx->sceneNum == SCENE_LOST_WOODS) && !func_800EE2F4(globalCtx)) { + Actor_MarkForDeath(&this->actor); + } + this->unk_32C = 2; + this->unk_2E4 = 255; + this->unk_2F8 = 996; + this->unk_2FC = 1000; + this->unk_300 = 0.7f; + this->actionFunc = func_80AA1704; + } + + this->unk_32D = 9; + this->unk_32E = 0; + this->unk_32F = 0; + this->unk_330 = 0; + this->unk_2E4 = this->unk_2E4; + this->actor.targetArrowOffset = 1100.0f; + this->unk_334 = 99; + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 24.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06013328, NULL, NULL, NULL, 0); + func_80A9FE3C(this, globalCtx, &this->skelAnime, &sAnimations[this->unk_2E0], 0); + } + + Actor_SetScale(&this->actor, 0.01f); + + if ((globalCtx->sceneNum == SCENE_00KEIKOKU) && (gSaveContext.sceneSetupIndex == 3) && + (globalCtx->csCtx.unk_12 > 0)) { + globalCtx->envCtx.unk_17 = 15; + globalCtx->envCtx.unk_18 = 15; + } +} + +void DmStk_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +void func_80AA16F4(DmStk* this, GlobalContext* globalCtx) { +} + +void func_80AA1704(DmStk* this, GlobalContext* globalCtx) { +} + +void func_80AA1714(DmStk* this, GlobalContext* globalCtx) { + Vec3f sp1C; + + if (!(gSaveContext.weekEventReg[74] & 0x20)) { + func_80169474(globalCtx, &this->actor.world.pos, &sp1C); + if (globalCtx->view.fovy < 25.0f) { + if ((sp1C.x >= 70.0f) && (sp1C.x < 250.0f) && (sp1C.y >= 30.0f) && (sp1C.y < 210.0f)) { + func_800FE484(); + this->actionFunc = func_80AA17F8; + } + } + } +} + +void func_80AA17F8(DmStk* this, GlobalContext* globalCtx) { + s16 sp1E = this->actor.cutscene; + s16 sp1C = ActorCutscene_GetAdditionalCutscene(sp1E); + s16 sp18 = ActorCutscene_GetAdditionalCutscene(sp1C); + s16 cutscene; + + if (gSaveContext.day < 3) { + cutscene = sp1E; + } else if ((gSaveContext.weekEventReg[8] & 0x40) || + ((CURRENT_DAY == 3) && (gSaveContext.time < CLOCK_TIME(6, 0)))) { + cutscene = sp18; + } else { + cutscene = sp1C; + } + + if (ActorCutscene_GetCanPlayNext(cutscene)) { + ActorCutscene_Start(cutscene, &this->actor); + func_800FE498(); + this->actionFunc = func_80AA1704; + } else { + ActorCutscene_SetIntentToPlay(cutscene); + } +} + +void func_80AA18D8(DmStk* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(9)) { + ActorCutscene_Start(9, &this->actor); + this->actionFunc = func_80AA192C; + } else { + ActorCutscene_SetIntentToPlay(9); + } +} + +void func_80AA192C(DmStk* this, GlobalContext* globalCtx) { + if (globalCtx->csCtx.state == 0) { + this->unk_2E0 = 33; + this->unk_32D = 3; + func_80A9FE3C(this, globalCtx, &this->skelAnime, &sAnimations[this->unk_2E0], 0); + this->actionFunc = func_80AA2720; + } +} + +void func_80AA1998(DmStk* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(0xB)) { + ActorCutscene_Start(0xB, &this->actor); + this->actionFunc = func_80AA19EC; + } else { + ActorCutscene_SetIntentToPlay(0xB); + } +} + +void func_80AA19EC(DmStk* this, GlobalContext* globalCtx) { + if (globalCtx->csCtx.state == 0) { + this->unk_2E0 = 38; + func_80A9FE3C(this, globalCtx, &this->skelAnime, &sAnimations[this->unk_2E0], 0); + this->actionFunc = func_80AA27EC; + } +} + +void func_80AA1A50(DmStk* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(0xA)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_DAMAGE); + ActorCutscene_Start(0xA, &this->actor); + this->actor.shape.rot.x = 0; + this->actor.world.rot.x = this->actor.shape.rot.x; + this->actor.shape.rot.y = this->actor.shape.rot.x; + this->actor.world.rot.y = this->actor.shape.rot.x; + this->actionFunc = func_80AA1AC8; + } else { + ActorCutscene_SetIntentToPlay(0xA); + } +} + +void func_80AA1AC8(DmStk* this, GlobalContext* globalCtx) { + if ((globalCtx->csCtx.state != 0) && (globalCtx->csCtx.frames > 20)) { + this->actionFunc = func_80AA27EC; + } +} + +void func_80AA1AF8(DmStk* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 sin; + + this->unk_32A += 0x4B0; + sin = Math_SinS(this->unk_32A) * 10.0f; + Math_SmoothStepToF(&this->actor.world.pos.y, 160.0f + sin, 0.2f, 1.0f, 0.0001f); + + this->actor.world.rot.y = Actor_YawBetweenActors(&this->actor, &player->actor); + this->actor.shape.rot.y = this->actor.world.rot.y; + + this->actor.world.rot.x = 0x1B58; + this->actor.shape.rot.x = this->actor.world.rot.x; +} + +void func_80AA1B9C(DmStk* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + func_80AA1AF8(this, globalCtx); + this->unk_339++; + if (this->unk_339 >= 3) { + this->unk_339 = 0; + if (!(player->stateFlags2 & 0x8000000)) { + func_801518B0(globalCtx, 0x2013, &this->actor); + } + } + + this->unk_2E0 = 39; + func_80A9FE3C(this, globalCtx, &this->skelAnime, &sAnimations[this->unk_2E0], 0); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_DOWN_K); + this->actionFunc = func_80AA1C64; +} + +void func_80AA1C64(DmStk* this, GlobalContext* globalCtx) { + func_80AA1AF8(this, globalCtx); + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->unk_2E0 = 38; + func_80A9FE3C(this, globalCtx, &this->skelAnime, &sAnimations[this->unk_2E0], 0); + this->actionFunc = func_80AA27EC; + } + + if ((this->collider.base.acFlags & AC_HIT) && (this->actor.colChkInfo.damageEffect == 0xF)) { + this->actionFunc = func_80AA1B9C; + } +} + +void func_80AA1D1C(DmStk* this, GlobalContext* globalCtx) { + s32 pad; + u32 temp_v0; + + if (func_800EE29C(globalCtx, 0x6B)) { + temp_v0 = func_800EE200(globalCtx, 0x6B); + + if (globalCtx->csCtx.frames == globalCtx->csCtx.npcActions[temp_v0]->startFrame) { + if (this->unk_334 != globalCtx->csCtx.npcActions[temp_v0]->unk0) { + this->unk_334 = globalCtx->csCtx.npcActions[temp_v0]->unk0; + if (globalCtx->sceneNum == SCENE_CLOCKTOWER) { + this->unk_32D = 6; + } else { + this->unk_32D = 9; + } + + switch (globalCtx->csCtx.npcActions[temp_v0]->unk0) { + case 0: + case 1: + this->unk_2E0 = 3; + break; + + case 2: + this->unk_2E0 = 1; + break; + + case 3: + this->unk_2E0 = 20; + break; + + case 4: + this->unk_2E0 = 18; + break; + + case 6: + this->unk_2E0 = 16; + this->unk_32D = 3; + break; + + case 7: + this->unk_2E0 = 14; + this->unk_32D = 3; + break; + + case 8: + this->unk_2E0 = 0; + break; + + case 9: + this->unk_2E0 = 3; + this->unk_32E = 1; + break; + + case 12: + this->unk_2E0 = 12; + this->unk_32D = 3; + break; + + case 13: + this->unk_2E0 = 27; + this->unk_32D = 3; + break; + + case 14: + this->unk_2E0 = 22; + break; + + case 15: + this->unk_2E0 = 23; + break; + + case 16: + this->unk_2E0 = 28; + break; + + case 17: + this->unk_2E0 = 7; + break; + + case 18: + this->unk_2E0 = 8; + break; + + case 19: + this->unk_2E0 = 10; + break; + + case 20: + this->unk_2E0 = 24; + break; + + case 21: + this->unk_2E0 = 26; + break; + + case 22: + this->unk_2E0 = 29; + if (gSaveContext.inventory.items[SLOT_OCARINA] == ITEM_NONE) { + this->unk_32D = 3; + } + break; + + case 23: + this->unk_2E0 = 30; + this->unk_32D = 4; + break; + + case 24: + this->unk_2E0 = 32; + if (gSaveContext.inventory.items[SLOT_OCARINA] == ITEM_NONE) { + this->unk_32D = 3; + } + break; + + case 25: + Actor_MarkForDeath(&this->actor); + break; + + case 26: + this->unk_2E0 = 34; + if (gSaveContext.inventory.items[SLOT_OCARINA] == ITEM_NONE) { + this->unk_32D = 3; + } + break; + + case 27: + this->unk_2E0 = 36; + if (gSaveContext.inventory.items[SLOT_OCARINA] == ITEM_NONE) { + this->unk_32D = 3; + } + break; + + case 28: + this->unk_2E0 = 37; + this->unk_32D = 4; + break; + + case 30: + this->unk_2E0 = 38; + break; + + case 31: + this->unk_2E0 = 39; + break; + + case 32: + this->unk_2E0 = 42; + break; + + case 33: + this->unk_2E0 = 44; + break; + + case 34: + this->unk_2E0 = 46; + break; + + case 35: + this->unk_2E0 = 48; + break; + + case 36: + this->unk_2E0 = 50; + break; + + case 37: + this->unk_2E0 = 51; + break; + + case 38: + this->unk_2E0 = 52; + break; + + case 39: + this->unk_2E0 = 54; + break; + + case 40: + this->unk_2E0 = 55; + break; + + case 41: + this->unk_2E0 = 40; + break; + + case 42: + this->unk_2E0 = 5; + break; + + case 43: + this->unk_2E0 = 56; + break; + + case 44: + this->unk_2E0 = 57; + break; + + case 45: + this->unk_2E0 = 58; + this->unk_32F = 1; + break; + + case 46: + this->unk_32D = 6; + this->unk_2E0 = 59; + break; + + case 47: + this->unk_2E0 = 60; + break; + + case 48: + this->unk_2E0 = 60; + break; + + case 49: + this->unk_2E0 = 65; + break; + + case 50: + this->unk_2E0 = 66; + break; + + case 51: + this->unk_2E0 = 68; + break; + + case 52: + this->unk_2E0 = 70; + break; + + case 53: + this->unk_2E0 = 60; + break; + + case 54: + this->unk_2E0 = 61; + break; + + case 55: + this->unk_2E0 = 62; + break; + + case 56: + this->unk_2E0 = 64; + break; + + case 57: + this->unk_2E0 = 65; + break; + + case 58: + this->unk_2E0 = 66; + break; + + case 59: + this->unk_2E0 = 68; + break; + + case 60: + this->unk_2E0 = 70; + break; + + case 5: + case 10: + break; + + default: + this->unk_2E0 = 0; + break; + } + + func_80A9FE3C(this, globalCtx, &this->skelAnime, &sAnimations[this->unk_2E0], 0); + } + } + + func_800EDF24(&this->actor, globalCtx, temp_v0); + } else { + this->unk_334 = 99; + } + + if (this->unk_32E == 1) { + Math_SmoothStepToF(&this->unk_300, 0.7f, 0.1f, 0.007f, 0.005f); + if (this->unk_300 < 0.71f) { + this->unk_300 = 0.7f; + this->unk_2F8 = 800; + this->unk_32E++; + } + this->unk_2E8 = globalCtx->lightCtx.unk7 * this->unk_300; + this->unk_2EC = globalCtx->lightCtx.unk8 * this->unk_300; + this->unk_2F0 = globalCtx->lightCtx.unk9 * this->unk_300; + + } else if (this->unk_32E == 2) { + if (this->unk_2F8 < 996) { + this->unk_2F8 += 10; + } + + if (this->unk_2F8 > 996) { + this->unk_32E++; + this->unk_2F8 = 996; + } + } else if (this->unk_32E == 3) { + if (this->unk_2E4 < 128) { + this->unk_2E4 += 3; + } + + if (this->unk_2E4 < 255) { + this->unk_2E4 += 20; + } else { + this->unk_2E4 = 255; + this->unk_32E = 0; + } + } + + if (this->unk_32F == 1) { + if (this->unk_330 > 40) { + this->unk_32C = 3; + } + + this->unk_330++; + if (this->unk_330 >= 44) { + this->unk_2E4 -= 35; + if (this->unk_2E4 < 0) { + this->unk_2E4 = 0; + this->unk_32F = 0; + gSaveContext.weekEventReg[12] |= 4; + if (!(globalCtx->actorCtx.unk5 & 2)) { + Actor_MarkForDeath(&this->actor); + } else { + this->unk_33B = 0; + } + } + } + } + + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + switch (this->unk_2E0) { + case 2: + case 8: + case 10: + case 12: + case 14: + case 16: + case 18: + case 20: + case 22: + case 24: + case 30: + case 32: + case 34: + case 40: + case 42: + case 44: + case 46: + case 48: + case 52: + case 62: + case 66: + case 68: + case 70: + this->unk_2E0++; + func_80A9FE3C(this, globalCtx, &this->skelAnime, &sAnimations[this->unk_2E0], 0); + break; + + case 26: + this->unk_2E0 = 3; + this->unk_32C = 1; + this->unk_32D = 9; + func_80A9FE3C(this, globalCtx, &this->skelAnime, &sAnimations[this->unk_2E0], 0); + break; + } + } + + if (((this->unk_2E0 == 24) && (this->skelAnime.curFrame >= 16.0f)) || (this->unk_2E0 == 25) || + (this->unk_2E0 == 26)) { + this->unk_32C = 9; + this->unk_32D = 2; + } else if (((this->unk_2E0 >= 50) && (this->unk_2E0 < 56)) || ((this->unk_2E0 > 58) && (this->unk_2E0 <= 60)) || + ((globalCtx->sceneNum == SCENE_00KEIKOKU) && (gSaveContext.sceneSetupIndex == 7))) { + this->unk_32C = 0; + if ((this->unk_2E0 == 52) || (this->unk_2E0 == 53)) { + this->unk_32D = 5; + } + } + + if (this->unk_2E0 == 64) { + this->unk_32C = 0; + } +} + +void func_80AA26CC(DmStk* this, GlobalContext* globalCtx) { + s32 pad; + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void func_80AA2720(DmStk* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (globalCtx->csCtx.state == 0) { + func_80AA1AF8(this, globalCtx); + this->actor.flags |= 1; + this->unk_328++; + if (this->unk_328 > 800) { + this->unk_328 = 0; + if (!(player->stateFlags2 & 0x8000000)) { + func_801518B0(globalCtx, 0x2014, &this->actor); + } + } + if ((this->collider.base.acFlags & AC_HIT) && (this->actor.colChkInfo.damageEffect == 0xF)) { + this->unk_335 = 1; + this->actionFunc = func_80AA1A50; + } + } +} + +void func_80AA27EC(DmStk* this, GlobalContext* globalCtx) { + if (globalCtx->csCtx.state == 0) { + func_80AA1AF8(this, globalCtx); + this->actor.flags |= 1; + + if (this->unk_2E0 == 33) { + this->actor.targetArrowOffset = 3100.0f; + } else { + this->actor.targetArrowOffset = 200.0f; + } + + if ((this->collider.base.acFlags & AC_HIT) && (this->actor.colChkInfo.damageEffect == 0xF)) { + this->unk_335 = 1; + this->actionFunc = func_80AA1B9C; + } + } +} + +void DmStk_Update(Actor* thisx, GlobalContext* globalCtx) { + DmStk* this = THIS; + u16 time; + + if (this->actor.params != 1) { + if (this->unk_2E0 == 33) { + Actor_SetHeight(&this->actor, 40.0f); + } else { + Actor_SetHeight(&this->actor, 6.0f); + } + + func_80A9FDB0(this, globalCtx); + + if (this->unk_2E0 != 61) { + SkelAnime_Update(&this->skelAnime); + } + + this->unk_2E4 = this->unk_2E4; + + this->actionFunc(this, globalCtx); + + if (globalCtx->sceneNum == SCENE_OKUJOU) { + func_80AA26CC(this, globalCtx); + } + + func_80AA1D1C(this, globalCtx); + func_80AA0E90(this, globalCtx); + + switch (this->unk_33A) { + case 1: + if (func_800B8718(&this->actor, globalCtx)) { + this->unk_33A = 2; + } else { + func_800B874C(&this->actor, globalCtx, this->actor.xzDistToPlayer, + fabsf(this->actor.playerHeightRel)); + } + break; + + case 2: + if (ActorCutscene_GetCanPlayNext(0x10)) { + this->unk_33A = 3; + ActorCutscene_Start(0x10, &this->actor); + this->actionFunc = func_80AA27EC; + } else { + ActorCutscene_SetIntentToPlay(0x10); + } + break; + + case 3: + if (globalCtx->csCtx.state == 0) { + this->unk_33A = 4; + } + break; + } + + if ((globalCtx->actorCtx.unk5 & 2) && (globalCtx->msgCtx.unk11F22 != 0) && + (globalCtx->msgCtx.unk11F04 == 0x5E6) && !FrameAdvance_IsEnabled(globalCtx) && + (globalCtx->sceneLoadFlag == 0) && (ActorCutscene_GetCurrentIndex() == -1) && + (globalCtx->csCtx.state == 0)) { + time = gSaveContext.time; + gSaveContext.time = (u16)REG(15) + time; + if (REG(15) != 0) { + time = gSaveContext.time; + gSaveContext.time = (u16)gSaveContext.unk_14 + time; + } + } + } + + if ((globalCtx->sceneNum == SCENE_00KEIKOKU) && (gSaveContext.sceneSetupIndex == 3) && + (globalCtx->csCtx.unk_12 > 0)) { + globalCtx->envCtx.unk_17 = 15; + globalCtx->envCtx.unk_18 = 15; + } +} + +s32 DmStk_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + DmStk* this = THIS; + + if (limbIndex == 15) { + if ((this->unk_32D == 0) || (this->unk_32D == 1) || (this->unk_32D == 3)) { + *dList = NULL; + } + } else if (limbIndex == 12) { + switch (this->unk_32D) { + case 1: + case 2: + case 3: + case 4: + case 6: + *dList = NULL; + break; + + case 9: + if (this->unk_2E4 == 255) { + *dList = NULL; + } + break; + } + } else if (limbIndex == 17) { + *dList = NULL; + } + + return false; +} + +void DmStk_PostLimbDraw2(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { + s32 pad; + s32 pad2; + DmStk* this = THIS; + + if (limbIndex == 17) { + Matrix_GetStateTranslation(&this->unk_304); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + if ((this->unk_2E0 == 69) || (this->unk_2E0 == 11) || (this->unk_2E0 == 71)) { + gSPDisplayList(POLY_OPA_DISP++, D_0600AEC0); + gSPDisplayList(POLY_OPA_DISP++, D_0600AE30); + } else { + gSPDisplayList(POLY_OPA_DISP++, D_0600A5C0); + gSPDisplayList(POLY_OPA_DISP++, D_0600A530); + } + + switch (this->unk_32C) { + case 0: + break; + + case 1: + if ((globalCtx->sceneNum == SCENE_LOST_WOODS) && (gSaveContext.sceneSetupIndex == 1) && + (globalCtx->csCtx.frames < 1400)) { + if (this->unk_2F8 == this->unk_2FC) { + this->unk_2FC = this->unk_2F8; + } + POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, this->unk_2E8, this->unk_2EC, this->unk_2F0, + this->unk_2F4, this->unk_2F8, this->unk_2FC); + gSPDisplayList(POLY_OPA_DISP++, D_06006BB0); + POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP); + } else { + gSPDisplayList(POLY_OPA_DISP++, D_06006BB0); + } + break; + + case 2: + gSPDisplayList(POLY_OPA_DISP++, D_06006BB0); + gSPDisplayList(POLY_OPA_DISP++, D_06005870); + + if (func_800EE29C(globalCtx, 0x201) && + (globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x201)]->unk0 == 2) && (this->unk_337 >= 0)) { + Matrix_StatePush(); + Matrix_Scale(2.0f, 2.0f, 2.0f, MTXMODE_APPLY); + gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[this->unk_337].segment); + + gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[this->unk_337].segment); + + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_06008658)); + func_800BDFC0(globalCtx, D_06007840); + gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[this->unk_336].segment); + + gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[this->unk_336].segment); + + Matrix_StatePop(); + } + break; + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + } else if (limbIndex == 15) { + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (this->unk_32D != 5) { + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + } + + switch (this->unk_32D) { + case 0: + gSPDisplayList(POLY_OPA_DISP++, D_06009AC0); + gSPDisplayList(POLY_OPA_DISP++, D_060046B0); + break; + + case 1: + gSPDisplayList(POLY_OPA_DISP++, D_06009710); + gSPDisplayList(POLY_OPA_DISP++, D_060053C0); + break; + + case 3: + gSPDisplayList(POLY_OPA_DISP++, D_06009DA0); + + if ((globalCtx->sceneNum == SCENE_LOST_WOODS) && (gSaveContext.sceneSetupIndex == 1)) { + gSPDisplayList(POLY_OPA_DISP++, D_0600CAD0); + } + break; + + case 5: + Matrix_InsertTranslation(-20.0f, -660.0f, 860.0f, MTXMODE_APPLY); + Matrix_RotateY(0x6142, MTXMODE_APPLY); + Matrix_InsertXRotation_s(-0x1988, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, D_06006BB0); + break; + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + } else if (limbIndex == 12) { + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + switch (this->unk_32D) { + case 0: + break; + + case 1: + gSPDisplayList(POLY_OPA_DISP++, D_060084C0); + break; + + case 2: + gSPDisplayList(POLY_OPA_DISP++, D_060090C0); + gSPDisplayList(POLY_OPA_DISP++, D_060079F0); + break; + + case 3: + if ((globalCtx->sceneNum != SCENE_LOST_WOODS) || (gSaveContext.sceneSetupIndex != 1)) { + gSPDisplayList(POLY_OPA_DISP++, D_0600CAD0); + } + gSPDisplayList(POLY_OPA_DISP++, D_060090C0); + break; + + case 4: + gSPDisplayList(POLY_OPA_DISP++, D_060090C0); + break; + + case 6: + gSPDisplayList(POLY_OPA_DISP++, D_06008A80); + gSPDisplayList(POLY_OPA_DISP++, D_06016620); + break; + + case 9: + if (this->unk_2E4 == 255) { + gSPDisplayList(POLY_OPA_DISP++, D_060087B0); + } + break; + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void DmStk_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + DmStk* this = THIS; + + DmStk_PostLimbDraw2(globalCtx, limbIndex, dList, rot, &this->actor, NULL); +} + +void DmStk_Draw(Actor* thisx, GlobalContext* globalCtx) { + DmStk* this = THIS; + + if (this->unk_33B != 0) { + if (this->actor.params == 1) { + func_800BDFC0(globalCtx, D_06006BB0); + return; + } + + gSegments[6] = PHYSICAL_TO_VIRTUAL(globalCtx->objectCtx.status[this->unk_336].segment); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + this->unk_2E4 = this->unk_2E4; + func_8012C28C(globalCtx->state.gfxCtx); + + if (this->unk_2E4 < 255) { + func_8012C2DC(globalCtx->state.gfxCtx); + Scene_SetRenderModeXlu(globalCtx, 1, 2); + + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, this->unk_2E4); + + POLY_XLU_DISP = + SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, NULL, DmStk_PostLimbDraw2, &this->actor, POLY_XLU_DISP); + } else { + Scene_SetRenderModeXlu(globalCtx, 0, 1); + + gDPPipeSync(POLY_OPA_DISP++); + gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 255); + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, DmStk_OverrideLimbDraw, DmStk_PostLimbDraw, &this->actor); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} diff --git a/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.h b/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.h index 07459e717..2b8c54383 100644 --- a/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.h +++ b/src/overlays/actors/ovl_Dm_Stk/z_dm_stk.h @@ -9,9 +9,37 @@ typedef void (*DmStkActionFunc)(struct DmStk*, GlobalContext*); typedef struct DmStk { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x14C]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ UNK_TYPE1 unk_188[0x108]; /* 0x0290 */ DmStkActionFunc actionFunc; - /* 0x0294 */ char unk_294[0xA8]; + /* 0x0294 */ ColliderCylinder collider; + /* 0x02E0 */ s16 unk_2E0; + /* 0x02E4 */ s32 unk_2E4; + /* 0x02E8 */ u32 unk_2E8; + /* 0x02EC */ u32 unk_2EC; + /* 0x02F0 */ u32 unk_2F0; + /* 0x02F4 */ s32 unk_2F4; + /* 0x02F8 */ s32 unk_2F8; + /* 0x02FC */ s32 unk_2FC; + /* 0x0300 */ f32 unk_300; + /* 0x0304 */ Vec3f unk_304; + /* 0x0310 */ Vec3f unk_310; + /* 0x031C */ UNK_TYPE1 unk31C[0xC]; + /* 0x0328 */ u16 unk_328; + /* 0x032A */ u16 unk_32A; + /* 0x032C */ u8 unk_32C; + /* 0x032D */ u8 unk_32D; + /* 0x032E */ u8 unk_32E; + /* 0x032F */ u8 unk_32F; + /* 0x0330 */ s32 unk_330; + /* 0x0334 */ u8 unk_334; + /* 0x0335 */ u8 unk_335; + /* 0x0336 */ s8 unk_336; + /* 0x0337 */ s8 unk_337; + /* 0x0338 */ s8 unk_338; + /* 0x0339 */ u8 unk_339; + /* 0x033A */ u8 unk_33A; + /* 0x033B */ u8 unk_33B; } DmStk; // size = 0x33C extern const ActorInit Dm_Stk_InitVars; diff --git a/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c b/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c index 22e249861..b37a3df2f 100644 --- a/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c +++ b/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.c @@ -5,6 +5,7 @@ */ #include "z_door_warp1.h" +#include "objects/object_warp1/object_warp1.h" #define FLAGS 0x00000000 @@ -15,26 +16,39 @@ void DoorWarp1_Destroy(Actor* thisx, GlobalContext* globalCtx); void DoorWarp1_Update(Actor* thisx, GlobalContext* globalCtx); void DoorWarp1_Draw(Actor* thisx, GlobalContext* globalCtx); +void DoorWarp1_SetupAction(DoorWarp1* this, DoorWarp1ActionFunc actionFunc); +void func_808B8924(DoorWarp1* this, GlobalContext* globalCtx); +void func_808B8A7C(DoorWarp1* this, GlobalContext* globalCtx); +void func_808B8C48(DoorWarp1* this, GlobalContext* globalCtx); +void func_808B8E78(DoorWarp1* this, GlobalContext* globalCtx); +void func_808B9094(DoorWarp1* this, GlobalContext* globalCtx); +void func_808B90CC(DoorWarp1* this, GlobalContext* globalCtx); void func_808B921C(DoorWarp1* this, GlobalContext* globalCtx); void func_808B93A0(DoorWarp1* this, GlobalContext* globalCtx); void func_808B94A4(DoorWarp1* this, GlobalContext* globalCtx); void func_808B9524(DoorWarp1* this, GlobalContext* globalCtx); void func_808B958C(DoorWarp1* this, GlobalContext* globalCtx); +void func_808B96A0(DoorWarp1* this, GlobalContext* globalCtx); void func_808B96B0(DoorWarp1* this, GlobalContext* globalCtx); +void func_808B977C(DoorWarp1* this, GlobalContext* globalCtx); void func_808B9840(DoorWarp1* this, GlobalContext* globalCtx); void func_808B98A8(DoorWarp1* this, GlobalContext* globalCtx); void func_808B9B30(DoorWarp1* this, GlobalContext* globalCtx); void func_808B9BE8(DoorWarp1* this, GlobalContext* globalCtx); void func_808B9CE8(DoorWarp1* this, GlobalContext* globalCtx); void func_808B9E94(DoorWarp1* this, GlobalContext* globalCtx); +void func_808B9ED8(DoorWarp1* this, GlobalContext* globalCtx); +void func_808B9F10(DoorWarp1* this, GlobalContext* globalCtx); void func_808B9FD0(DoorWarp1* this, GlobalContext* globalCtx); +void func_808BA10C(DoorWarp1* this, GlobalContext* globalCtx); void func_808BA550(DoorWarp1* this, GlobalContext* globalCtx); void func_808BAAF4(DoorWarp1* this, GlobalContext* globalCtx); void func_808BABF4(DoorWarp1* this, GlobalContext* globalCtx); +void func_808BB8D4(DoorWarp1* this, GlobalContext* globalCtx, s32 arg2); -void DoorWarp1_SetupAction(DoorWarp1* this, DoorWarp1ActionFunc actionFunc); +static s16 D_808BC000; +static f32 D_808BC004; -#if 0 const ActorInit Door_Warp1_InitVars = { ACTOR_DOOR_WARP1, ACTORCAT_ITEMACTION, @@ -47,92 +61,1114 @@ const ActorInit Door_Warp1_InitVars = { (ActorFunc)DoorWarp1_Draw, }; +static InitChainEntry sInitChain[] = { + ICHAIN_VEC3F_DIV1000(scale, 1000, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneScale, 800, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneDownward, 4000, ICHAIN_STOP), +}; + +void DoorWarp1_SetupAction(DoorWarp1* this, DoorWarp1ActionFunc actionFunc) { + this->actionFunc = actionFunc; +} + +s32 func_808B849C(DoorWarp1* this, GlobalContext* globalCtx) { + s32 ret = 0; + + if ((globalCtx->sceneNum == SCENE_MITURIN_BS) && !CHECK_QUEST_ITEM(QUEST_REMAINS_ODOWLA)) { + ret = 1; + } else if ((globalCtx->sceneNum == SCENE_HAKUGIN_BS) && !CHECK_QUEST_ITEM(QUEST_REMAINS_GOHT)) { + ret = 2; + } else if ((globalCtx->sceneNum == SCENE_SEA_BS) && !CHECK_QUEST_ITEM(QUEST_REMAINS_GYORG)) { + ret = 3; + } else if ((globalCtx->sceneNum == SCENE_INISIE_BS) && !CHECK_QUEST_ITEM(QUEST_REMAINS_TWINMOLD)) { + ret = 4; + } + return ret; +} + +void func_808B8568(DoorWarp1* this, GlobalContext* globalCtx) { + s32 pad[2]; + + Lights_PointNoGlowSetInfo(&this->unk_1E0, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, 0, 0, 0, 0); + this->unk_1DC = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->unk_1E0); + Lights_PointNoGlowSetInfo(&this->unk_1F4, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, 0, 0, 0, 0); + this->unk_1F0 = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->unk_1F4); +} + +s32 func_808B866C(DoorWarp1* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 ret = false; + + if ((fabsf(this->dyna.actor.xzDistToPlayer) < 60.0f) && + (((player->actor.world.pos.y - 20.0f) < this->dyna.actor.world.pos.y) && + (this->dyna.actor.world.pos.y < (player->actor.world.pos.y + 20.0f)))) { + ret = true; + } + return ret; +} + +void DoorWarp1_Init(Actor* thisx, GlobalContext* globalCtx) { + DoorWarp1* this = THIS; + + this->unk_1CC = 0; + this->unk_202 = 0; + this->unk_203 = 0; + this->unk_1A0 = NULL; + this->unk_1C0 = 0.0f; + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + ActorShape_Init(&this->dyna.actor.shape, 0.0f, NULL, 0.0f); + + this->unk_1D3 = 0; + this->unk_1D4 = 0; + this->unk_203 = 0; + this->unk_204 = 1.0f; + + switch (DOORWARP1_GET_FF(&this->dyna.actor)) { + case ENDOORWARP1_FF_0: + case ENDOORWARP1_FF_1: + case ENDOORWARP1_FF_2: + case ENDOORWARP1_FF_3: + case ENDOORWARP1_FF_4: + case ENDOORWARP1_FF_5: + func_808B8568(this, globalCtx); + break; + } + + switch (DOORWARP1_GET_FF(&this->dyna.actor)) { + case ENDOORWARP1_FF_0: + func_808B8924(this, globalCtx); + break; + + case ENDOORWARP1_FF_1: + func_808B8A7C(this, globalCtx); + break; + + case ENDOORWARP1_FF_2: + case ENDOORWARP1_FF_3: + case ENDOORWARP1_FF_4: + case ENDOORWARP1_FF_5: + this->unk_1D3 = 1; + DynaPolyActor_Init(&this->dyna, 0); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_warp1_Colheader_008BD4); + func_808B8C48(this, globalCtx); + break; + + case ENDOORWARP1_FF_6: + func_808B8E78(this, globalCtx); + break; + } + + if ((globalCtx->sceneNum == SCENE_MITURIN_BS) || (globalCtx->sceneNum == SCENE_HAKUGIN_BS) || + (globalCtx->sceneNum == SCENE_INISIE_BS) || (globalCtx->sceneNum == SCENE_SEA_BS)) { + func_800FE484(); + globalCtx->interfaceCtx.restrictions.unk_312 = 1; + globalCtx->interfaceCtx.restrictions.songOfSoaring = 1; + } +} + +void DoorWarp1_Destroy(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + DoorWarp1* this = THIS; + s16 i; + + LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->unk_1DC); + LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->unk_1F0); + + for (i = 0; i < ARRAY_COUNT(globalCtx->envCtx.unk_8C.diffuseColor1); i++) { + globalCtx->envCtx.unk_8C.diffuseColor1[i] = 0; + globalCtx->envCtx.unk_8C.fogColor[i] = globalCtx->envCtx.unk_8C.diffuseColor1[i]; + globalCtx->envCtx.unk_8C.ambientColor[i] = globalCtx->envCtx.unk_8C.diffuseColor1[i]; + } + + if (this->unk_1D3 != 0) { + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + } +} + +void func_808B8924(DoorWarp1* this, GlobalContext* globalCtx) { + this->unk_1C4 = 0; + this->unk_1C6 = -140; + this->unk_1C8 = -80; + this->unk_1BC = 1.0f; + this->unk_1B0 = 0.0f; + this->unk_1B4 = 0.0f; + this->unk_1B8 = 0.0f; + this->unk_1A4 = 0.3f; + this->unk_1A8 = 0.3f; + this->unk_1AC = 0.0f; + this->dyna.actor.shape.yOffset = 1.0f; + this->unk_1D0 = 0; + D_808BC000 = 100; + Lights_PointNoGlowSetInfo(&this->unk_1E0, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, 200, 255, 255, 255); + Lights_PointNoGlowSetInfo(&this->unk_1F4, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, 200, 255, 255, 255); + DoorWarp1_SetupAction(this, func_808B96B0); +} + +void func_808B8A7C(DoorWarp1* this, GlobalContext* globalCtx) { + SkelAnime_Init(globalCtx, &this->skelAnime, &object_warp1_Skel_002CA8, &object_warp1_Anim_001374, NULL, NULL, 0); + Animation_ChangeImpl(&this->skelAnime, &object_warp1_Anim_001374, 1.0f, 1.0f, 1.0f, 2, 40.0f, 1); + this->unk_1C4 = 0; + this->unk_1C6 = -140; + this->unk_1C8 = -80; + this->unk_1D0 = 0; + this->unk_1BC = 1.0f; + this->unk_1A4 = 0.3f; + this->unk_1A8 = 0.3f; + this->unk_1B0 = 0.0f; + this->unk_1B4 = 0.0f; + this->unk_1B8 = 0.0f; + this->unk_1AC = 0.0f; + this->dyna.actor.shape.yOffset = -400.0f; + D_808BC000 = 160; + Lights_PointNoGlowSetInfo(&this->unk_1E0, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, 200, 255, 255, 255); + Lights_PointNoGlowSetInfo(&this->unk_1F4, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, 200, 255, 255, 255); + DoorWarp1_SetupAction(this, func_808B9B30); +} + +void func_808B8C48(DoorWarp1* this, GlobalContext* globalCtx) { + this->dyna.actor.shape.yOffset = 0.0f; + Actor_SetScale(&this->dyna.actor, 0.1f); + Lights_PointNoGlowSetInfo(&this->unk_1E0, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, 200, 255, 255, 255); + Lights_PointNoGlowSetInfo(&this->unk_1F4, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, 200, 255, 255, 255); + if (((DOORWARP1_GET_FF(&this->dyna.actor) == ENDOORWARP1_FF_2) && CHECK_QUEST_ITEM(QUEST_REMAINS_ODOWLA)) || + ((DOORWARP1_GET_FF(&this->dyna.actor) == ENDOORWARP1_FF_3) && CHECK_QUEST_ITEM(QUEST_REMAINS_GOHT)) || + ((DOORWARP1_GET_FF(&this->dyna.actor) == ENDOORWARP1_FF_4) && CHECK_QUEST_ITEM(QUEST_REMAINS_GYORG)) || + ((DOORWARP1_GET_FF(&this->dyna.actor) == ENDOORWARP1_FF_5) && CHECK_QUEST_ITEM(QUEST_REMAINS_TWINMOLD))) { + s16 params = DOORWARP1_GET_FF00_2(&this->dyna.actor); + + params |= 6; + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->dyna.actor, globalCtx, ACTOR_DOOR_WARP1, + this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y + 10.0f, + this->dyna.actor.world.pos.z, this->dyna.actor.world.rot.x, this->dyna.actor.world.rot.y, + this->dyna.actor.world.rot.z, params); + DoorWarp1_SetupAction(this, func_808BAAF4); + } else { + DoorWarp1_SetupAction(this, func_808BABF4); + } +} + +void func_808B8E78(DoorWarp1* this, GlobalContext* globalCtx) { + Actor_SetScale(&this->dyna.actor, 0.1f); + Lights_PointNoGlowSetInfo(&this->unk_1E0, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, 200, 255, 255, 0); + Lights_PointNoGlowSetInfo(&this->unk_1F4, this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, 200, 255, 255, 0); + Actor_SetScale(&this->dyna.actor, 3.0f); + this->unk_1D4 = 1; + this->unk_1D0 = 0; + this->unk_1A8 = 0.0f; + this->unk_1AC = 0.0f; + this->unk_1A4 = 700.0f; + if (globalCtx->sceneNum == SCENE_INISIE_N) { + DoorWarp1_SetupAction(this, func_808B96A0); + } else if (gSaveContext.weekEventReg[86] & 0x80) { + this->unk_1D4 = 0; + DoorWarp1_SetupAction(this, func_808B921C); + } else { + DoorWarp1_SetupAction(this, func_808B9094); + } +} + +s32 func_808B900C(DoorWarp1* this, GlobalContext* globalCtx) { + u32 index; + u8 ret = false; + + if (func_800EE29C(globalCtx, 0x239)) { + index = func_800EE200(globalCtx, 0x239); + if (this->unk_208 != globalCtx->csCtx.npcActions[index]->unk0) { + this->unk_208 = globalCtx->csCtx.npcActions[index]->unk0; + if (globalCtx->csCtx.npcActions[index]->unk0 == 2) { + ret = true; + } + } + } + + return ret; +} + +void func_808B9094(DoorWarp1* this, GlobalContext* globalCtx) { + if (func_808B900C(this, globalCtx)) { + DoorWarp1_SetupAction(this, func_808B90CC); + } +} + +void func_808B90CC(DoorWarp1* this, GlobalContext* globalCtx) { + s32 pad[2]; + s16 sp2E = 0; + f32 phi_f0 = 0.0f; + + if (globalCtx->sceneNum == SCENE_MITURIN) { + sp2E = -10; + phi_f0 = -5.0f; + } else if (globalCtx->sceneNum == SCENE_HAKUGIN) { + sp2E = -20; + } else if (globalCtx->sceneNum == SCENE_SEA) { + sp2E = -20; + } + + Math_SmoothStepToF(&this->unk_1AC, 40.0f, 0.5f, 1.2f + phi_f0, 0.01f); + Math_SmoothStepToF(&this->unk_1A4, 0.0f, 0.5f, 12.0f, 0.1f); + if ((this->unk_1A4 < 460.0f) && (this->unk_1A4 > 100.0f)) { + func_808BB8D4(this, globalCtx, 6); + } + + if (this->unk_1A4 < 0.1f) { + this->unk_1D0 = sp2E + 30; + this->unk_1D4 = 0; + DoorWarp1_SetupAction(this, func_808B921C); + } + + Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_WARP_HOLE_ENERGY - SFX_FLAG); +} + +void func_808B921C(DoorWarp1* this, GlobalContext* globalCtx) { + if (this->unk_1D0 != 0) { + this->unk_1D0--; + return; + } + + Math_SmoothStepToF(&this->unk_1A8, 1.0f, 0.2f, 0.05f, 0.01f); + this->unk_203 = (u8)(this->unk_1A8 * 200.0f); + if (this->unk_1A8 > 0.8f) { + func_808BB8D4(this, globalCtx, 1); + } + + if (func_808B866C(this, globalCtx) && !func_801690CC(globalCtx)) { + func_800B7298(globalCtx, &this->dyna.actor, 7); + func_801518B0(globalCtx, 0xF2, &this->dyna.actor); + DoorWarp1_SetupAction(this, func_808B93A0); + } + + Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BOSS_WARP_HOLE - SFX_FLAG); +} + +void func_808B93A0(DoorWarp1* this, GlobalContext* globalCtx) { + s32 pad; + Player* player = GET_PLAYER(globalCtx); + + if ((func_80152498(&globalCtx->msgCtx) == 4) && func_80147624(globalCtx)) { + func_801477B4(globalCtx); + if (globalCtx->msgCtx.choiceIndex == 0) { + func_8019F208(); + func_800B7298(globalCtx, &this->dyna.actor, 9); + player->unk_3A0.x = this->dyna.actor.world.pos.x; + player->unk_3A0.z = this->dyna.actor.world.pos.z; + this->unk_1CA = 1; + DoorWarp1_SetupAction(this, func_808B9524); + } else { + func_8019F230(); + func_800B7298(globalCtx, &this->dyna.actor, 6); + DoorWarp1_SetupAction(this, func_808B94A4); + } + } + func_808BB8D4(this, globalCtx, 1); + Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BOSS_WARP_HOLE - SFX_FLAG); +} + +void func_808B94A4(DoorWarp1* this, GlobalContext* globalCtx) { + if (!func_808B866C(this, globalCtx) && (ActorCutscene_GetCurrentIndex() != globalCtx->unk_1879C[8])) { + DoorWarp1_SetupAction(this, func_808B921C); + } + func_808BB8D4(this, globalCtx, 1); + Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BOSS_WARP_HOLE - SFX_FLAG); +} + +void func_808B9524(DoorWarp1* this, GlobalContext* globalCtx) { + if (!ActorCutscene_GetCanPlayNext(globalCtx->unk_1879C[9])) { + ActorCutscene_SetIntentToPlay(globalCtx->unk_1879C[9]); + } else { + ActorCutscene_Start(globalCtx->unk_1879C[9], NULL); + DoorWarp1_SetupAction(this, func_808B958C); + } +} + +void func_808B958C(DoorWarp1* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + func_808BB8D4(this, globalCtx, 1); + + if (this->unk_1CA > 100) { + if (player->actor.velocity.y < 10.0f) { + player->actor.gravity = 0.1f; + } else { + player->actor.gravity = 0.0f; + } + } else { + this->unk_1CA++; + } + + this->unk_1D0++; + if ((this->unk_1D0 > 120) && (gSaveContext.nextCutsceneIndex == 0xFFEF)) { + func_808BA10C(this, globalCtx); + globalCtx->unk_1887F = 3; + gSaveContext.nextTransition = 3; + } + + Math_SmoothStepToF(&this->unk_1A8, 6.0f, 0.2f, 0.02f, 0.01f); + Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_LINK_WARP - SFX_FLAG); +} + +void func_808B96A0(DoorWarp1* this, GlobalContext* globalCtx) { +} + +void func_808B96B0(DoorWarp1* this, GlobalContext* globalCtx) { + Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_WARP_HOLE - SFX_FLAG); + Math_SmoothStepToF(&this->unk_1B0, 255.0f, 0.4f, 10.0f, 0.01f); + Math_SmoothStepToF(&this->unk_1B4, 255.0f, 0.4f, 10.0f, 0.01f); + + if (this->unk_1C4 < 100) { + this->unk_1C4 += 2; + } + + if (this->unk_1C6 < 120) { + this->unk_1C6 += 4; + } + + if (this->unk_1C8 < 230) { + this->unk_1C8 += 4; + } else { + DoorWarp1_SetupAction(this, func_808B977C); + } +} + +void func_808B977C(DoorWarp1* this, GlobalContext* globalCtx) { + Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_WARP_HOLE - SFX_FLAG); + if (func_808B866C(this, globalCtx) && !func_801690CC(globalCtx)) { + Player* player = GET_PLAYER(globalCtx); + + func_801A5CFC(NA_SE_EV_LINK_WARP, &player->actor.projectedPos, 4, &D_801DB4B0, &D_801DB4B0, &D_801DB4B8); + func_800B7298(globalCtx, &this->dyna.actor, 9); + player->unk_3A0.x = this->dyna.actor.world.pos.x; + player->unk_3A0.z = this->dyna.actor.world.pos.z; + this->unk_1CA = 1; + DoorWarp1_SetupAction(this, func_808B9840); + } +} + +void func_808B9840(DoorWarp1* this, GlobalContext* globalCtx) { + if (!ActorCutscene_GetCanPlayNext(globalCtx->unk_1879C[9])) { + ActorCutscene_SetIntentToPlay(globalCtx->unk_1879C[9]); + } else { + ActorCutscene_Start(globalCtx->unk_1879C[9], NULL); + DoorWarp1_SetupAction(this, func_808B98A8); + } +} + +void func_808B98A8(DoorWarp1* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (this->unk_1CA > 100) { + if (player->actor.velocity.y < 10.0f) { + player->actor.gravity = 0.1f; + } else { + player->actor.gravity = 0.0f; + } + } else { + this->unk_1CA++; + } + + Math_SmoothStepToF(&this->unk_1B0, 0.0f, 0.2f, 6.0f, 0.01f); + + this->unk_1D0++; + if (D_808BC000 < this->unk_1D0) { + if ((gSaveContext.nextCutsceneIndex == 0xFFEF) && (D_808BC000 < this->unk_1D0) && + (gSaveContext.nextCutsceneIndex == 0xFFEF)) { + if (DOORWARP1_GET_FF00_1(&this->dyna.actor) != 0xFF) { + globalCtx->nextEntranceIndex = globalCtx->setupExitList[DOORWARP1_GET_FF00_3(&this->dyna.actor)]; + Scene_SetExitFade(globalCtx); + globalCtx->sceneLoadFlag = 0x14; + } else { + func_80169FDC(globalCtx); + } + } + } + + Math_StepToF(&this->unk_1A4, 2.0f, 0.01f); + Math_StepToF(&this->unk_1A8, 10.0f, 0.02f); + Lights_PointNoGlowSetInfo(&this->unk_1E0, player->actor.world.pos.x + 10, player->actor.world.pos.y + 10, + player->actor.world.pos.z + 10, 235, 255, 255, 255); + Lights_PointNoGlowSetInfo(&this->unk_1F4, player->actor.world.pos.x - 10, player->actor.world.pos.y - 10, + player->actor.world.pos.z - 10, 235, 255, 255, 255); + Math_SmoothStepToF(&this->dyna.actor.shape.yOffset, 0.0f, 0.5f, 2.0f, 0.1f); +} + +void func_808B9B30(DoorWarp1* this, GlobalContext* globalCtx) { + if (fabsf(this->dyna.actor.xzDistToPlayer) >= 60.0f) { + if (func_808B849C(this, globalCtx)) { + this->unk_1A0 = + (DmHina*)Actor_SpawnAsChild(&globalCtx->actorCtx, &this->dyna.actor, globalCtx, ACTOR_DM_HINA, + this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, 0, 0, 0, func_808B849C(this, globalCtx) - 1); + } + DoorWarp1_SetupAction(this, func_808B9BE8); + } +} + +void func_808B9BE8(DoorWarp1* this, GlobalContext* globalCtx) { + Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_WARP_HOLE - SFX_FLAG); + Math_SmoothStepToF(&this->unk_1B0, 255.0f, 0.2f, 2.0f, 0.1f); + Math_SmoothStepToF(&this->unk_1B4, 255.0f, 0.2f, 2.0f, 0.1f); + if (this->unk_1C4 < 10) { + this->unk_1C4 += 2; + } + + if (this->unk_1C6 < 120) { + this->unk_1C6 += 4; + } + + if (this->unk_1C8 < 230) { + this->unk_1C8 += 4; + return; + } + + this->dyna.actor.parent = NULL; + if (func_808B849C(this, globalCtx)) { + this->unk_202 = 1; + DoorWarp1_SetupAction(this, func_808B9CE8); + } else { + DoorWarp1_SetupAction(this, func_808B9F10); + } +} + +void func_808B9CE8(DoorWarp1* this, GlobalContext* globalCtx) { + if (this->unk_203 != 0) { + if (1) {} + return; + } + + if (!Actor_HasParent(&this->dyna.actor, globalCtx)) { + func_800B8A1C(&this->dyna.actor, globalCtx, func_808B849C(this, globalCtx) + 84, 30.0f, 80.0f); + return; + } + + switch (globalCtx->sceneNum) { + case SCENE_MITURIN_BS: + gSaveContext.roomInf[126][3] = + (((void)0, gSaveContext.roomInf[126][3]) & 0xFFFFFF00) | (((u8)gSaveContext.roomInf[126][4]) & 0xFF); + break; + + case SCENE_HAKUGIN_BS: + gSaveContext.roomInf[126][3] = (((void)0, gSaveContext.roomInf[126][3]) & 0xFFFF00FF) | + ((((u8)gSaveContext.roomInf[126][4]) & 0xFF) << 8); + break; + + case SCENE_INISIE_BS: + gSaveContext.roomInf[126][3] = (((void)0, gSaveContext.roomInf[126][3]) & 0xFF00FFFF) | + ((((u8)gSaveContext.roomInf[126][4]) & 0xFF) << 0x10); + break; + + case SCENE_SEA_BS: + gSaveContext.roomInf[126][3] = (((void)0, gSaveContext.roomInf[126][3]) & 0x00FFFFFF) | + ((((u8)gSaveContext.roomInf[126][4]) & 0xFF) << 0x18); + break; + } + + gSaveContext.roomInf[126][4] = + (gSaveContext.roomInf[126][4] & 0xFFFFFF00) | ((((u8)gSaveContext.roomInf[126][4]) + 1) & 0xFF); + Item_Give(globalCtx, func_808B849C(this, globalCtx) + (ITEM_REMAINS_ODOLWA - 1)); + DoorWarp1_SetupAction(this, func_808B9E94); +} + +void func_808B9E94(DoorWarp1* this, GlobalContext* globalCtx) { + if (func_80152498(&globalCtx->msgCtx) == 2) { + this->unk_1CE = 110; + DoorWarp1_SetupAction(this, func_808B9ED8); + } +} + +void func_808B9ED8(DoorWarp1* this, GlobalContext* globalCtx) { + this->unk_1CE--; + if (this->unk_1CE <= 0) { + func_808BA10C(this, globalCtx); + } +} + +void func_808B9F10(DoorWarp1* this, GlobalContext* globalCtx) { + Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_WARP_HOLE - SFX_FLAG); + if ((this->unk_203 == 0) && func_808B866C(this, globalCtx) && !func_801690CC(globalCtx) && (this->unk_203 == 0)) { + Player* player = GET_PLAYER(globalCtx); + + Interface_ChangeAlpha(1); + func_800B7298(globalCtx, &this->dyna.actor, 9); + player->unk_3A0.x = this->dyna.actor.world.pos.x; + player->unk_3A0.z = this->dyna.actor.world.pos.z; + this->unk_1CA = 20; + DoorWarp1_SetupAction(this, func_808B9FD0); + } +} + +void func_808B9FD0(DoorWarp1* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Player* player2 = GET_PLAYER(globalCtx); + + if (this->unk_1CA != 0) { + this->unk_1CA--; + return; + } + + if (!ActorCutscene_GetCanPlayNext(globalCtx->unk_1879C[9])) { + ActorCutscene_SetIntentToPlay(globalCtx->unk_1879C[9]); + } else { + ActorCutscene_Start(globalCtx->unk_1879C[9], NULL); + func_801A5CFC(NA_SE_EV_LINK_WARP, &player->actor.projectedPos, 4, &D_801DB4B0, &D_801DB4B0, &D_801DB4B8); + Animation_ChangeImpl(&this->skelAnime, &object_warp1_Anim_001374, 1.0f, + Animation_GetLastFrame(&object_warp1_Anim_001374.common), + Animation_GetLastFrame(&object_warp1_Anim_001374.common), 2, 40.0f, 1); + this->unk_1CA = 50; + D_808BC004 = player2->actor.world.pos.y; + DoorWarp1_SetupAction(this, func_808BA550); + } +} + +void func_808BA10C(DoorWarp1* this, GlobalContext* globalCtx) { + s32 phi_v0_2; + u8 phi_a0; + s32 phi_v0_3; + + if ((globalCtx->sceneNum == SCENE_MITURIN_BS) || (globalCtx->sceneNum == SCENE_HAKUGIN_BS) || + (globalCtx->sceneNum == SCENE_INISIE_BS) || (globalCtx->sceneNum == SCENE_SEA_BS)) { + D_801F4DE2 = globalCtx->sceneNum; + if (globalCtx->sceneNum == SCENE_MITURIN_BS) { + phi_v0_2 = 0; + } else if (globalCtx->sceneNum == SCENE_HAKUGIN_BS) { + phi_v0_2 = 1; + } else if (globalCtx->sceneNum == SCENE_INISIE_BS) { + phi_v0_2 = 2; + } else if (globalCtx->sceneNum == SCENE_SEA_BS) { + phi_v0_2 = 3; + } else { + phi_v0_2 = 0; + } + + if (this->unk_202 != 0) { + if (phi_v0_2 > 0) { + gSaveContext.weekEventReg[7] |= 0x80; + } + + switch (phi_v0_2) { + case 0: + phi_a0 = gSaveContext.roomInf[126][3] & 0xFF; + break; + + case 1: + phi_a0 = (gSaveContext.roomInf[126][3] & 0xFF00) >> 8; + break; + + case 2: + phi_a0 = (gSaveContext.roomInf[126][3] & 0xFF0000) >> 0x10; + break; + + case 3: + phi_a0 = (gSaveContext.roomInf[126][3] & 0xFF000000) >> 0x18; + break; + + default: + phi_a0 = 0; + break; + } + + switch (phi_a0) { + case 0: + phi_v0_3 = 10; + break; + + case 1: + phi_v0_3 = 0; + break; + + case 2: + phi_v0_3 = 1; + break; + + case 3: + phi_v0_3 = 2; + break; + + default: + phi_v0_3 = 10; + break; + } + + globalCtx->nextEntranceIndex = 0xCC00; + if (phi_v0_3 < 10) { + gSaveContext.nextCutsceneIndex = phi_v0_3 + 0xFFF0; + } + + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 3; + gSaveContext.nextTransition = 3; + } else { + switch (phi_v0_2) { + case 0: + if (gSaveContext.weekEventReg[20] & 2) { + gSaveContext.weekEventReg[7] |= 0x80; + globalCtx->nextEntranceIndex = 0x3010; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 3; + gSaveContext.nextTransition = 3; + } else { + globalCtx->nextEntranceIndex = 0x8600; + gSaveContext.nextCutsceneIndex = 0xFFF0; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 3; + gSaveContext.nextTransition = 3; + } + break; + + case 1: + gSaveContext.weekEventReg[33] |= 0x80; + globalCtx->nextEntranceIndex = 0xAE70; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 3; + gSaveContext.nextTransition = 3; + break; + + case 3: + if (gSaveContext.weekEventReg[55] & 0x80) { + globalCtx->nextEntranceIndex = 0x6A90; + gSaveContext.nextCutsceneIndex = 0xFFF0; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 3; + gSaveContext.nextTransition = 3; + } else { + gSaveContext.weekEventReg[55] |= 0x80; + globalCtx->nextEntranceIndex = 0x6A80; + gSaveContext.nextCutsceneIndex = 0xFFF0; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 3; + gSaveContext.nextTransition = 3; + } + break; + + case 2: + gSaveContext.weekEventReg[52] |= 0x20; + globalCtx->nextEntranceIndex = 0x20F0; + gSaveContext.nextCutsceneIndex = 0xFFF2; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 3; + gSaveContext.nextTransition = 3; + break; + } + } + } else if (DOORWARP1_GET_FF00_1(&this->dyna.actor) != 0xFF) { + if (DOORWARP1_GET_FF(&this->dyna.actor) == ENDOORWARP1_FF_6) { + gSaveContext.respawnFlag = ~1; + } + globalCtx->nextEntranceIndex = globalCtx->setupExitList[DOORWARP1_GET_FF00_3(&this->dyna.actor)]; + Scene_SetExitFade(globalCtx); + globalCtx->sceneLoadFlag = 0x14; + } else { + func_80169FDC(globalCtx); + } +} + +void func_808BA550(DoorWarp1* this, GlobalContext* globalCtx) { + Player* player2 = GET_PLAYER(globalCtx); + Player* player = GET_PLAYER(globalCtx); + s16 i; + s32 temp_f16; + f32 temp_f0; + f32 temp_f2; + s32 temp; + s32 tempS; + + if (this->unk_1CA != 0) { + this->unk_1CA--; + } + + if (this->unk_1CA < 0x1F) { + temp_f0 = 0.0f; + switch (player2->transformation) { + case PLAYER_FORM_FIERCE_DEITY: + temp_f0 = -37.0f; + break; + + case PLAYER_FORM_GORON: + temp_f0 = -37.0f; + break; + + case PLAYER_FORM_ZORA: + temp_f0 = -37.0f; + break; + + case PLAYER_FORM_DEKU: + temp_f0 = -20.0f; + break; + + case PLAYER_FORM_HUMAN: + temp_f0 = -25.0f; + break; + } + + temp_f2 = this->dyna.actor.world.pos.y + (this->dyna.actor.shape.yOffset * 0.1f) + temp_f0; + + if (D_808BC004 < temp_f2) { + player->actor.world.pos.y = temp_f2; + } + + if (this->unk_1CA <= 0) { + if (this->unk_1CC < 4000) { + this->unk_1CC += 40; + } + player->actor.world.rot.y -= this->unk_1CC; + player->actor.shape.rot.y -= this->unk_1CC; + } + Math_SmoothStepToF(&player->actor.world.pos.x, this->dyna.actor.world.pos.x, 0.5f, 0.1f, 0.01f); + Math_SmoothStepToF(&player->actor.world.pos.z, this->dyna.actor.world.pos.z, 0.5f, 0.1f, 0.01f); + } + + this->unk_1D0++; + if ((D_808BC000 < this->unk_1D0) && (gSaveContext.nextCutsceneIndex == 0xFFEF)) { + func_808BA10C(this, globalCtx); + } + + if (this->unk_1D0 > 140) { + globalCtx->envCtx.unk_E5 = 1; + temp_f0 = (this->unk_1D0 - 140) / 20.0f; + if (temp_f0 > 1.0f) { + temp_f0 = 1.0f; + } + globalCtx->envCtx.unk_E6[0] = 160; + globalCtx->envCtx.unk_E6[1] = 160; + globalCtx->envCtx.unk_E6[2] = 160; + globalCtx->envCtx.unk_E6[3] = 255.0f * temp_f0; + } + + Lights_PointNoGlowSetInfo(&this->unk_1E0, player->actor.world.pos.x + 10.0f, player->actor.world.pos.y + 10.0f, + player->actor.world.pos.z + 10.0f, 235, 255, 255, 255); + Lights_PointNoGlowSetInfo(&this->unk_1F4, player->actor.world.pos.x - 10.0f, player->actor.world.pos.y - 10.0f, + player->actor.world.pos.z - 10.0f, 235, 255, 255, 255); + Math_SmoothStepToF(&this->dyna.actor.shape.yOffset, 800.0f, 0.2f, 15.0f, 0.01f); + this->dyna.actor.shape.rot.y += 0x320; + Math_SmoothStepToF(&this->unk_1BC, 1.13f, 0.2f, 0.1f, 0.01f); + Math_StepToF(&this->unk_1A4, 2.0f, 0.003f); + Math_StepToF(&this->unk_1A8, 10.0f, 0.006f); + Math_SmoothStepToF(&this->unk_1B0, 0.0f, 0.2f, 3.0f, 0.01f); + Math_SmoothStepToF(&this->unk_1B4, 0.0f, 0.2f, 2.0f, 0.01f); + Math_SmoothStepToF(&this->unk_1B8, 255.0f, 0.1f, 1.0f, 0.01f); + + tempS = D_808BC000; + if (1) {} + temp_f0 = 1.0f - ((f32)(D_808BC000 - this->unk_1D0) / ((D_808BC000 - tempS) + 100)); + if (temp_f0 > 0.0f) { + temp_f16 = -255.0f * temp_f0; + + for (i = 0; i < 3; i++) { + globalCtx->envCtx.unk_8C.diffuseColor1[i] = temp_f16; + globalCtx->envCtx.unk_8C.fogColor[i] = temp_f16; + globalCtx->envCtx.unk_8C.ambientColor[i] = temp_f16; + } + + globalCtx->envCtx.unk_8C.fogNear = -500.0f * temp_f0; + if (globalCtx->envCtx.unk_8C.fogNear < -300) { + globalCtx->roomCtx.currRoom.segment = NULL; + } + } +} + +void func_808BAAF4(DoorWarp1* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 cutscene; + f32 phi_f2; + + phi_f2 = 200.0f; + if (globalCtx->sceneNum == SCENE_SEA) { + phi_f2 = 85.0f; + } + + if (!(gSaveContext.weekEventReg[86] & 0x80) && (fabsf(this->dyna.actor.xzDistToPlayer) < phi_f2) && + ((player->actor.world.pos.y - 20.0f) < this->dyna.actor.world.pos.y) && + (this->dyna.actor.world.pos.y < (player->actor.world.pos.y + 20.0f))) { + cutscene = this->dyna.actor.cutscene; + + if (ActorCutscene_GetCanPlayNext(cutscene)) { + ActorCutscene_Start(cutscene, &this->dyna.actor); + gSaveContext.weekEventReg[86] |= 0x80; + DoorWarp1_SetupAction(this, func_808BABF4); + } else { + ActorCutscene_SetIntentToPlay(cutscene); + } + } +} + +void func_808BABF4(DoorWarp1* this, GlobalContext* globalCtx) { +} + +void DoorWarp1_Update(Actor* thisx, GlobalContext* globalCtx) { + DoorWarp1* this = THIS; + + if (this->unk_203 == 0) { + this->unk_204 = 1.0f; + } + + if ((this->unk_1A0 != NULL) && (this->unk_1A0->unk_15C != this->unk_204)) { + this->unk_1A0->actor.world.pos.y = this->dyna.actor.world.pos.y; + this->unk_1A0->unk_158 = this->dyna.actor.world.pos.y; + this->unk_1A0->unk_15C = this->unk_204; + } + + this->actionFunc(this, globalCtx); + + if (DOORWARP1_GET_FF(&this->dyna.actor) < ENDOORWARP1_FF_2) { + Actor_SetScale(&this->dyna.actor, this->unk_1C4 / 100.0f); + } +} + +void func_808BACCC(DoorWarp1* this, GlobalContext* globalCtx) { + s32 pad; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + gDPSetPrimColor(POLY_XLU_DISP++, 0xFF, 0xFF, 200, 255, 255, (u8)this->unk_1B8); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 100, 255, (u8)this->unk_1B8); + + POLY_XLU_DISP = SkelAnime_Draw(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, NULL, NULL, + &this->dyna.actor, POLY_XLU_DISP); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + SkelAnime_Update(&this->skelAnime); +} + +void func_808BAE9C(DoorWarp1* this, GlobalContext* globalCtx) { + s32 pad; + s32 pad2; + s32 sp94 = globalCtx->state.frames * 10; + f32 sp90; + f32 sp8C; + f32 phi_f12; + f32 sp84; + + if (this->unk_1A4 >= 1.0f) { + sp90 = 0.0f; + } else { + sp90 = 1.0f - this->unk_1A4; + } + + if (this->unk_1A8 >= 1.0f) { + sp8C = 0.0f; + } else { + sp8C = 1.0f - this->unk_1A8; + } + + OPEN_DISPS(globalCtx->state.gfxCtx); + + sp84 = 1.0f - ((2.0f - this->unk_1A4) / 1.7f); + this->unk_1AC += sp84 * 15.0f; + func_8012C2DC(globalCtx->state.gfxCtx); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255.0f * sp84, 255, 255, (u8)this->unk_1B4); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 255.0f * sp84, 255, 255); + + Matrix_InsertTranslation(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y + 1.0f, + this->dyna.actor.world.pos.z, MTXMODE_NEW); + phi_f12 = 1.0f; + if (this->unk_203 != 0) { + phi_f12 = this->unk_204 * phi_f12; + } + Matrix_Scale(phi_f12, phi_f12, phi_f12, MTXMODE_APPLY); + + gSPSegment(POLY_XLU_DISP++, 0x0A, Matrix_NewMtx(globalCtx->state.gfxCtx)); + Matrix_StatePush(); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, sp94 & 0xFF, -((s16)(2.0f * this->unk_1AC) & 0x1FF), 0x100, + 0x100, 1, sp94 & 0xFF, -((s16)(2.0f * this->unk_1AC) & 0x1FF), 0x100, 0x100)); + + Matrix_InsertTranslation(0.0f, this->unk_1A4 * 230.0f, 0.0f, MTXMODE_APPLY); + Matrix_Scale(((this->unk_1C6 * sp90) / 100.0f) + 1.0f, 1.0f, ((this->unk_1C6 * sp90) / 100.0f) + 1.0f, + MTXMODE_APPLY); + + gSPSegment(POLY_XLU_DISP++, 0x09, Matrix_NewMtx(globalCtx->state.gfxCtx)); + gSPDisplayList(POLY_XLU_DISP++, object_warp1_DL_0001A0); + + Matrix_StatePop(); + + if (this->unk_1B0 > 0.0f) { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255.0f * sp84, 255, 255, (u8)this->unk_1B0); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 255.0f * sp84, 255, 255); + + sp94 *= 2; + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, sp94 & 0xFF, -((s16)this->unk_1AC & 0x1FF), 0x100, + 0x100, 1, sp94 & 0xFF, -((s16)this->unk_1AC & 0x1FF), 0x100, 0x100)); + + Matrix_InsertTranslation(0.0f, this->unk_1A8 * 60.0f, 0.0f, MTXMODE_APPLY); + Matrix_Scale(((this->unk_1C8 * sp8C) / 100.0f) + 1.0f, 1.0f, ((this->unk_1C8 * sp8C) / 100.0f) + 1.0f, + MTXMODE_APPLY); + + gSPSegment(POLY_XLU_DISP++, 0x09, Matrix_NewMtx(globalCtx->state.gfxCtx)); + gSPDisplayList(POLY_XLU_DISP++, object_warp1_DL_0001A0); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_808BB4C4(DoorWarp1* this, GlobalContext* globalCtx) { + func_800BDFC0(globalCtx, object_warp1_DL_0076C0); +} + +#ifdef NON_MATCHING +// GraphicsContext should be compiler-managed? +void func_808BB4F4(DoorWarp1* this, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + GraphicsContext* gfxCtx; + Color_RGB8 sp64[] = { + { 50, 150, 0 }, + { 100, 150, 200 }, + { 0, 50, 200 }, + { 120, 150, 0 }, + }; + s32 sp60 = 0; + + if (this->unk_1D4 != 0) { + Matrix_InsertTranslation(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y + this->unk_1A4, + this->dyna.actor.world.pos.z, MTXMODE_NEW); + Matrix_Scale(4.0f, this->unk_1AC, 4.0f, MTXMODE_APPLY); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_warp1_Matanimheader_0044D8)); + func_800BE03C(globalCtx, object_warp1_DL_003230); + return; + } + + if (globalCtx->sceneNum != SCENE_MITURIN) { + if (globalCtx->sceneNum == SCENE_HAKUGIN) { + sp60 = 1; + } else if (globalCtx->sceneNum == SCENE_SEA) { + sp60 = 2; + } else if (globalCtx->sceneNum == SCENE_INISIE_R) { + sp60 = 3; + } + } + + Matrix_InsertTranslation(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, + MTXMODE_NEW); + Matrix_RotateY(this->dyna.actor.world.rot.y, MTXMODE_APPLY); + Matrix_Scale(1.0f, this->unk_1A8, 1.0f, MTXMODE_APPLY); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_warp1_Matanimheader_0057D8)); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + gDPSetEnvColor(POLY_XLU_DISP++, sp64[sp60].r, sp64[sp60].g, sp64[sp60].b, 255); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, 255); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_warp1_DL_004690); + gfxCtx = globalCtx->state.gfxCtx; + + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_warp1_Matanimheader_007238)); + Matrix_InsertTranslation(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, + MTXMODE_NEW); + Matrix_RotateY(this->dyna.actor.world.rot.y, MTXMODE_APPLY); + Matrix_Scale(1.0f, 0.0f, 1.0f, MTXMODE_APPLY); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + OPEN_DISPS(gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + gDPSetEnvColor(POLY_XLU_DISP++, sp64[sp60].r, sp64[sp60].g, sp64[sp60].b, 255); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, this->unk_203); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_warp1_DL_0058C8); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} +#else +static Color_RGB8 D_808BBB50[] = { + { 50, 150, 0 }, + { 100, 150, 200 }, + { 0, 50, 200 }, + { 120, 150, 0 }, +}; +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808BB4F4.s") #endif -extern UNK_TYPE D_060001A0; -extern UNK_TYPE D_06001374; -extern UNK_TYPE D_060044D8; -extern UNK_TYPE D_060076C0; -extern UNK_TYPE D_06008BD4; +void DoorWarp1_Draw(Actor* thisx, GlobalContext* globalCtx) { + DoorWarp1* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/DoorWarp1_SetupAction.s") + switch (DOORWARP1_GET_FF(&this->dyna.actor)) { + case ENDOORWARP1_FF_0: + func_808BAE9C(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B849C.s") + case ENDOORWARP1_FF_1: + func_808BACCC(this, globalCtx); + func_808BAE9C(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B8568.s") + case ENDOORWARP1_FF_2: + case ENDOORWARP1_FF_3: + case ENDOORWARP1_FF_4: + case ENDOORWARP1_FF_5: + func_808BB4C4(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B866C.s") + case ENDOORWARP1_FF_6: + func_808BB4F4(this, globalCtx); + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/DoorWarp1_Init.s") +#ifdef NON_MATCHING +// casting/macro on temp_s1/s0 +void func_808BB8D4(DoorWarp1* this, GlobalContext* globalCtx, s32 arg2) { + static Vec3f D_808BBB5C = { 0.0f, 0.05f, 0.0f }; + static Vec3f D_808BBB68 = { 0.0f, 0.25f, 0.0f }; + Vec3f sp9C; + Color_RGBA8 sp98; + Color_RGBA8 sp94; + s32 i; + s16 temp_s0; + s32 temp_s1; + s32 phi_s2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/DoorWarp1_Destroy.s") + for (i = 0; i < arg2; i++) { + temp_s1 = (Rand_ZeroOne() * 0x10000); + temp_s0 = temp_s1 - 0x8000; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B8924.s") + sp9C.x = (-Math_SinS(temp_s0) * 35.0f) + this->dyna.actor.world.pos.x; + sp9C.y = this->dyna.actor.world.pos.y; + temp_s0 = (s16)(temp_s1 - 0x8000); + sp9C.z = Math_CosS(temp_s0) * 35.0f + this->dyna.actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B8A7C.s") + D_808BBB5C.x = 0.0f; + D_808BBB68.y = 0.25f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B8C48.s") + sp98.r = 255; + sp98.g = 255; + sp98.b = 255; + sp94.r = 200; + sp94.g = 200; + sp94.b = 255; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B8E78.s") + D_808BBB5C.z = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B900C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B9094.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B90CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B921C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B93A0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B94A4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B9524.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B958C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B96A0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B96B0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B977C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B9840.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B98A8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B9B30.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B9BE8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B9CE8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B9E94.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B9ED8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B9F10.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808B9FD0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808BA10C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808BA550.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808BAAF4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808BABF4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/DoorWarp1_Update.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808BACCC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808BAE9C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808BB4C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808BB4F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/DoorWarp1_Draw.s") + temp_s1 = (s16)((Rand_ZeroOne() * 1000.0f) + 800.0f); + phi_s2 = 27; + if (arg2 >= 2) { + phi_s2 = 8; + D_808BBB68.y = 1.8f; + D_808BBB5C.x = -Math_SinS(temp_s0) * 5.0f; + D_808BBB5C.z = Math_CosS(temp_s0) * 5.0f; + } + EffectSsKiraKira_SpawnDispersed(globalCtx, &sp9C, &D_808BBB5C, &D_808BBB68, &sp98, &sp94, temp_s1, phi_s2); + } +} +#else +static Vec3f D_808BBB5C = { 0.0f, 0.05f, 0.0f }; +static Vec3f D_808BBB68 = { 0.0f, 0.25f, 0.0f }; #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Door_Warp1/func_808BB8D4.s") +#endif diff --git a/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.h b/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.h index e7b67312e..ca177006b 100644 --- a/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.h +++ b/src/overlays/actors/ovl_Door_Warp1/z_door_warp1.h @@ -2,19 +2,58 @@ #define Z_DOOR_WARP1_H #include "global.h" +#include "overlays/actors/ovl_Dm_Hina/z_dm_hina.h" struct DoorWarp1; typedef void (*DoorWarp1ActionFunc)(struct DoorWarp1*, GlobalContext*); +#define DOORWARP1_GET_FF(thisx) ((thisx)->params & 0xFF) +#define DOORWARP1_GET_FF00_1(thisx) (((thisx)->params >> 8) & 0xFF) +#define DOORWARP1_GET_FF00_2(thisx) ((thisx)->params & 0xFF00) +#define DOORWARP1_GET_FF00_3(thisx) ((thisx)->params >> 8) + +enum { + /* 0 */ ENDOORWARP1_FF_0, + /* 1 */ ENDOORWARP1_FF_1, + /* 2 */ ENDOORWARP1_FF_2, + /* 3 */ ENDOORWARP1_FF_3, + /* 4 */ ENDOORWARP1_FF_4, + /* 5 */ ENDOORWARP1_FF_5, + /* 6 */ ENDOORWARP1_FF_6, +}; + typedef struct DoorWarp1 { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x94]; + /* 0x0000 */ DynaPolyActor dyna; + /* 0x015C */ SkelAnime skelAnime; + /* 0x01A0 */ DmHina* unk_1A0; + /* 0x01A4 */ f32 unk_1A4; + /* 0x01A8 */ f32 unk_1A8; + /* 0x01AC */ f32 unk_1AC; + /* 0x01B0 */ f32 unk_1B0; + /* 0x01B4 */ f32 unk_1B4; + /* 0x01B8 */ f32 unk_1B8; + /* 0x01BC */ f32 unk_1BC; + /* 0x01C0 */ f32 unk_1C0; + /* 0x01C4 */ s16 unk_1C4; + /* 0x01C6 */ s16 unk_1C6; + /* 0x01C8 */ s16 unk_1C8; + /* 0x01CA */ s16 unk_1CA; + /* 0x01CC */ s16 unk_1CC; + /* 0x01CE */ s16 unk_1CE; + /* 0x01D0 */ u16 unk_1D0; + /* 0x01D2 */ s8 unk_1D2; + /* 0x01D3 */ u8 unk_1D3; + /* 0x01D4 */ u8 unk_1D4; /* 0x01D8 */ DoorWarp1ActionFunc actionFunc; - /* 0x01DC */ char unk_1DC[0x27]; + /* 0x01DC */ LightNode* unk_1DC; + /* 0x01E0 */ LightInfo unk_1E0; + /* 0x01F0 */ LightNode* unk_1F0; + /* 0x01F4 */ LightInfo unk_1F4; + /* 0x0202 */ u8 unk_202; /* 0x0203 */ u8 unk_203; /* 0x0204 */ f32 unk_204; - /* 0x0208 */ char unk_208[0x4]; + /* 0x0208 */ u8 unk_208; } DoorWarp1; // size = 0x20C extern const ActorInit Door_Warp1_InitVars; diff --git a/src/overlays/actors/ovl_Eff_Change/z_eff_change.c b/src/overlays/actors/ovl_Eff_Change/z_eff_change.c index 339a08076..45a62ed72 100644 --- a/src/overlays/actors/ovl_Eff_Change/z_eff_change.c +++ b/src/overlays/actors/ovl_Eff_Change/z_eff_change.c @@ -1,7 +1,7 @@ /* * File: z_eff_change.c * Overlay: ovl_Eff_Change - * Description: + * Description: Elegy of Emptiness - Beam of Light When Creating Statue */ #include "z_eff_change.h" diff --git a/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c b/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c index 3ca55d7b8..296d6e429 100644 --- a/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c +++ b/src/overlays/actors/ovl_Eff_Dust/z_eff_dust.c @@ -1,5 +1,5 @@ /* - * File z_eff_dust.c + * File: z_eff_dust.c * Overlay: ovl_Eff_Dust * Description: Dust effects */ @@ -288,7 +288,7 @@ void func_80919768(Actor* thisx, GlobalContext* globalCtx2) { initialPositions->z * ((this->dz * aux) + (1.0f - this->dz)), MTXMODE_APPLY); Matrix_Scale(this->scalingFactor, this->scalingFactor, this->scalingFactor, MTXMODE_APPLY); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); @@ -345,7 +345,7 @@ void func_809199FC(Actor* thisx, GlobalContext* globalCtx2) { Matrix_Scale(*distanceTraveled * this->scalingFactor, *distanceTraveled * this->scalingFactor, *distanceTraveled * this->scalingFactor, MTXMODE_APPLY); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPClearGeometryMode(POLY_XLU_DISP++, G_FOG | G_LIGHTING); diff --git a/src/overlays/actors/ovl_Eff_Kamejima_Wave/z_eff_kamejima_wave.c b/src/overlays/actors/ovl_Eff_Kamejima_Wave/z_eff_kamejima_wave.c index 7b982d25c..faea4c4e4 100644 --- a/src/overlays/actors/ovl_Eff_Kamejima_Wave/z_eff_kamejima_wave.c +++ b/src/overlays/actors/ovl_Eff_Kamejima_Wave/z_eff_kamejima_wave.c @@ -1,5 +1,5 @@ /* - * File z_eff_kamejima_wave.c + * File: z_eff_kamejima_wave.c * Overlay: ovl_Eff_Kamejima_Wave * Description: Wave Created by Turtle Awakening */ diff --git a/src/overlays/actors/ovl_Eff_Lastday/z_eff_lastday.c b/src/overlays/actors/ovl_Eff_Lastday/z_eff_lastday.c index 7812faa9b..4f9138aa7 100644 --- a/src/overlays/actors/ovl_Eff_Lastday/z_eff_lastday.c +++ b/src/overlays/actors/ovl_Eff_Lastday/z_eff_lastday.c @@ -1,5 +1,5 @@ /* - * File z_eff_lastday.c + * File: z_eff_lastday.c * Overlay: ovl_Eff_Lastday * Description: Moon Crash Cutscene Fire Wall */ diff --git a/src/overlays/actors/ovl_Eff_Stk/z_eff_stk.c b/src/overlays/actors/ovl_Eff_Stk/z_eff_stk.c index dcc61493a..b02e52e57 100644 --- a/src/overlays/actors/ovl_Eff_Stk/z_eff_stk.c +++ b/src/overlays/actors/ovl_Eff_Stk/z_eff_stk.c @@ -1,5 +1,5 @@ /* - * File z_eff_stk.c + * File: z_eff_stk.c * Overlay: ovl_Eff_Stk * Description: Skullkid Effects (calling down moon / cursing Link) */ diff --git a/src/overlays/actors/ovl_Eff_Zoraband/z_eff_zoraband.c b/src/overlays/actors/ovl_Eff_Zoraband/z_eff_zoraband.c index 6ffafb311..6da3885be 100644 --- a/src/overlays/actors/ovl_Eff_Zoraband/z_eff_zoraband.c +++ b/src/overlays/actors/ovl_Eff_Zoraband/z_eff_zoraband.c @@ -1,7 +1,7 @@ /* - * File z_eff_zoraband.c + * File: z_eff_zoraband.c * Overlay: ovl_Eff_Zoraband - * Description: + * Description: Indigo-Go's (Mikau's healing cutscene) */ #include "z_eff_zoraband.h" diff --git a/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c b/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c index 7c7a39a2c..d3d0317ae 100644 --- a/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c +++ b/src/overlays/actors/ovl_Elf_Msg/z_elf_msg.c @@ -1,5 +1,5 @@ /* - * File z_elf_msg.c + * File: z_elf_msg.c * Overlay: ovl_Elf_Msg * Description: Tatl Hint (proximity-activated C-up hint?) */ diff --git a/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.c b/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.c index 014f61c43..ece5b9a5c 100644 --- a/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.c +++ b/src/overlays/actors/ovl_Elf_Msg2/z_elf_msg2.c @@ -1,5 +1,5 @@ /* - * File z_elf_msg2.c + * File: z_elf_msg2.c * Overlay: ovl_Elf_Msg2 * Description: Tatl Hint (Z-target-activated C-up hint?) */ diff --git a/src/overlays/actors/ovl_Elf_Msg3/z_elf_msg3.c b/src/overlays/actors/ovl_Elf_Msg3/z_elf_msg3.c index 6e84cccf2..95942b815 100644 --- a/src/overlays/actors/ovl_Elf_Msg3/z_elf_msg3.c +++ b/src/overlays/actors/ovl_Elf_Msg3/z_elf_msg3.c @@ -1,5 +1,5 @@ /* - * File z_elf_msg3.c + * File: z_elf_msg3.c * Overlay: ovl_Elf_Msg3 * Description: Tatl Message (Proximity-activated dialogue?) */ diff --git a/src/overlays/actors/ovl_Elf_Msg4/z_elf_msg4.c b/src/overlays/actors/ovl_Elf_Msg4/z_elf_msg4.c index eefe99063..c55591fba 100644 --- a/src/overlays/actors/ovl_Elf_Msg4/z_elf_msg4.c +++ b/src/overlays/actors/ovl_Elf_Msg4/z_elf_msg4.c @@ -1,5 +1,5 @@ /* - * File z_elf_msg4.c + * File: z_elf_msg4.c * Overlay: ovl_Elf_Msg4 * Description: Tatl Hint (another proximity-activated C-up hint?) */ diff --git a/src/overlays/actors/ovl_Elf_Msg5/z_elf_msg5.c b/src/overlays/actors/ovl_Elf_Msg5/z_elf_msg5.c index 371fa7f22..3fc56c89b 100644 --- a/src/overlays/actors/ovl_Elf_Msg5/z_elf_msg5.c +++ b/src/overlays/actors/ovl_Elf_Msg5/z_elf_msg5.c @@ -1,5 +1,5 @@ /* - * File z_elf_msg5.c + * File: z_elf_msg5.c * Overlay: ovl_Elf_Msg5 * Description: Tatl Message (Another proximity-activated dialogue?) */ diff --git a/src/overlays/actors/ovl_Elf_Msg6/z_elf_msg6.c b/src/overlays/actors/ovl_Elf_Msg6/z_elf_msg6.c index ea9e79df6..ecd927765 100644 --- a/src/overlays/actors/ovl_Elf_Msg6/z_elf_msg6.c +++ b/src/overlays/actors/ovl_Elf_Msg6/z_elf_msg6.c @@ -1,5 +1,5 @@ /* - * File z_elf_msg6.c + * File: z_elf_msg6.c * Overlay: ovl_Elf_Msg6 * Description: Tatl Hint (another proximity-activated C-up hint?) */ diff --git a/src/overlays/actors/ovl_En_Ah/z_en_ah.c b/src/overlays/actors/ovl_En_Ah/z_en_ah.c index da7721152..19a2aaf2d 100644 --- a/src/overlays/actors/ovl_En_Ah/z_en_ah.c +++ b/src/overlays/actors/ovl_En_Ah/z_en_ah.c @@ -1,5 +1,5 @@ /* - * File z_en_ah.c + * File: z_en_ah.c * Overlay: ovl_En_Ah * Description: Anju's Mother */ diff --git a/src/overlays/actors/ovl_En_Akindonuts/z_en_akindonuts.c b/src/overlays/actors/ovl_En_Akindonuts/z_en_akindonuts.c index 191b35ec9..4010b1e12 100644 --- a/src/overlays/actors/ovl_En_Akindonuts/z_en_akindonuts.c +++ b/src/overlays/actors/ovl_En_Akindonuts/z_en_akindonuts.c @@ -1,10 +1,11 @@ /* - * File z_en_akindonuts.c + * File: z_en_akindonuts.c * Overlay: ovl_En_Akindonuts - * Description: Woodfall - Business Scrub + * Description: Trade quest Business Scrubs */ #include "z_en_akindonuts.h" +#include "objects/object_dnt/object_dnt.h" #define FLAGS 0x00000039 @@ -15,7 +16,21 @@ void EnAkindonuts_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnAkindonuts_Update(Actor* thisx, GlobalContext* globalCtx); void EnAkindonuts_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80BEEDC0(EnAkindonuts* this, GlobalContext* globalCtx); +void func_80BEEE10(EnAkindonuts* this, GlobalContext* globalCtx); +void func_80BEEFA8(EnAkindonuts* this, GlobalContext* globalCtx); +void func_80BEF18C(EnAkindonuts* this, GlobalContext* globalCtx); +void func_80BEF20C(EnAkindonuts* this, GlobalContext* globalCtx); +void func_80BEF360(EnAkindonuts* this, GlobalContext* globalCtx); +void func_80BEF450(EnAkindonuts* this, GlobalContext* globalCtx); +void func_80BEF4B8(EnAkindonuts* this, GlobalContext* globalCtx); +void func_80BEF518(EnAkindonuts* this, GlobalContext* globalCtx); +void func_80BEF770(EnAkindonuts* this, GlobalContext* globalCtx); +void func_80BEF83C(EnAkindonuts* this, GlobalContext* globalCtx); +void func_80BEF9F0(EnAkindonuts* this, GlobalContext* globalCtx); +void func_80BEFAF0(EnAkindonuts* this, GlobalContext* globalCtx); +void func_80BEFD74(EnAkindonuts* this, GlobalContext* globalCtx); + const ActorInit En_Akindonuts_InitVars = { ACTOR_EN_AKINDONUTS, ACTORCAT_NPC, @@ -28,113 +43,1659 @@ const ActorInit En_Akindonuts_InitVars = { (ActorFunc)EnAkindonuts_Draw, }; -// static ColliderCylinderInitType1 sCylinderInit = { -static ColliderCylinderInitType1 D_80BF02F0 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInitType1 sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 27, 32, 0, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80BF04B4[] = { +static ActorAnimationEntryS sAnimations[] = { + { &object_dnt_Anim_005488, 1.0f, 0, -1, 0, 0 }, { &object_dnt_Anim_00B0B4, 1.0f, 0, -1, 0, 0 }, + { &object_dnt_Anim_004AA0, 1.0f, 0, -1, 2, 0 }, { &object_dnt_Anim_004E38, 1.0f, 0, -1, 2, 0 }, + { &object_dnt_Anim_0029E8, 1.0f, 0, -1, 2, 0 }, { &object_dnt_Anim_005CA8, 1.0f, 0, -1, 2, 0 }, + { &object_dnt_Anim_0038CC, 1.0f, 0, -1, 0, 0 }, { &object_dnt_Anim_003CC0, 1.0f, 0, -1, 0, 0 }, + { &object_dnt_Anim_0012F4, 1.0f, 0, -1, 2, 0 }, { &object_dnt_Anim_004700, 1.0f, 0, -1, 2, 0 }, + { &object_dnt_Anim_001BC8, 1.0f, 0, -1, 0, 0 }, { &object_dnt_Anim_003438, 1.0f, 0, -1, 2, 0 }, + { &object_dnt_Anim_001E2C, 1.0f, 0, -1, 0, 0 }, { &object_dnt_Anim_000994, 1.0f, 0, -1, 0, 0 }, + { &object_dnt_Anim_002268, 1.0f, 0, -1, 2, 0 }, { &object_dnt_Anim_002F08, 1.0f, 0, -1, 0, 0 }, + { &object_dnt_Anim_00577C, 1.0f, 0, -1, 0, -4 }, { &object_dnt_Anim_0029E8, 1.0f, 8, -1, 2, 0 }, + { &object_dnt_Anim_0029E8, 1.0f, 4, -1, 2, -4 }, { &object_dnt_Anim_0029E8, 1.0f, 0, -1, 2, 0 }, + { &object_dnt_Anim_001BC8, 1.0f, 0, -1, 0, 0 }, { &object_dnt_Anim_0012F4, -1.0f, 0, -1, 2, 0 }, + { &object_dnt_Anim_002670, 1.0f, 0, -1, 2, 0 }, +}; + +static u16 D_80BF048C[] = { + 0x15E4, + 0x15F8, + 0x1609, + 0x161D, +}; + +static u16 D_80BF0494[] = { + 0x15E3, + 0x15F9, + 0x160A, + 0x161E, +}; + +static u16 D_80BF049C[] = { + 0x15E3, + 0x15F7, + 0x160C, + 0x161F, +}; + +static u16 D_80BF04A4[] = { + 0x15E3, + 0x15F7, + 0x160B, + 0x1621, +}; + +static u16 D_80BF04AC[] = { + 0x15E3, + 0x15F7, + 0x160B, + 0x1620, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_U8(targetMode, 0, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 30, ICHAIN_STOP), }; -#endif +void func_80BECBE0(EnAkindonuts* this, s16 arg1) { + f32 sp24 = Math_CosS(this->actor.world.rot.x) * this->actor.speedXZ; -extern ColliderCylinderInit D_80BF02F0; -extern InitChainEntry D_80BF04B4[]; + this->actor.velocity.x = Math_SinS(this->actor.world.rot.y) * sp24; + this->actor.velocity.y = Math_SinS(this->actor.world.rot.x) * this->actor.speedXZ; + this->actor.velocity.z = Math_CosS(this->actor.world.rot.y) * sp24; -extern UNK_TYPE D_06001350; -extern UNK_TYPE D_06005488; + if (arg1) { + this->actor.velocity.x = 0.0f; + this->actor.velocity.z = 0.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BECBE0.s") + Actor_ApplyMovement(&this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BECC7C.s") +void func_80BECC7C(EnAkindonuts* this, GlobalContext* globalCtx) { + if (this->unk_32C & 4) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BECD10.s") + if (this->unk_32C & 2) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 20.0f, 5); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BECEAC.s") +s32 func_80BECD10(EnAkindonuts* this, Path* path, s32 arg2) { + Vec3s* sp5C = Lib_SegmentedToVirtual(path->points); + s32 sp58 = path->count; + s32 idx = arg2; + s32 sp50 = false; + f32 phi_f12; + f32 phi_f14; + f32 sp44; + f32 sp40; + f32 sp3C; + Vec3f sp30; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BECF6C.s") + Math_Vec3s_ToVec3f(&sp30, &sp5C[idx]); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BECFBC.s") + if (idx == 0) { + phi_f12 = sp5C[1].x - sp5C[0].x; + phi_f14 = sp5C[1].z - sp5C[0].z; + } else if (idx == (sp58 - 1)) { + phi_f12 = sp5C[sp58 - 1].x - sp5C[sp58 - 2].x; + phi_f14 = sp5C[sp58 - 1].z - sp5C[sp58 - 2].z; + } else { + phi_f12 = sp5C[idx + 1].x - sp5C[idx - 1].x; + phi_f14 = sp5C[idx + 1].z - sp5C[idx - 1].z; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BED034.s") + func_8017B7F8(&sp30, RADF_TO_BINANG(func_80086B30(phi_f12, phi_f14)), &sp44, &sp40, &sp3C); + if (((this->actor.world.pos.x * sp44) + (sp40 * this->actor.world.pos.z) + sp3C) > 0.0f) { + sp50 = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BED090.s") + return sp50; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BED140.s") +f32 func_80BECEAC(Path* path, s32 arg1, Vec3f* pos, Vec3s* arg3) { + Vec3s* temp; + Vec3f sp20; + Vec3s* point; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BED208.s") + if (path != NULL) { + temp = Lib_SegmentedToVirtual(path->points); + point = &temp[arg1]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BED27C.s") + sp20.x = point->x; + sp20.y = point->y; + sp20.z = point->z; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BED2FC.s") + arg3->y = Math_Vec3f_Yaw(pos, &sp20); + arg3->x = Math_Vec3f_Pitch(pos, &sp20); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BED35C.s") + return sp20.y - pos->y; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BED3BC.s") +s16 func_80BECF6C(Path* path) { + Vec3s* sp34 = Lib_SegmentedToVirtual(path->points); + Vec3f sp28; + Vec3f sp1C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BED680.s") + Math_Vec3s_ToVec3f(&sp28, &sp34[0]); + Math_Vec3s_ToVec3f(&sp1C, &sp34[1]); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BED8A4.s") + return Math_Vec3f_Yaw(&sp28, &sp1C); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEDB88.s") +s32 func_80BECFBC(EnAkindonuts* this) { + switch (ENAKINDONUTS_GET_3(&this->actor)) { + case 0: + return 0x98; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEDDAC.s") + case 1: + return 0x99; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEE070.s") + case 2: + return 0x9A; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEE274.s") + case 3: + func_801149A0(ITEM_DEED_OCEAN, SLOT(ITEM_DEED_OCEAN)); + return 0x7; + } + return 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEE530.s") +s32 func_80BED034(EnAkindonuts* this) { + switch (ENAKINDONUTS_GET_3(&this->actor)) { + case 0: + return 0x35; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEE73C.s") + case 1: + return 0x1D; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEE938.s") + case 2: + return 0x5C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEEB20.s") + case 3: + return 0x5D; + } + return 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEEDC0.s") +void func_80BED090(GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEEE10.s") + if (player->transformation == PLAYER_FORM_DEKU) { + gSaveContext.weekEventReg[63] |= 0x8; + gSaveContext.weekEventReg[63] &= (u8)~0x10; + } else if (player->transformation == PLAYER_FORM_ZORA) { + gSaveContext.weekEventReg[63] &= (u8)~0x8; + gSaveContext.weekEventReg[63] |= 0x10; + } else if (player->transformation == PLAYER_FORM_GORON) { + gSaveContext.weekEventReg[63] |= 0x8; + gSaveContext.weekEventReg[63] |= 0x10; + } else if (player->transformation == PLAYER_FORM_HUMAN) { + gSaveContext.weekEventReg[63] &= (u8)~0x8; + gSaveContext.weekEventReg[63] &= (u8)~0x10; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEEFA8.s") +s32 func_80BED140(GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEF18C.s") + if (player->transformation == PLAYER_FORM_DEKU) { + if ((gSaveContext.weekEventReg[63] & 0x8) && !(gSaveContext.weekEventReg[63] & 0x10)) { + return true; + } + } else if (player->transformation == PLAYER_FORM_ZORA) { + if (!(gSaveContext.weekEventReg[63] & 0x8) && (gSaveContext.weekEventReg[63] & 0x10)) { + return true; + } + } else if (player->transformation == PLAYER_FORM_GORON) { + if ((gSaveContext.weekEventReg[63] & 0x8) && (gSaveContext.weekEventReg[63] & 0x10)) { + return true; + } + } else if (player->transformation == PLAYER_FORM_HUMAN) { + if (!(gSaveContext.weekEventReg[63] & 0x8) && !(gSaveContext.weekEventReg[63] & 0x10)) { + return true; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEF20C.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEF360.s") +s32 func_80BED208(EnAkindonuts* this) { + if (INV_CONTENT(ITEM_MAGIC_BEANS) != 10U) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEF450.s") + if (gSaveContext.rupees < 10) { + return 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEF4B8.s") + if (AMMO(ITEM_MAGIC_BEANS) >= 20) { + return 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEF518.s") + this->unk_364 = -10; + this->unk_366 = 10; + return 3; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEF770.s") +s32 func_80BED27C(EnAkindonuts* this) { + if (CUR_UPG_VALUE_VOID(UPG_BOMB_BAG) == 3) { + return 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEF83C.s") + if (CUR_UPG_VALUE_VOID(UPG_BOMB_BAG) < 2) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEF9F0.s") + if (gSaveContext.rupees < 200) { + return 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEFAF0.s") + this->unk_364 = -200; + this->unk_366 = 88; + return 3; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEFD74.s") +s32 func_80BED2FC(EnAkindonuts* this) { + if (!func_80114E90()) { + return 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/EnAkindonuts_Init.s") + if (gSaveContext.rupees < 40) { + return 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/EnAkindonuts_Destroy.s") + this->unk_364 = -40; + this->unk_366 = 20; + return 3; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/EnAkindonuts_Update.s") +s32 func_80BED35C(EnAkindonuts* this) { + if (!func_80114E90()) { + return 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BEFFB4.s") + if (gSaveContext.rupees < 100) { + return 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BF0178.s") + this->unk_364 = -100; + this->unk_366 = 21; + return 3; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/func_80BF0190.s") +void func_80BED3BC(EnAkindonuts* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Akindonuts/EnAkindonuts_Draw.s") + switch (this->unk_33C) { + case 0: + if (player->transformation != PLAYER_FORM_DEKU) { + this->unk_33C = 0x15E0; + break; + } + this->unk_33C = 0x15E7; + break; + + case 0x15E0: + this->unk_33C = 0x15E1; + break; + + case 0x15E1: + this->unk_33C = 0x15E2; + break; + + case 0x15E2: + this->unk_33C = 0xFF; + break; + + case 0x15E7: + if (!(gSaveContext.weekEventReg[61] & 0x20)) { + gSaveContext.weekEventReg[61] |= 0x20; + this->unk_33C = 0x15E8; + break; + } + this->unk_33C = 0x15E9; + break; + + case 0x15E8: + this->unk_33C = 0x15E9; + break; + + case 0x15E9: + this->unk_33C = 0x15EA; + break; + + case 0x15EA: + this->unk_32C |= 0x1; + if (this->unk_32C & 8) { + this->unk_32C &= ~8; + + switch (func_80BED208(this)) { + case 0: + play_sound(NA_SE_SY_ERROR); + this->unk_33C = 0x15EC; + break; + + case 1: + play_sound(NA_SE_SY_ERROR); + this->unk_33C = 0x15ED; + break; + + case 2: + play_sound(NA_SE_SY_ERROR); + this->unk_33C = 0x15EE; + break; + + case 3: + func_8019F208(); + this->unk_32C &= ~0x1; + this->unk_32C |= 0x40; + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_33C = 0x15EF; + this->actionFunc = func_80BEF360; + return; + } + } else if (this->unk_32C & 0x10) { + this->unk_32C &= ~0x10; + this->unk_33C = 0x15EB; + break; + } + break; + + case 0x15E4: + this->unk_33C = 0x15E5; + this->unk_32C |= 1; + break; + + case 0x15E5: + this->unk_33C = 0x15E6; + func_80BED090(globalCtx); + gSaveContext.weekEventReg[61] |= 0x10; + this->unk_32C |= 0x20; + break; + + case 0x15EF: + this->unk_32C |= 1; + break; + } + + func_801518B0(globalCtx, this->unk_33C, &this->actor); +} + +void func_80BED680(EnAkindonuts* this, GlobalContext* globalCtx) { + switch (this->unk_33C) { + case 0: + if (func_80BED140(globalCtx) && !(gSaveContext.weekEventReg[61] & 0x40)) { + gSaveContext.weekEventReg[61] |= 0x40; + this->unk_33C = 0x15F0; + break; + } + + this->unk_33C = 0x15F2; + break; + + case 0x15F0: + this->unk_33C = 0x15F1; + break; + + case 0x15F1: + case 0x15F2: + this->unk_33C = 0x15F3; + break; + + case 0x15F3: + this->unk_33C = 0x15EA; + break; + + case 0x15EA: + this->unk_32C |= 1; + if (this->unk_32C & 8) { + this->unk_32C &= ~8; + + switch (func_80BED208(this)) { + case 0: + play_sound(NA_SE_SY_ERROR); + this->unk_33C = 0x15EC; + break; + + case 1: + play_sound(NA_SE_SY_ERROR); + this->unk_33C = 0x15ED; + break; + + case 2: + play_sound(NA_SE_SY_ERROR); + this->unk_33C = 0x15EE; + break; + + case 3: + func_8019F208(); + this->unk_32C |= 0x40; + this->unk_32C &= ~0x1; + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_33C = 0x15EF; + this->actionFunc = func_80BEF360; + return; + } + } else if (this->unk_32C & 0x10) { + this->unk_32C &= ~0x10; + this->unk_33C = 0x15EB; + break; + } + break; + + case 0x15EF: + this->unk_32C |= 1; + break; + } + + func_801518B0(globalCtx, this->unk_33C, &this->actor); +} + +void func_80BED8A4(EnAkindonuts* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + switch (this->unk_33C) { + case 0: + if (player->transformation == PLAYER_FORM_DEKU) { + this->unk_33C = 0x15F4; + break; + } else if (player->transformation == PLAYER_FORM_GORON) { + this->unk_33C = 0x15FE; + break; + } + this->unk_33C = 0x15FC; + break; + + case 0x15F4: + this->unk_33C = 0x15F5; + break; + + case 0x15F5: + this->unk_33C = 0x15F6; + break; + + case 0x15F6: + this->unk_33C = 0xFF; + break; + + case 0x15FC: + this->unk_33C = 0x15FD; + this->unk_32C |= 1; + break; + + case 0x15FE: + if (!(gSaveContext.weekEventReg[62] & 1)) { + gSaveContext.weekEventReg[62] |= 1; + this->unk_33C = 0x15FF; + break; + } + this->unk_33C = 0x1600; + break; + + case 0x15FF: + this->unk_33C = 0x1600; + break; + + case 0x1600: + this->unk_33C = 0x15EA; + break; + + case 0x15EA: + this->unk_32C |= 0x1; + if (this->unk_32C & 8) { + this->unk_32C &= ~8; + + switch (func_80BED27C(this)) { + case 2: + play_sound(NA_SE_SY_ERROR); + this->unk_33C = 0x1601; + break; + + case 0: + play_sound(NA_SE_SY_ERROR); + this->unk_33C = 0x1602; + break; + + case 1: + play_sound(NA_SE_SY_ERROR); + this->unk_33C = 0x1603; + break; + + case 3: + func_8019F208(); + this->unk_32C |= 0x40; + this->unk_32C &= ~0x1; + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_33C = 0x15EF; + this->actionFunc = func_80BEF360; + return; + } + } else if (this->unk_32C & 0x10) { + this->unk_32C &= ~0x10; + this->unk_33C = 0x1604; + break; + } + break; + + case 0x15F9: + this->unk_33C = 0x15FA; + this->unk_32C |= 1; + break; + + case 0x15FA: + this->unk_33C = 0x15FB; + gSaveContext.weekEventReg[61] |= 0x80; + this->unk_32C |= 0x20; + break; + + case 0x15EF: + this->unk_32C |= 1; + break; + } + + func_801518B0(globalCtx, this->unk_33C, &this->actor); +} + +void func_80BEDB88(EnAkindonuts* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + switch (this->unk_33C) { + case 0: + if ((player->transformation == PLAYER_FORM_DEKU) && !(gSaveContext.weekEventReg[62] & 2)) { + gSaveContext.weekEventReg[62] |= 0x2; + this->unk_33C = 0x15F0; + break; + } + this->unk_33C = 0x15F2; + break; + + case 0x15F0: + this->unk_33C = 0x1605; + break; + + case 0x15F2: + case 0x1605: + this->unk_33C = 0x1606; + break; + + case 0x1606: + this->unk_33C = 0x15EA; + break; + + case 0x15EA: + this->unk_32C |= 0x1; + if (this->unk_32C & 8) { + this->unk_32C &= ~8; + + switch (func_80BED27C(this)) { + case 2: + play_sound(NA_SE_SY_ERROR); + this->unk_33C = 0x1601; + break; + + case 0: + play_sound(NA_SE_SY_ERROR); + this->unk_33C = 0x1602; + break; + + case 1: + play_sound(NA_SE_SY_ERROR); + this->unk_33C = 0x1603; + break; + + case 3: + func_8019F208(); + this->unk_32C |= 0x40; + this->unk_32C &= ~0x1; + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_33C = 0x15EF; + this->actionFunc = func_80BEF360; + return; + } + } else if (this->unk_32C & 0x10) { + this->unk_32C &= ~0x10; + this->unk_33C = 0x15EB; + break; + } + break; + + case 0x15EF: + this->unk_32C |= 1; + break; + } + + func_801518B0(globalCtx, this->unk_33C, &this->actor); +} + +void func_80BEDDAC(EnAkindonuts* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + switch (this->unk_33C) { + case 0: + if (player->transformation == PLAYER_FORM_GORON) { + this->unk_33C = 0x1607; + break; + } else if (player->transformation == PLAYER_FORM_ZORA) { + this->unk_33C = 0x1610; + break; + } + this->unk_33C = 0x160E; + break; + + case 0x1607: + this->unk_33C = 0x1608; + break; + + case 0x1608: + this->unk_33C = 0x15E2; + break; + + case 0x15E2: + this->unk_33C = 0xFF; + break; + + case 0x160E: + this->unk_33C = 0x160F; + this->unk_32C |= 1; + break; + + case 0x1610: + if (!(gSaveContext.weekEventReg[62] & 8)) { + gSaveContext.weekEventReg[62] |= 8; + this->unk_33C = 0x1611; + break; + } + this->unk_33C = 0x1612; + break; + + case 0x1611: + this->unk_33C = 0x1612; + break; + + case 0x1612: + this->unk_33C = 0x15EA; + break; + + case 0x15EA: + this->unk_32C |= 0x1; + if (this->unk_32C & 0x8) { + this->unk_32C &= ~8; + + switch (func_80BED2FC(this)) { + case 2: + play_sound(NA_SE_SY_ERROR); + this->unk_33C = 0x1613; + break; + + case 1: + play_sound(NA_SE_SY_ERROR); + this->unk_33C = 0x15ED; + break; + + case 3: + func_8019F208(); + this->unk_32C |= 0x40; + this->unk_32C &= ~0x1; + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_33C = 0x15EF; + this->actionFunc = func_80BEF360; + return; + } + } else if (this->unk_32C & 0x10) { + this->unk_32C &= ~0x10; + this->unk_33C = 0x15EB; + break; + } + break; + + case 0x160C: + this->unk_33C = 0x15FA; + this->unk_32C |= 1; + break; + + case 0x15FA: + this->unk_33C = 0x160D; + gSaveContext.weekEventReg[62] |= 0x4; + this->unk_32C |= 0x20; + break; + + case 0x15EF: + this->unk_32C |= 1; + break; + } + + func_801518B0(globalCtx, this->unk_33C, &this->actor); +} + +void func_80BEE070(EnAkindonuts* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + switch (this->unk_33C) { + case 0: + if ((player->transformation == PLAYER_FORM_GORON) && !(gSaveContext.weekEventReg[62] & 0x10)) { + gSaveContext.weekEventReg[62] |= 0x10; + this->unk_33C = 0x1614; + break; + } + this->unk_33C = 0x1616; + break; + + case 0x1614: + this->unk_33C = 0x1615; + break; + + case 0x1615: + case 0x1616: + this->unk_33C = 0x1617; + break; + + case 0x1617: + this->unk_33C = 0x1618; + break; + + case 0x1618: + this->unk_32C |= 0x1; + if (this->unk_32C & 0x8) { + this->unk_32C &= ~8; + + switch (func_80BED2FC(this)) { + case 2: + play_sound(NA_SE_SY_ERROR); + this->unk_33C = 0x1613; + break; + + case 1: + play_sound(NA_SE_SY_ERROR); + this->unk_33C = 0x15ED; + break; + + case 3: + func_8019F208(); + this->unk_32C |= 0x40; + this->unk_32C &= ~0x1; + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_33C = 0x161A; + this->actionFunc = func_80BEF360; + return; + } + } else if (this->unk_32C & 0x10) { + this->unk_32C &= ~0x10; + this->unk_33C = 0x1619; + break; + } + break; + + case 0x161A: + this->unk_32C |= 1; + break; + } + + func_801518B0(globalCtx, this->unk_33C, &this->actor); +} + +void func_80BEE274(EnAkindonuts* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + switch (this->unk_33C) { + case 0: + if (player->transformation == PLAYER_FORM_ZORA) { + this->unk_33C = 0x161B; + break; + } + this->unk_33C = 0x1624; + break; + + case 0x161B: + this->unk_33C = 0x161C; + break; + + case 0x161C: + this->unk_33C = 0x15E2; + break; + + case 0x15E2: + this->unk_33C = 0xFF; + break; + + case 0x1624: + if (!(gSaveContext.weekEventReg[62] & 0x40)) { + gSaveContext.weekEventReg[62] |= 0x40; + this->unk_33C = 0x1625; + break; + } + this->unk_33C = 0x1627; + break; + + case 0x1625: + case 0x1627: + this->unk_33C = 0x1626; + break; + + case 0x1626: + this->unk_33C = 0x15EA; + break; + + case 0x15EA: + this->unk_32C |= 0x1; + if (this->unk_32C & 0x8) { + this->unk_32C &= ~8; + + switch (func_80BED35C(this)) { + case 2: + play_sound(NA_SE_SY_ERROR); + this->unk_33C = 0x1613; + break; + + case 1: + play_sound(NA_SE_SY_ERROR); + this->unk_33C = 0x15ED; + break; + + case 3: + func_8019F208(); + this->unk_32C |= 0x40; + this->unk_32C &= ~0x1; + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_33C = 0x1629; + this->actionFunc = func_80BEF360; + return; + } + } else if (this->unk_32C & 0x10) { + this->unk_32C &= ~0x10; + this->unk_33C = 0x1628; + break; + } + break; + + case 0x1621: + this->unk_33C = 0x1622; + this->unk_32C |= 1; + break; + + case 0x1622: + this->unk_33C = 0x1623; + gSaveContext.weekEventReg[62] |= 0x20; + this->unk_32C |= 0x20; + break; + + case 0x1629: + this->unk_32C |= 1; + break; + } + + func_801518B0(globalCtx, this->unk_33C, &this->actor); +} + +void func_80BEE530(EnAkindonuts* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + switch (this->unk_33C) { + case 0: + if ((player->transformation == PLAYER_FORM_ZORA) && !(gSaveContext.weekEventReg[62] & 0x80)) { + gSaveContext.weekEventReg[62] |= 0x80; + this->unk_33C = 0x162A; + break; + } + this->unk_33C = 0x162C; + break; + + case 0x162A: + this->unk_33C = 0x162B; + break; + + case 0x162B: + case 0x162C: + this->unk_33C = 0x162D; + break; + + case 0x162D: + this->unk_33C = 0x15EA; + break; + + case 0x15EA: + this->unk_32C |= 0x1; + if (this->unk_32C & 0x8) { + this->unk_32C &= ~8; + + switch (func_80BED35C(this)) { + case 2: + play_sound(NA_SE_SY_ERROR); + this->unk_33C = 0x1613; + break; + + case 1: + play_sound(NA_SE_SY_ERROR); + this->unk_33C = 0x15ED; + break; + + case 3: + func_8019F208(); + this->unk_32C |= 0x40; + this->unk_32C &= ~0x1; + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_33C = 0x15EF; + this->actionFunc = func_80BEF360; + return; + } + } else if (this->unk_32C & 0x10) { + this->unk_32C &= ~0x10; + this->unk_33C = 0x162E; + break; + } + break; + + case 0x15EF: + this->unk_32C |= 1; + break; + } + + func_801518B0(globalCtx, this->unk_33C, &this->actor); +} + +void func_80BEE73C(EnAkindonuts* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 pad; + s32 params = ENAKINDONUTS_GET_3(&this->actor); + s32 itemActionParam = func_80123810(globalCtx); + + if (itemActionParam > PLAYER_AP_NONE) { + if (itemActionParam == PLAYER_AP_DEED_LAND) { + player->actor.textId = D_80BF048C[params]; + this->unk_33C = player->actor.textId; + if (this->unk_33C == 0x15E4) { + player->unk_A87 = itemActionParam; + this->actionFunc = func_80BEF20C; + } else { + this->actionFunc = func_80BEF18C; + } + } else if (itemActionParam == PLAYER_AP_DEED_SWAMP) { + player->actor.textId = D_80BF0494[params]; + this->unk_33C = player->actor.textId; + if (this->unk_33C == 0x15F9) { + player->unk_A87 = itemActionParam; + this->actionFunc = func_80BEF20C; + } else { + this->actionFunc = func_80BEF18C; + } + } else if (itemActionParam == PLAYER_AP_DEED_MOUNTAIN) { + player->actor.textId = D_80BF049C[params]; + this->unk_33C = player->actor.textId; + if (this->unk_33C == 0x160C) { + player->unk_A87 = itemActionParam; + this->actionFunc = func_80BEF20C; + } else { + this->actionFunc = func_80BEF18C; + } + } else if (itemActionParam == PLAYER_AP_DEED_OCEAN) { + player->actor.textId = D_80BF04A4[params]; + this->unk_33C = player->actor.textId; + if (this->unk_33C == 0x1621) { + player->unk_A87 = itemActionParam; + this->actionFunc = func_80BEF20C; + } else { + this->actionFunc = func_80BEF18C; + } + } else { + player->actor.textId = D_80BF04AC[params]; + this->unk_33C = player->actor.textId; + this->actionFunc = func_80BEF18C; + } + func_801477B4(globalCtx); + } else if (itemActionParam < PLAYER_AP_NONE) { + this->unk_33C = D_80BF04AC[params]; + func_80151938(globalCtx, this->unk_33C); + this->actionFunc = func_80BEF18C; + } +} + +void func_80BEE938(EnAkindonuts* this, GlobalContext* globalCtx) { + switch (ENAKINDONUTS_GET_3(&this->actor)) { + case 0: + if (gSaveContext.weekEventReg[61] & 0x10) { + if (ENAKINDONUTS_GET_4(&this->actor)) { + this->unk_2DC = func_80BED680; + } else { + Actor_MarkForDeath(&this->actor); + } + } else if (ENAKINDONUTS_GET_4(&this->actor)) { + Actor_MarkForDeath(&this->actor); + } else { + this->unk_2DC = func_80BED3BC; + } + break; + + case 1: + if (gSaveContext.weekEventReg[61] & 0x80) { + if (ENAKINDONUTS_GET_4(&this->actor)) { + this->unk_2DC = func_80BEDB88; + } else { + Actor_MarkForDeath(&this->actor); + } + } else if (ENAKINDONUTS_GET_4(&this->actor)) { + Actor_MarkForDeath(&this->actor); + } else { + this->unk_2DC = func_80BED8A4; + } + break; + + case 2: + if (gSaveContext.weekEventReg[62] & 4) { + if (ENAKINDONUTS_GET_4(&this->actor)) { + this->unk_2DC = func_80BEE070; + } else { + Actor_MarkForDeath(&this->actor); + } + } else if (ENAKINDONUTS_GET_4(&this->actor)) { + Actor_MarkForDeath(&this->actor); + } else { + this->unk_2DC = func_80BEDDAC; + } + break; + + case 3: + if (gSaveContext.weekEventReg[62] & 0x20) { + if (ENAKINDONUTS_GET_4(&this->actor)) { + this->unk_2DC = func_80BEE530; + } else { + Actor_MarkForDeath(&this->actor); + } + } else if (ENAKINDONUTS_GET_4(&this->actor)) { + Actor_MarkForDeath(&this->actor); + } else { + this->unk_2DC = func_80BEE274; + } + break; + } +} + +void func_80BEEB20(EnAkindonuts* this, GlobalContext* globalCtx) { + s16 sp26 = this->skelAnime.curFrame; + s16 sp24 = Animation_GetLastFrame(&sAnimations[this->unk_338].animationSeg->common); + s16 phi_v0; + + Math_ApproachS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0xE38); + + if ((this->actor.playerHeightRel < 50.0f) && (this->actor.playerHeightRel > -50.0f)) { + phi_v0 = true; + } else { + phi_v0 = false; + } + + if (phi_v0) { + if (this->actor.xzDistToPlayer < 200.0f) { + phi_v0 = true; + } else { + phi_v0 = false; + } + + if (phi_v0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); + this->actionFunc = func_80BEEDC0; + this->unk_338 = 3; + this->collider.dim.height = 64; + func_8013BC6C(&this->skelAnime, sAnimations, 3); + return; + } + } + + if (sp26 == sp24) { + if ((this->unk_338 == 4) || (this->unk_338 == 18)) { + this->unk_338 = 17; + this->collider.dim.height = 0; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_DOWN); + func_8013BC6C(&this->skelAnime, sAnimations, 17); + } else if (this->unk_338 == 2) { + this->unk_338 = 16; + this->collider.dim.height = 32; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_UP); + func_8013BC6C(&this->skelAnime, sAnimations, 16); + } else if (this->unk_338 == 17) { + phi_v0 = DECR(this->unk_33A); + if (phi_v0 == 0) { + this->unk_33A = Rand_ZeroOne() * 10.0f; + this->unk_338 = 2; + this->collider.dim.height = 32; + func_8013BC6C(&this->skelAnime, sAnimations, 2); + } + } else if (this->unk_338 == 16) { + phi_v0 = DECR(this->unk_33A); + if (phi_v0 == 0) { + this->unk_33A = Rand_S16Offset(40, 40); + this->unk_338 = 18; + this->collider.dim.height = 32; + func_8013BC6C(&this->skelAnime, sAnimations, 18); + } + } + } +} + +void func_80BEEDC0(EnAkindonuts* this, GlobalContext* globalCtx) { + if (this->skelAnime.curFrame == this->skelAnime.endFrame) { + this->actionFunc = func_80BEEE10; + func_8013BC6C(&this->skelAnime, sAnimations, 0); + } +} + +void func_80BEEE10(EnAkindonuts* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 3, 2000, 0); + this->actor.world.rot.y = this->actor.shape.rot.y; + + if (func_800B84D0(&this->actor, globalCtx)) { + this->unk_2DC(this, globalCtx); + this->actionFunc = func_80BEEFA8; + } else if (((this->actor.xzDistToPlayer < 100.0f) && + (((this->actor.playerHeightRel < 50.0f) && (this->actor.playerHeightRel > -50.0f)) ? true : false)) || + this->actor.isTargeted) { + func_800B8614(&this->actor, globalCtx, 100.0f); + } else if (!(((this->actor.playerHeightRel < 50.0f) && (this->actor.playerHeightRel > -50.0f)) ? true : false) || + !((this->actor.xzDistToPlayer < 200.0f) ? true : false)) { + this->unk_338 = 4; + func_8013BC6C(&this->skelAnime, sAnimations, 4); + this->actionFunc = func_80BEEB20; + } +} + +void func_80BEEFA8(EnAkindonuts* this, GlobalContext* globalCtx) { + u8 temp_v0 = func_80152498(&globalCtx->msgCtx); + + if (temp_v0 == 5) { + if (func_80147624(globalCtx)) { + if (this->unk_32C & 1) { + this->unk_32C &= ~0x1; + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_33C = 0; + this->actionFunc = func_80BEEE10; + } else if (this->unk_32C & 0x20) { + this->unk_32C &= ~0x20; + this->actor.flags &= ~1; + this->unk_32C &= ~0x4; + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_338 = 8; + this->unk_33C = 0; + func_8013BC6C(&this->skelAnime, sAnimations, this->unk_338); + this->actionFunc = func_80BEF518; + } else { + this->unk_2DC(this, globalCtx); + } + } + } else if (temp_v0 == 4) { + if (func_80147624(globalCtx)) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + this->unk_32C |= 0x8; + this->unk_2DC(this, globalCtx); + break; + + case 1: + func_8019F230(); + this->unk_32C |= 0x10; + this->unk_2DC(this, globalCtx); + break; + } + } + } else if (temp_v0 == 16) { + func_80BEE73C(this, globalCtx); + } +} + +void func_80BEF18C(EnAkindonuts* this, GlobalContext* globalCtx) { + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_33C = 0; + this->actionFunc = func_80BEEE10; + } +} + +void func_80BEF20C(EnAkindonuts* this, GlobalContext* globalCtx) { + u8 sp27 = func_80152498(&globalCtx->msgCtx); + s16 sp24 = this->skelAnime.curFrame; + s16 sp22 = Animation_GetLastFrame(&sAnimations[this->unk_338].animationSeg->common); + + if (this->unk_356 == 40) { + this->unk_338 = 5; + func_8013BC6C(&this->skelAnime, sAnimations, 5); + } + + this->unk_356++; + + if ((sp24 == sp22) && (this->unk_338 == 5)) { + this->unk_338 = 6; + func_8013BC6C(&this->skelAnime, sAnimations, 6); + } + + if ((sp27 == 5) && func_80147624(globalCtx)) { + if (this->unk_32C & 1) { + this->unk_32C &= ~0x1; + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->actionFunc = func_80BEF360; + } else { + this->unk_2DC(this, globalCtx); + } + } +} + +void func_80BEF360(EnAkindonuts* this, GlobalContext* globalCtx) { + if (this->unk_32C & 0x40) { + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + func_801159EC(this->unk_364); + this->unk_32C &= ~0x40; + this->actionFunc = func_80BEF450; + } else { + func_800B8A1C(&this->actor, globalCtx, func_80BED034(this), 300.0f, 300.0f); + } + } else if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + this->actionFunc = func_80BEF450; + } else { + func_800B8A1C(&this->actor, globalCtx, func_80BECFBC(this), 300.0f, 300.0f); + } +} + +void func_80BEF450(EnAkindonuts* this, GlobalContext* globalCtx) { + if ((func_80152498(&globalCtx->msgCtx) == 6) && func_80147624(globalCtx)) { + func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + this->actionFunc = func_80BEF4B8; + } +} + +void func_80BEF4B8(EnAkindonuts* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + this->unk_2DC(this, globalCtx); + this->actionFunc = func_80BEEFA8; + } else { + func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + } +} + +void func_80BEF518(EnAkindonuts* this, GlobalContext* globalCtx) { + s16 sp26 = this->skelAnime.curFrame; + s16 sp24 = Animation_GetLastFrame(&sAnimations[this->unk_338].animationSeg->common); + + switch (sp26) { + case 10: + this->unk_33E = 1; + this->unk_340 = 0.1f; + this->unk_344 = 0.1f; + this->unk_348 = 0.1f; + break; + + case 11: + case 12: + this->unk_340 += 0.15f; + this->unk_344 += 0.32f; + this->unk_348 += 0.15f; + break; + + case 13: + this->unk_340 = 0.55f; + this->unk_344 = 1.05f; + this->unk_348 = 0.55f; + break; + + case 14: + this->unk_340 = 1.0f; + this->unk_344 = 2.0f; + this->unk_348 = 1.0f; + break; + + case 15: + case 16: + this->unk_344 -= 0.33f; + break; + + case 17: + this->unk_344 = 1.0f; + break; + + case 18: + case 19: + this->unk_344 += 0.27f; + break; + case 20: + this->unk_33E = 2; + this->unk_344 = 1.8f; + break; + + case 21: + case 22: + case 23: + this->unk_344 -= 0.2f; + break; + + case 24: + this->unk_344 = 1.0f; + break; + } + + if (this->unk_35E == 0) { + if (ActorCutscene_GetCanPlayNext(this->cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->cutscene, &this->actor); + this->unk_35E = 1; + } else { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + } + ActorCutscene_SetIntentToPlay(this->cutscene); + return; + } + } + + if (sp26 == sp24) { + this->unk_33E = 3; + this->unk_338 = 19; + func_8013BC6C(&this->skelAnime, sAnimations, this->unk_338); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_DOWN); + this->unk_32C &= ~2; + this->unk_32C |= 0x80; + this->unk_358 = this->actor.world.pos.y; + this->actionFunc = func_80BEF770; + } +} + +void func_80BEF770(EnAkindonuts* this, GlobalContext* globalCtx) { + f32 sp24 = this->unk_358 - this->actor.world.pos.y; + Vec3f sp18; + + this->unk_352 += this->unk_362; + if (!(this->unk_35C & 3)) { + sp18.x = this->actor.world.pos.x; + sp18.y = this->unk_358; + sp18.z = this->actor.world.pos.z; + func_800B14D4(globalCtx, 20.0f, &sp18); + } + + if (sp24 > 5.0f) { + this->unk_33A = 50; + this->actor.velocity.y = 0.0f; + this->actor.gravity = 0.0f; + this->unk_368 = func_80BECF6C(this->path); + this->actionFunc = func_80BEF83C; + } +} + +void func_80BEF83C(EnAkindonuts* this, GlobalContext* globalCtx) { + Vec3f sp34; + s16 sp32 = this->skelAnime.curFrame; + s16 sp30 = Animation_GetLastFrame(&sAnimations[this->unk_338].animationSeg->common); + + if (sp32 == sp30) { + Math_SmoothStepToS(&this->unk_362, 0x1C71, 3, 0x100, 0); + this->unk_352 += this->unk_362; + this->actor.shape.yOffset = 1500.0f; + } + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->unk_368, 3, 2000, 0); + this->actor.world.rot.y = this->actor.shape.rot.y; + + if (DECR(this->unk_33A) == 0) { + if (!(this->unk_35C & 3)) { + sp34 = this->actor.world.pos; + func_800B14D4(globalCtx, 20.0f, &sp34); + } + this->actor.velocity.y = 5.0f; + } else if (!(this->unk_35C & 3)) { + sp34.x = this->actor.world.pos.x; + sp34.y = this->unk_358; + sp34.z = this->actor.world.pos.z; + func_800B14D4(globalCtx, 20.0f, &sp34); + } + if ((this->actor.home.pos.y + 22.5f) < this->actor.world.pos.y) { + this->unk_34C = 0.3f; + this->unk_338 = 9; + func_8013BC6C(&this->skelAnime, sAnimations, this->unk_338); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_AKINDONUTS_HIDE); + this->actionFunc = func_80BEF9F0; + } +} + +void func_80BEF9F0(EnAkindonuts* this, GlobalContext* globalCtx) { + this->unk_352 += this->unk_362; + if (this->unk_34C >= 1.0f) { + this->unk_34C = 1.0f; + this->actor.velocity.y = 5.0f; + } else { + this->actor.velocity.y = 5.0f; + this->unk_34C += 0.1f; + } + + if ((this->actor.home.pos.y + 200.0f) < this->actor.world.pos.y) { + Math_ApproachF(&this->actor.velocity.y, 0.0f, 0.2f, 1.0f); + this->unk_338 = 10; + func_8013BC6C(&this->skelAnime, sAnimations, this->unk_338); + if (ENAKINDONUTS_GET_3(&this->actor) == ENAKINDONUTS_3_2) { + this->unk_32C |= 0x2; + } + this->unk_356 = 0; + this->actionFunc = func_80BEFAF0; + } +} + +void func_80BEFAF0(EnAkindonuts* this, GlobalContext* globalCtx) { + Vec3s sp38; + f32 sp34; + s16 sp32 = false; + + this->actor.velocity.y = 0.0f; + this->actor.gravity = 0.0f; + + if (this->path != NULL) { + sp34 = func_80BECEAC(this->path, this->unk_334, &this->actor.world.pos, &sp38); + if (this->actor.bgCheckFlags & 0x8) { + sp38.y = this->actor.wallYaw; + } + + if (ENAKINDONUTS_GET_3(&this->actor) == ENAKINDONUTS_3_1) { + Math_SmoothStepToS(&this->actor.world.rot.y, sp38.y, 10, 1000, 0); + } else { + Math_SmoothStepToS(&this->actor.world.rot.y, sp38.y, 10, 300, 0); + } + + this->actor.shape.rot.y = this->actor.world.rot.y; + this->unk_350 = 0x1000; + this->unk_352 += this->unk_362; + this->actor.world.rot.x = -sp38.x; + + if (func_80BECD10(this, this->path, this->unk_334) && (sp34 < 10.0f)) { + if (this->unk_334 >= (this->path->count - 1)) { + ActorCutscene_Stop(this->cutscene); + this->actionFunc = func_80BEFD74; + } else { + this->unk_334++; + } + } + } else if (this->actor.playerHeightRel > 500.0f) { + ActorCutscene_Stop(this->cutscene); + this->actionFunc = func_80BEFD74; + } + + if (ENAKINDONUTS_GET_3(&this->actor) == ENAKINDONUTS_3_2) { + if (this->unk_334 >= 3) { + sp32 = true; + } + Math_ApproachF(&this->actor.speedXZ, 1.5f, 0.2f, 1.0f); + } else { + Math_ApproachF(&this->actor.speedXZ, 2.0f, 0.2f, 1.0f); + } + + func_80BECBE0(this, sp32); + + if (this->unk_35E == 2) { + if (ActorCutscene_GetCanPlayNext(this->cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->cutscene, &this->actor); + this->unk_35E = 3; + } else { + ActorCutscene_SetIntentToPlay(this->cutscene); + return; + } + } else if ((this->unk_35E == 1) && (this->unk_356 == 20)) { + ActorCutscene_Stop(this->cutscene); + this->cutscene = ActorCutscene_GetAdditionalCutscene(this->cutscene); + ActorCutscene_SetIntentToPlay(this->cutscene); + this->unk_35E = 2; + } + this->unk_356++; +} + +void func_80BEFD74(EnAkindonuts* this, GlobalContext* globalCtx) { + Actor_MarkForDeath(&this->actor); +} + +void EnAkindonuts_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnAkindonuts* this = THIS; + + Actor_ProcessInitChain(&this->actor, sInitChain); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_dnt_Skel_00AC70, &object_dnt_Anim_005488, this->jointTable, + this->morphTable, 28); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinderType1(globalCtx, &this->collider, &this->actor, &sCylinderInit); + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 35.0f); + Actor_SetScale(&this->actor, 0.01f); + + this->actor.colChkInfo.cylRadius = 0; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->actor.gravity = -1.0f; + + if (!ENAKINDONUTS_GET_4(&this->actor)) { + this->path = func_8013D648(globalCtx, ENAKINDONUTS_GET_FC00(&this->actor), 0x3F); + if (this->path == NULL) { + Actor_MarkForDeath(&this->actor); + return; + } + } + + func_8013BC6C(&this->skelAnime, sAnimations, 4); + this->unk_32C |= 0x2; + this->unk_32C |= 0x4; + this->unk_338 = 4; + this->cutscene = this->actor.cutscene; + func_80BEE938(this, globalCtx); + this->actionFunc = func_80BEEB20; +} + +void EnAkindonuts_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnAkindonuts* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void EnAkindonuts_Update(Actor* thisx, GlobalContext* globalCtx) { + EnAkindonuts* this = THIS; + + Actor_SetHeight(&this->actor, 60.0f); + SkelAnime_Update(&this->skelAnime); + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + + this->actionFunc(this, globalCtx); + + if (this->unk_32C & 0x80) { + func_800B9010(&this->actor, NA_SE_EN_AKINDO_FLY - SFX_FLAG); + } + func_80BECC7C(this, globalCtx); +} + +s32 EnAkindonuts_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnAkindonuts* this = THIS; + + if (((this->unk_338 == 4) && (this->unk_33E == 0)) || ((this->unk_338 == 8) && (this->unk_33E == 0)) || + (this->unk_338 == 18) || (this->unk_338 == 2) || (this->unk_338 == 3) || (this->unk_338 == 17) || + (this->unk_338 == 5) || (this->unk_338 == 6) || (this->unk_338 == 7) || (this->unk_338 == 16)) { + if ((limbIndex == 16) || (limbIndex == 21) || (limbIndex == 27) || (limbIndex == 23) || (limbIndex == 24) || + (limbIndex == 15)) { + *dList = NULL; + } + } else if ((this->unk_338 == 8) || (this->unk_338 == 19)) { + switch (this->unk_33E) { + case 1: + if ((limbIndex == 16) || (limbIndex == 21) || (limbIndex == 27) || (limbIndex == 25)) { + *dList = NULL; + } + break; + + case 2: + case 3: + if ((limbIndex == 16) || (limbIndex == 21) || (limbIndex == 27) || (limbIndex == 15) || + (limbIndex == 25)) { + *dList = NULL; + } + break; + } + } else if (((this->unk_338 == 9) || (this->unk_338 == 10)) && ((limbIndex == 15) || (limbIndex == 25))) { + *dList = NULL; + } + + if (limbIndex == 26) { + if ((this->unk_338 == 6) || (this->unk_338 == 5) || (this->unk_338 == 7)) { + *dList = object_dnt_DL_001350; + } else { + *dList = object_dnt_DL_008290; + } + } + return 0; +} + +void EnAkindonuts_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { +} + +void EnAkindonuts_UnkActorDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnAkindonuts* this = THIS; + + if (((this->unk_33E == 1) || (this->unk_33E == 2)) && ((limbIndex == 23) || (limbIndex == 24))) { + Matrix_Scale(this->unk_340, this->unk_344, this->unk_348, MTXMODE_APPLY); + } + + if ((this->unk_338 == 9) && ((limbIndex == 16) || (limbIndex == 21) || (limbIndex == 27))) { + Matrix_Scale(this->unk_34C, this->unk_34C, this->unk_34C, MTXMODE_APPLY); + } + + if (limbIndex == 24) { + Matrix_RotateY(this->unk_352, MTXMODE_APPLY); + } +} + +void EnAkindonuts_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnAkindonuts* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnAkindonuts_OverrideLimbDraw, EnAkindonuts_PostLimbDraw, EnAkindonuts_UnkActorDraw, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Akindonuts/z_en_akindonuts.h b/src/overlays/actors/ovl_En_Akindonuts/z_en_akindonuts.h index 08efd8975..e5d134f45 100644 --- a/src/overlays/actors/ovl_En_Akindonuts/z_en_akindonuts.h +++ b/src/overlays/actors/ovl_En_Akindonuts/z_en_akindonuts.h @@ -6,12 +6,48 @@ struct EnAkindonuts; typedef void (*EnAkindonutsActionFunc)(struct EnAkindonuts*, GlobalContext*); +typedef void (*EnAkindonutsUnkFunc)(struct EnAkindonuts*, GlobalContext*); + +#define ENAKINDONUTS_GET_3(thisx) ((thisx)->params & 3) +#define ENAKINDONUTS_GET_4(thisx) (((thisx)->params & 4) >> 2) +#define ENAKINDONUTS_GET_FC00(thisx) (((thisx)->params & 0xFC00) >> 0xA) + +enum { + /* 1 */ ENAKINDONUTS_3_1 = 1, + /* 2 */ ENAKINDONUTS_3_2, +}; typedef struct EnAkindonuts { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x194]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[28]; + /* 0x0230 */ Vec3s morphTable[28]; /* 0x02D8 */ EnAkindonutsActionFunc actionFunc; - /* 0x02DC */ char unk_2DC[0x90]; + /* 0x02DC */ EnAkindonutsUnkFunc unk_2DC; + /* 0x02E0 */ ColliderCylinder collider; + /* 0x032C */ u16 unk_32C; + /* 0x0330 */ Path* path; + /* 0x0334 */ s32 unk_334; + /* 0x0338 */ s16 unk_338; + /* 0x033A */ s16 unk_33A; + /* 0x033C */ u16 unk_33C; + /* 0x033E */ s16 unk_33E; + /* 0x0340 */ f32 unk_340; + /* 0x0344 */ f32 unk_344; + /* 0x0348 */ f32 unk_348; + /* 0x034C */ f32 unk_34C; + /* 0x0350 */ s16 unk_350; + /* 0x0352 */ s16 unk_352; + /* 0x0354 */ UNK_TYPE1 unk354[0x2]; + /* 0x0356 */ s16 unk_356; + /* 0x0358 */ f32 unk_358; + /* 0x035C */ s16 unk_35C; + /* 0x035E */ s16 unk_35E; + /* 0x0360 */ s16 cutscene; + /* 0x0362 */ s16 unk_362; + /* 0x0364 */ s16 unk_364; + /* 0x0366 */ s8 unk_366; + /* 0x0368 */ s16 unk_368; } EnAkindonuts; // size = 0x36C extern const ActorInit En_Akindonuts_InitVars; diff --git a/src/overlays/actors/ovl_En_Al/z_en_al.c b/src/overlays/actors/ovl_En_Al/z_en_al.c index 66eb513b9..26961e4c7 100644 --- a/src/overlays/actors/ovl_En_Al/z_en_al.c +++ b/src/overlays/actors/ovl_En_Al/z_en_al.c @@ -1,5 +1,5 @@ /* - * File z_en_al.c + * File: z_en_al.c * Overlay: ovl_En_Al * Description: Madame Aroma */ diff --git a/src/overlays/actors/ovl_En_Am/z_en_am.c b/src/overlays/actors/ovl_En_Am/z_en_am.c index 37a38a9e8..355d37e59 100644 --- a/src/overlays/actors/ovl_En_Am/z_en_am.c +++ b/src/overlays/actors/ovl_En_Am/z_en_am.c @@ -1,5 +1,5 @@ /* - * File z_en_am.c + * File: z_en_am.c * Overlay: ovl_En_Am * Description: Armos */ diff --git a/src/overlays/actors/ovl_En_An/z_en_an.c b/src/overlays/actors/ovl_En_An/z_en_an.c index 9611e2c76..43ea5744a 100644 --- a/src/overlays/actors/ovl_En_An/z_en_an.c +++ b/src/overlays/actors/ovl_En_An/z_en_an.c @@ -1,5 +1,5 @@ /* - * File z_en_an.c + * File: z_en_an.c * Overlay: ovl_En_An * Description: Anju */ diff --git a/src/overlays/actors/ovl_En_And/z_en_and.c b/src/overlays/actors/ovl_En_And/z_en_and.c index 178674efd..ad0291e7d 100644 --- a/src/overlays/actors/ovl_En_And/z_en_and.c +++ b/src/overlays/actors/ovl_En_And/z_en_and.c @@ -1,5 +1,5 @@ /* - * File z_en_and.c + * File: z_en_and.c * Overlay: ovl_En_And * Description: Anju in Wedding Dress */ diff --git a/src/overlays/actors/ovl_En_Ani/z_en_ani.c b/src/overlays/actors/ovl_En_Ani/z_en_ani.c index 5571fe73c..c12578420 100644 --- a/src/overlays/actors/ovl_En_Ani/z_en_ani.c +++ b/src/overlays/actors/ovl_En_Ani/z_en_ani.c @@ -1,7 +1,7 @@ /* - * File z_en_ani.c + * File: z_en_ani.c * Overlay: ovl_En_Ani - * Description: Part-Timer + * Description: Part-time worker */ #include "z_en_ani.h" diff --git a/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.c b/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.c index fe0312f3b..c26081e0d 100644 --- a/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.c +++ b/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.c @@ -1,10 +1,13 @@ /* - * File z_en_aob_01.c + * File: z_en_aob_01.c * Overlay: ovl_En_Aob_01 * Description: Mamamu Yan */ #include "z_en_aob_01.h" +#include "overlays/actors/ovl_En_Racedog/z_en_racedog.h" +#include "overlays/actors/ovl_En_Dg/z_en_dg.h" +#include "objects/object_aob/object_aob.h" #define FLAGS 0x00000019 @@ -28,8 +31,8 @@ void func_809C2A64(EnAob01* this, GlobalContext* globalCtx); void func_809C2BE4(EnAob01* this, GlobalContext* globalCtx); void func_809C2C9C(EnAob01* this, GlobalContext* globalCtx); void func_809C2D0C(EnAob01* this, GlobalContext* globalCtx); +s32 func_809C2EC4(EnAob01* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Aob_01_InitVars = { ACTOR_EN_AOB_01, ACTORCAT_NPC, @@ -42,92 +45,1012 @@ const ActorInit En_Aob_01_InitVars = { (ActorFunc)EnAob01_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_809C3820 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK1, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ActorAnimationEntry D_809C3790[6] = { + { &object_aob_Anim_007758, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &object_aob_Anim_0068B4, 1.0f, 0.0f, 0.0f, 2, 0.0f }, + { &object_aob_Anim_00700C, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &object_aob_Anim_0058EC, 1.0f, 0.0f, 0.0f, 2, 0.0f }, + { &object_aob_Anim_006040, 1.0f, 0.0f, 0.0f, 0, 0.0f }, { &object_aob_Anim_007758, 1.0f, 0.0f, 0.0f, 0, -6.0f }, +}; + +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK1, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 18, 64, 0, { 0, 0, 0 } }, }; -#endif +typedef struct { + Vec3f unk_00; + s16 unk_04; + s16 unk_06; +} EnAobStruct; -extern ColliderCylinderInit D_809C3820; +static EnAobStruct D_809C384C[] = { + { { -4130.0f, 150.0f, 1367.0f }, 84, 0 }, { { -4861.0f, 172.0f, 1606.0f }, 94, 4 }, + { { -4139.0f, 155.0f, 2133.0f }, 73, 6 }, { { -4406.0f, 144.0f, 1416.0f }, 88, 2 }, + { { -4156.0f, 155.0f, 1731.0f }, 42, 0 }, { { -4033.0f, 157.0f, 1994.0f }, -65, 1 }, + { { -4582.0f, 158.0f, 1206.0f }, 144, 2 }, { { -4595.0f, 156.0f, 1493.0f }, 61, 3 }, + { { -4526.0f, 146.0f, 1702.0f }, 61, 4 }, { { -3820.0f, 162.0f, 1965.0f }, 109, 5 }, + { { -4395.0f, 147.0f, 1569.0f }, -24, 0 }, { { -4315.0f, 150.0f, 2048.0f }, 61, 6 }, + { { -4827.0f, 168.0f, 1328.0f }, 115, 4 }, { { -4130.0f, 150.0f, 1367.0f }, 112, 0 }, +}; -extern UNK_TYPE D_06000180; -extern UNK_TYPE D_06003D18; +void func_809C10B0(EnAob01* this, s32 arg1) { + if (DECR(this->unk_3F0) == 0) { + this->unk_3EE++; + if (this->unk_3EE >= arg1) { + this->unk_3EE = 0; + this->unk_3F0 = Rand_S16Offset(30, 30); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C10B0.s") +void func_809C1124(void) { + u16 time = gSaveContext.time; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C1124.s") + gSaveContext.time = (u16)REG(15) + time; + time = gSaveContext.time; + gSaveContext.time = (u16)gSaveContext.unk_14 + time; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C1158.s") +void func_809C1158(EnAob01* this, GlobalContext* globalCtx) { + s32 temp_s0 = ENAOB01_GET_7E00_2(&this->actor); + s16 i = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C11EC.s") + if (temp_s0 != 0x3F) { + do { + this->unk_1D8[i] = func_8013D648(globalCtx, temp_s0, 0x3F); + temp_s0 = this->unk_1D8[i]->unk1; + i++; + } while (temp_s0 != 0xFF); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C1304.s") +void func_809C11EC(EnAob01* this, GlobalContext* globalCtx) { + s32 unk; + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C1424.s") + func_809C1158(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C14D0.s") + for (i = 0; i < ARRAY_COUNT(D_809C384C); i++) { + unk = (this->unk_1D8[D_809C384C[i].unk_06]->unk1 << 0xA) | (i << 5); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C15BC.s") + this->unk_3F8[i] = Actor_SpawnAsChildAndCutscene( + &globalCtx->actorCtx, globalCtx, ACTOR_EN_DG, D_809C384C[i].unk_00.x, D_809C384C[i].unk_00.y, + D_809C384C[i].unk_00.z, 0, D_809C384C[i].unk_04 * 182.04445f, 0, unk, 0xFFFF, this->actor.unk20, NULL); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C165C.s") +void func_809C1304(EnAob01* this, GlobalContext* globalCtx) { + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C16DC.s") + for (i = 0; i < ARRAY_COUNT(this->unk_3F8); i++) { + this->unk_3F8[i] = Actor_SpawnAsChildAndCutscene( + &globalCtx->actorCtx, globalCtx, ACTOR_EN_RACEDOG, (i * 15.0f) + -3897.0f, 130.0f, 1290.0f - (i * 10.0f), 0, + 0x1555, 0, (i << 5) | ENAOB01_GET_7E00_1(&this->actor), 0xFFFF, this->actor.unk20, NULL); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C1C9C.s") +s32 func_809C1424(EnAob01* this) { + s16 curFrame = this->skelAnime.curFrame; + s16 lastFrame = Animation_GetLastFrame(D_809C3790[this->unk_43C].animation); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C1D64.s") + if (this->unk_43C == 1) { + if (curFrame == lastFrame) { + this->unk_43C = 2; + func_800BDC5C(&this->skelAnime, D_809C3790, 2); + return true; + } + } else if (this->unk_43C == 2) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C1EC8.s") +s32 func_809C14D0(EnAob01* this) { + s16 curFrame = this->skelAnime.curFrame; + s16 lastFrame = Animation_GetLastFrame(D_809C3790[this->unk_43C].animation); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C2060.s") + if ((this->unk_43C == 0) || (this->unk_43C == 5)) { + if (curFrame == lastFrame) { + this->unk_43C = 3; + func_800BDC5C(&this->skelAnime, D_809C3790, 3); + return true; + } + } else if (this->unk_43C == 3) { + if (curFrame == lastFrame) { + this->unk_43C = 4; + func_800BDC5C(&this->skelAnime, D_809C3790, 4); + return true; + } + } else if (this->unk_43C == 4) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C21E0.s") +s32 func_809C15BC(EnAob01* this) { + s16 curFrame = this->skelAnime.curFrame; + s16 lastFrame = Animation_GetLastFrame(D_809C3790[this->unk_43C].animation); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C2504.s") + if ((this->unk_43C != 0) && (this->unk_43C != 5)) { + if (curFrame == lastFrame) { + this->unk_43C = 5; + func_800BDC5C(&this->skelAnime, D_809C3790, 5); + return true; + } + } else { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C2594.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C25E4.s") +void func_809C165C(EnAob01* this, GlobalContext* globalCtx) { + this->collider.dim.pos.x = this->actor.world.pos.x; + this->collider.dim.pos.y = this->actor.world.pos.y; + this->collider.dim.pos.z = this->actor.world.pos.z; + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C2680.s") +void func_809C16DC(EnAob01* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C26E4.s") + switch (this->unk_210) { + case 0: + case 0x3524: + case 0x3535: + case 0x3548: + case 0x3549: + case 0x354A: + switch (gSaveContext.day) { + case 1: + if (!gSaveContext.isNight) { + if (!(gSaveContext.weekEventReg[64] & 0x80)) { + gSaveContext.weekEventReg[64] |= 0x80; + this->unk_210 = 0x3520; + } else { + this->unk_210 = 0x352F; + } + } else { + if (!(gSaveContext.weekEventReg[65] & 1)) { + gSaveContext.weekEventReg[65] |= 1; + this->unk_210 = 0x3530; + } else { + this->unk_210 = 0x352F; + } + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C2730.s") + case 2: + if (!gSaveContext.isNight) { + if (!(gSaveContext.weekEventReg[65] & 2)) { + gSaveContext.weekEventReg[65] |= 2; + this->unk_210 = 0x3531; + } else { + this->unk_210 = 0x352F; + } + } else { + if (!(gSaveContext.weekEventReg[65] & 4)) { + gSaveContext.weekEventReg[65] |= 4; + this->unk_210 = 0x3532; + } else { + this->unk_210 = 0x352F; + } + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C2788.s") + case 3: + if (!gSaveContext.isNight) { + if (!(gSaveContext.weekEventReg[65] & 8)) { + gSaveContext.weekEventReg[65] |= 8; + this->unk_210 = 0x3533; + } else { + this->unk_210 = 0x352F; + } + } else { + if (!(gSaveContext.weekEventReg[65] & 0x10)) { + gSaveContext.weekEventReg[65] |= 0x10; + this->unk_210 = 0x3534; + } else { + this->unk_210 = 0x352F; + } + } + break; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C2824.s") + case 0x3520: + case 0x352F: + case 0x3530: + case 0x3531: + case 0x3532: + case 0x3533: + case 0x3534: + this->unk_210 = 0x3521; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C28B8.s") + case 0x3521: + if (this->unk_2D2 & 2) { + this->unk_2D2 &= ~2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C2A64.s") + switch (player->transformation) { + case PLAYER_FORM_GORON: + this->unk_210 = 0x3548; + this->unk_2D2 |= 0x10; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C2BE4.s") + case PLAYER_FORM_ZORA: + this->unk_210 = 0x3549; + this->unk_2D2 |= 0x10; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C2C9C.s") + case PLAYER_FORM_DEKU: + this->unk_210 = 0x354A; + this->unk_2D2 |= 0x10; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C2D0C.s") + case PLAYER_FORM_HUMAN: + if (gSaveContext.rupees < 10) { + this->unk_210 = 0x3524; + this->unk_2D2 |= 0x10; + } else { + this->unk_210 = 0x3522; + this->unk_2D2 |= 4; + this->unk_2D2 |= 0x10; + } + } + } else { + this->unk_2D2 |= 0x10; + this->unk_210 = 0x3535; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C2EC4.s") + case 0x3522: + case 0x3523: + if (this->unk_2D2 & 8) { + this->unk_210 = 0x3525; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C2F34.s") + this->unk_210 = 0x3523; + this->unk_2D2 |= 0x40; + this->unk_2D2 |= 0x10; + this->unk_43C = 1; + func_800BDC5C(&this->skelAnime, D_809C3790, 1); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C2FA0.s") + case 0x3525: + case 0x3526: + if (this->unk_2D2 & 4) { + if (this->unk_2D2 & 8) { + this->unk_210 = 0x3525; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/EnAob01_Init.s") + this->unk_210 = 0x3523; + this->unk_2D2 |= 0x40; + this->unk_2D2 |= 0x10; + this->unk_43C = 1; + func_800BDC5C(&this->skelAnime, D_809C3790, 1); + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/EnAob01_Destroy.s") + if (this->unk_2D2 & 2) { + this->unk_2D2 &= ~2; + this->unk_210 = 0x3527; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/EnAob01_Update.s") + this->unk_210 = 0x3526; + this->unk_2D2 |= 0x40; + this->unk_2D2 |= 4; + this->unk_2D2 |= 0x10; + this->unk_43C = 1; + func_800BDC5C(&this->skelAnime, D_809C3790, 1); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C33D8.s") + case 0x3527: + this->unk_210 = 0x3528; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C35B4.s") + case 0x3528: + if (gSaveContext.rupees < this->unk_434) { + this->unk_210 = 0x3536; + this->unk_2D2 |= 0x40; + this->unk_43C = 1; + func_800BDC5C(&this->skelAnime, D_809C3790, 1); + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/func_809C35F4.s") + if (this->unk_434 == 0) { + this->unk_210 = 0x3537; + this->unk_2D2 |= 0x40; + this->unk_43C = 1; + func_800BDC5C(&this->skelAnime, D_809C3790, 1); + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Aob_01/EnAob01_Draw.s") + gSaveContext.unk_3F5C = this->unk_434; + globalCtx->msgCtx.bankRupees = this->unk_434; + this->unk_210 = 0x3529; + break; + + case 0x3529: + if (this->unk_2D2 & 2) { + this->unk_2D2 &= ~2; + func_801159EC(-this->unk_434); + func_800B7298(globalCtx, NULL, 7); + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->actionFunc = func_809C1C9C; + return; + } + this->unk_210 = 0x3528; + break; + + case 0x3536: + case 0x3537: + this->unk_210 = 0x3528; + break; + } + + func_801518B0(globalCtx, this->unk_210, &this->actor); +} + +void func_809C1C9C(EnAob01* this, GlobalContext* globalCtx) { + if (gSaveContext.rupeeAccumulator == 0) { + gSaveContext.weekEventReg[63] |= 1; + gSaveContext.weekEventReg[63] &= (u8)~2; + this->unk_2D2 |= 0x20; + func_800FD750(0x40); + globalCtx->nextEntranceIndex = 0x7C10; + globalCtx->unk_1887F = 0x40; + gSaveContext.nextTransition = 0x40; + gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & (u8)~7) | 2; + gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & 7) | (this->unk_432 * 8); + globalCtx->sceneLoadFlag = 0x14; + } +} + +void func_809C1D64(EnAob01* this, GlobalContext* globalCtx) { + u8 temp_v0 = func_80152498(&globalCtx->msgCtx); + + if (temp_v0 == 4) { + if (func_80147624(globalCtx)) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + if (gSaveContext.rupees < 10) { + play_sound(NA_SE_SY_ERROR); + this->unk_210 = 0x3524; + func_801518B0(globalCtx, this->unk_210, &this->actor); + } else { + func_8019F208(); + this->unk_2D2 |= 4; + this->unk_2D2 |= 0x10; + this->unk_210 = 0x3522; + func_801518B0(globalCtx, this->unk_210, &this->actor); + this->actionFunc = func_809C21E0; + } + break; + + case 1: + func_8019F230(); + this->unk_210 = 0x3535; + func_801518B0(globalCtx, this->unk_210, &this->actor); + break; + } + } + } else if ((temp_v0 == 5) && func_80147624(globalCtx)) { + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_210 = 0; + this->actionFunc = func_809C2060; + } +} + +void func_809C1EC8(EnAob01* this, GlobalContext* globalCtx) { + static u16 D_809C392C[] = { 4000, 4, 1, 3, 6000, 4, 1, 6, 4000, 4, 1, 3, 6000, 4, 1, 6 }; + Player* player = GET_PLAYER(globalCtx); + Vec3f sp30; + + SkelAnime_Update(&this->skelAnime); + if (func_8013D5E8(this->actor.shape.rot.y, 14000, this->actor.yawTowardsPlayer)) { + sp30.x = player->actor.world.pos.x; + sp30.y = player->bodyPartsPos[7].y + 3.0f; + sp30.z = player->actor.world.pos.z; + func_8013D2E0(&sp30, &this->actor.focus.pos, &this->actor.shape.rot, &this->unk_2D4, &this->unk_2DA, + &this->unk_2E0, D_809C392C); + } else { + Math_SmoothStepToS(&this->unk_2D4.x, 0, 4, 1000, 1); + Math_SmoothStepToS(&this->unk_2D4.y, 0, 4, 1000, 1); + Math_SmoothStepToS(&this->unk_2DA.x, 0, 4, 1000, 1); + Math_SmoothStepToS(&this->unk_2DA.y, 0, 4, 1000, 1); + Math_SmoothStepToS(&this->unk_2E0.x, 0, 4, 1000, 1); + Math_SmoothStepToS(&this->unk_2E0.y, 0, 4, 1000, 1); + } + func_809C10B0(this, 3); + func_8013D9C8(globalCtx, this->unk_2F8, this->unk_318, 0x10); + func_809C165C(this, globalCtx); + if (player->stateFlags1 & 0x20) { + func_809C1124(); + } +} + +void func_809C2060(EnAob01* this, GlobalContext* globalCtx) { + if (func_809C15BC(this)) { + if (func_809C2EC4(this, globalCtx) && !(this->unk_2D2 & 0x100)) { + if (this->collider.base.ocFlags2 & OC2_HIT_PLAYER) { + this->actor.flags |= 0x10000; + func_800B8614(&this->actor, globalCtx, 100.0f); + this->unk_2D2 |= 8; + this->actionFunc = func_809C21E0; + } + } else if (func_800B84D0(&this->actor, globalCtx) && (this->unk_2D2 & 0x100)) { + this->unk_2D2 &= ~0x100; + this->unk_2E6 = this->unk_2D4; + this->unk_2EC = this->unk_2DA; + this->unk_2F2 = this->unk_2E0; + func_809C16DC(this, globalCtx); + this->actionFunc = func_809C21E0; + } else { + this->unk_2D2 &= ~0x100; + if ((this->actor.xzDistToPlayer < 100.0f) && !(this->collider.base.ocFlags2 & OC2_HIT_PLAYER)) { + this->unk_2D2 |= 0x100; + func_800B8614(&this->actor, globalCtx, 100.0f); + } + } + } +} + +void func_809C21E0(EnAob01* this, GlobalContext* globalCtx) { + u8 sp2F = func_80152498(&globalCtx->msgCtx); + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 4, 4000, 1); + + if ((this->unk_2D2 & 8) && !func_809C2EC4(this, globalCtx)) { + if ((this->unk_210 != 0) && (this->unk_210 != 0x3535) && (this->unk_210 != 0x3524) && + (this->unk_210 != 0x3548) && (this->unk_210 != 0x3549) && (this->unk_210 != 0x354A)) { + this->unk_210 = 0x3523; + } + this->actor.textId = 0; + this->unk_2D2 &= ~8; + this->actor.flags &= ~0x10000; + this->actionFunc = func_809C2060; + return; + } + + if (this->unk_2D2 & 0x40) { + if (!func_809C1424(this)) { + return; + } + } else if (!func_809C15BC(this)) { + return; + } + + if (this->unk_2D2 & 8) { + if (func_800B84D0(&this->actor, globalCtx)) { + this->actor.flags &= ~0x10000; + func_80123E90(globalCtx, &this->actor); + if (this->unk_2D2 & 4) { + func_809C16DC(this, globalCtx); + this->unk_2D2 &= ~4; + } else { + this->unk_2D2 |= 0x10; + this->unk_2D2 |= 0x40; + this->unk_43C = 1; + func_800BDC5C(&this->skelAnime, D_809C3790, 1); + func_801518B0(globalCtx, 0x354B, &this->actor); + } + this->unk_2D2 &= ~8; + } + } else if (sp2F == 4) { + if (func_80147624(globalCtx)) { + this->unk_2D2 &= ~0x40; + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_8019F208(); + this->unk_2D2 |= 2; + func_809C16DC(this, globalCtx); + break; + + case 1: + func_8019F230(); + func_809C16DC(this, globalCtx); + break; + } + } + } else if (sp2F == 5) { + if (func_80147624(globalCtx)) { + this->unk_2D2 &= ~0x40; + if (this->unk_2D2 & 0x10) { + this->unk_2D2 &= ~0x10; + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->actionFunc = func_809C2060; + } else { + func_809C16DC(this, globalCtx); + } + } + } else if ((sp2F == 14) && func_80147624(globalCtx)) { + this->unk_2D2 &= ~0x40; + this->unk_434 = globalCtx->msgCtx.bankRupeesSelected; + func_809C16DC(this, globalCtx); + } +} + +s32 func_809C2504(EnAob01* this, GlobalContext* globalCtx) { + Actor* npc = globalCtx->actorCtx.actorList[ACTORCAT_NPC].first; + + while (npc != NULL) { + if ((npc->id == ACTOR_EN_RACEDOG) && (func_800F2178(this->unk_430) == ((EnRacedog*)npc)->unk_1E8)) { + ActorCutscene_Stop(this->unk_430); + this->unk_3F4 = npc; + this->unk_430 = ActorCutscene_GetAdditionalCutscene(this->unk_430); + return true; + } + npc = npc->next; + } + + return false; +} + +s32 func_809C2594(EnAob01* this, GlobalContext* globalCtx) { + Actor* npc = globalCtx->actorCtx.actorList[ACTORCAT_NPC].first; + + while (npc != NULL) { + if ((npc->id == ACTOR_EN_RACEDOG) && (((EnRacedog*)npc)->unk_290 == ((EnRacedog*)npc)->unk_292)) { + this->unk_3F4 = npc; + return true; + } + npc = npc->next; + } + + return false; +} + +s32 func_809C25E4(EnAob01* this, GlobalContext* globalCtx) { + Actor* npc = globalCtx->actorCtx.actorList[ACTORCAT_NPC].first; + s16 count = 0; + + while (npc != NULL) { + if ((npc->id == ACTOR_EN_RACEDOG) && (((EnRacedog*)npc)->unk_29C == 3)) { + count++; + } + npc = npc->next; + } + + if (count >= 14) { + return true; + } + + if ((count >= 10) && (DECR(this->unk_440) == 0)) { + return true; + } + return false; +} + +s32 func_809C2680(EnAob01* this) { + if ((ActorCutscene_GetLength(this->unk_430) > 0) && (ActorCutscene_GetCurrentIndex() != this->unk_430)) { + this->unk_430 = ActorCutscene_GetAdditionalCutscene(this->unk_430); + return true; + } + return false; +} + +void func_809C26E4(EnAob01* this, GlobalContext* globalCtx) { + ActorCutscene_Stop(this->unk_430); + this->unk_430 = ActorCutscene_GetAdditionalCutscene(this->unk_430); + this->actionFunc = func_809C2824; +} + +void func_809C2730(EnAob01* this, GlobalContext* globalCtx) { + if (func_809C2504(this, globalCtx) || func_809C2680(this)) { + ActorCutscene_SetIntentToPlay(this->unk_430); + this->actionFunc = func_809C2824; + } +} + +void func_809C2788(EnAob01* this, GlobalContext* globalCtx) { + this->unk_2D2 |= 0x20; + if (func_809C25E4(this, globalCtx)) { + globalCtx = globalCtx; + if (func_801A8A50(0) != 0x41) { + globalCtx->nextEntranceIndex = 0x7C10; + gSaveContext.eventInf[0] = (gSaveContext.eventInf[0] & (u8)~7) | 3; + globalCtx->unk_1887F = 0x40; + gSaveContext.nextTransition = 3; + globalCtx->sceneLoadFlag = 0x14; + } + } +} + +void func_809C2824(EnAob01* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->unk_430)) { + ActorCutscene_Start(this->unk_430, this->unk_3F4); + switch (func_800F2178(this->unk_430)) { + case 255: + this->actionFunc = func_809C26E4; + break; + + case 99: + this->actionFunc = func_809C2788; + break; + + default: + this->actionFunc = func_809C2730; + } + } else { + ActorCutscene_SetIntentToPlay(this->unk_430); + } +} + +void func_809C28B8(EnAob01* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + this->actor.flags &= ~0x10000; + func_80123E90(globalCtx, &this->actor); + this->unk_434 = gSaveContext.unk_3F5C; + switch ((gSaveContext.eventInf[0] & 0xF8) >> 3) { + case 1: + this->unk_210 = 0x352A; + this->unk_2D2 |= 0x80; + this->unk_434 *= 3; + func_801159EC(this->unk_434); + globalCtx->msgCtx.bankRupees = this->unk_434; + break; + + case 2: + this->unk_210 = 0x352B; + this->unk_2D2 |= 0x80; + this->unk_434 *= 2; + func_801159EC(this->unk_434); + globalCtx->msgCtx.bankRupees = this->unk_434; + break; + + case 3: + case 4: + case 5: + this->unk_210 = 0x352C; + func_801159EC(this->unk_434); + break; + + default: + this->unk_210 = 0x352D; + this->unk_2D2 |= 0x40; + this->unk_43C = 1; + func_800BDC5C(&this->skelAnime, D_809C3790, 1); + break; + } + + func_801518B0(globalCtx, this->unk_210, &this->actor); + this->actionFunc = func_809C2D0C; + } else if (this->actor.xzDistToPlayer < 100.0f) { + func_800B8614(&this->actor, globalCtx, 100.0f); + } +} + +void func_809C2A64(EnAob01* this, GlobalContext* globalCtx) { + u8 sp2F = func_80152498(&globalCtx->msgCtx); + + if (func_809C15BC(this)) { + if ((sp2F == 5) && func_80147624(globalCtx)) { + this->unk_434 = 0; + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + } + + if (Actor_HasParent(&this->actor, globalCtx)) { + this->unk_2D4 = this->unk_2E6; + this->unk_2DA = this->unk_2EC; + this->unk_2E0 = this->unk_2F2; + this->actor.parent = NULL; + this->actor.shape.rot.y = this->actor.world.rot.y; + if (gSaveContext.weekEventReg[8] & 0x20) { + this->actionFunc = func_809C2BE4; + } else { + gSaveContext.weekEventReg[8] |= 0x20; + this->actionFunc = func_809C2BE4; + } + } else if (gSaveContext.weekEventReg[8] & 0x20) { + func_800B8A1C(&this->actor, globalCtx, 4, 300.0f, 300.0f); + } else { + func_800B8A1C(&this->actor, globalCtx, 12, 300.0f, 300.0f); + } + } +} + +void func_809C2BE4(EnAob01* this, GlobalContext* globalCtx) { + u8 temp_v0 = func_80152498(&globalCtx->msgCtx); + + if (((temp_v0 == 5) || (temp_v0 == 6)) && func_80147624(globalCtx)) { + if (gSaveContext.weekEventReg[63] & 2) { + gSaveContext.weekEventReg[63] &= (u8)~2; + } + + if (gSaveContext.weekEventReg[63] & 1) { + gSaveContext.weekEventReg[63] &= (u8)~1; + } + + this->unk_210 = 0; + func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + gSaveContext.eventInf[0] &= (u8)~7; + this->actionFunc = func_809C2C9C; + } +} + +void func_809C2C9C(EnAob01* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + this->unk_210 = 0x354C; + func_80151938(globalCtx, this->unk_210); + this->actionFunc = func_809C1D64; + } else { + func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + } +} + +void func_809C2D0C(EnAob01* this, GlobalContext* globalCtx) { + u8 sp2F = func_80152498(&globalCtx->msgCtx); + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 4, 4000, 1); + + if (this->unk_2D2 & 0x40) { + if (!func_809C1424(this)) { + return; + } + } else if (this->unk_2D2 & 0x80) { + if (!func_809C14D0(this)) { + return; + } + } + + if ((sp2F == 5) && func_80147624(globalCtx)) { + this->unk_2D2 &= ~0x40; + this->unk_2D2 &= ~0x80; + if (this->unk_434 >= 150) { + this->unk_210 = 0x352E; + func_801518B0(globalCtx, this->unk_210, &this->actor); + this->actionFunc = func_809C2A64; + } else { + this->unk_2D4 = this->unk_2E6; + this->unk_2DA = this->unk_2EC; + this->unk_2E0 = this->unk_2F2; + + this->unk_434 = 0; + this->actor.shape.rot.y = this->actor.world.rot.y; + if (gSaveContext.weekEventReg[63] & 2) { + gSaveContext.weekEventReg[63] &= (u8)~2; + } + + if (gSaveContext.weekEventReg[63] & 1) { + gSaveContext.weekEventReg[63] &= (u8)~1; + } + + this->unk_210 = 0x354C; + func_801518B0(globalCtx, this->unk_210, &this->actor); + this->actionFunc = func_809C1D64; + gSaveContext.eventInf[0] &= (u8)~7; + } + } +} + +s32 func_809C2EC4(EnAob01* this, GlobalContext* globalCtx) { + Actor* dog = globalCtx->actorCtx.actorList[ACTORCAT_ENEMY].first; + + while (dog != NULL) { + if (dog->id == ACTOR_EN_DG) { + this->unk_432 = ((EnDg*)dog)->unk_288; + if (this->unk_432 == -1) { + return false; + } + + if (this->unk_432 == ENDG_GET_3E0(dog)) { + return true; + } + } + dog = dog->next; + } + + return false; +} + +void func_809C2F34(EnAob01* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + player->actor.world.pos.x = -4134.0f; + player->actor.world.pos.z = 1464.0f; + player->actor.shape.rot.y = player->actor.world.rot.y; + player->actor.draw = NULL; + player->stateFlags1 |= 0x20; + this->actor.world.pos.x = -4308.0f; + this->actor.world.pos.z = 1620.0f; + this->actor.prevPos = this->actor.world.pos; +} + +void func_809C2FA0(void) { + u8 i; + u8 idx; + u8 idx2; + u8 orig; + u8 orig2; + u8 sp44[7]; + u8 sp34[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, + }; + + for (i = 0; i < ARRAY_COUNT(sp34); i++) { + idx = Rand_ZeroFloat(14.0f); + orig = sp34[i]; + + sp34[i] = sp34[idx]; + sp34[idx] = orig; + } + + for (i = 0; i < ARRAY_COUNT(sp44); i++) { + gSaveContext.weekEventReg[42 + i] = 0; + sp44[i] = 0; + } + + for (i = 0; i < ARRAY_COUNT(sp34); i++) { + orig2 = sp34[i]; + idx2 = i / 2; + + if (i % 2) { + sp44[idx2] |= orig2 << 0x4; + idx = gSaveContext.weekEventReg[42 + idx2]; + gSaveContext.weekEventReg[42 + idx2] = idx | sp44[idx2]; + } else { + sp44[idx2] |= orig2; + } + } +} + +void EnAob01_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnAob01* this = THIS; + + ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_aob_Skel_000180, NULL, this->jointTable, this->morphTable, + 16); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + this->unk_43C = 0; + func_800BDC5C(&this->skelAnime, D_809C3790, 0); + Actor_SetScale(&this->actor, 0.01f); + + switch (gSaveContext.eventInf[0] & 7) { + case 0: + func_809C2FA0(); + func_809C11EC(this, globalCtx); + this->actor.flags |= 1; + this->actionFunc = func_809C2060; + break; + + case 2: + this->unk_440 = 500; + func_809C1304(this, globalCtx); + this->actor.draw = NULL; + this->unk_430 = this->actor.cutscene; + func_809C2594(this, globalCtx); + ActorCutscene_SetIntentToPlay(this->unk_430); + this->actor.flags &= ~1; + func_809C2F34(this, globalCtx); + this->actionFunc = func_809C2824; + break; + + case 3: + func_809C2FA0(); + func_809C11EC(this, globalCtx); + this->actor.flags |= 1; + this->actor.flags |= 0x10000; + this->actionFunc = func_809C28B8; + break; + } +} + +void EnAob01_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnAob01* this = THIS; + + if (!(this->unk_2D2 & 0x20)) { + gSaveContext.weekEventReg[63] &= (u8)~1; + } + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void EnAob01_Update(Actor* thisx, GlobalContext* globalCtx) { + EnAob01* this = THIS; + + this->actionFunc(this, globalCtx); + func_809C1EC8(this, globalCtx); +} + +s32 EnAob01_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnAob01* this = THIS; + UNK_TYPE sp38[] = { + &object_aob_Tex_000658, + &object_aob_Tex_000E58, + &object_aob_Tex_001658, + }; + + if (limbIndex == 15) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + *dList = object_aob_DL_003D18; + + gSPSegment(POLY_OPA_DISP++, 0x0A, Lib_SegmentedToVirtual(sp38[this->unk_3EE])); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + + if (limbIndex == 15) { + Matrix_InsertTranslation(1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->unk_2DA.y, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->unk_2DA.x * -1, MTXMODE_APPLY); + Matrix_InsertTranslation(-1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + } + + if (limbIndex == 8) { + Matrix_InsertXRotation_s(this->unk_2E0.y * -1, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->unk_2E0.x * -1, MTXMODE_APPLY); + } + + if ((limbIndex == 8) || (limbIndex == 9) || (limbIndex == 12)) { + rot->y += (s16)Math_SinS(this->unk_2F8[limbIndex]) * 200; + rot->z += (s16)Math_CosS(this->unk_318[limbIndex]) * 200; + } + return false; +} + +void EnAob01_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Vec3f D_809C3968 = { 0.0f, 0.0f, 0.0f }; + EnAob01* this = THIS; + + if (limbIndex == 15) { + Matrix_MultiplyVector3fByState(&D_809C3968, &this->actor.focus.pos); + } +} + +void EnAob01_UnkDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { +} + +void EnAob01_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnAob01* this = THIS; + Vec3f sp5C; + Vec3f sp50; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Gfx_EnvColor(globalCtx->state.gfxCtx, 50, 80, 0, 0)); + gSPSegment(POLY_OPA_DISP++, 0x09, Gfx_EnvColor(globalCtx->state.gfxCtx, 50, 80, 0, 0)); + gDPPipeSync(POLY_OPA_DISP++); + + func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnAob01_OverrideLimbDraw, EnAob01_PostLimbDraw, EnAob01_UnkDraw, &this->actor); + + if (this->actor.draw != NULL) { + func_8012C2DC(globalCtx->state.gfxCtx); + sp5C = this->actor.world.pos; + sp50.x = 0.5f; + sp50.y = 0.5f; + sp50.z = 0.5f; + func_800BC620(&sp5C, &sp50, 0xFF, globalCtx); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.h b/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.h index e0418f305..be7655fad 100644 --- a/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.h +++ b/src/overlays/actors/ovl_En_Aob_01/z_en_aob_01.h @@ -7,10 +7,38 @@ struct EnAob01; typedef void (*EnAob01ActionFunc)(struct EnAob01*, GlobalContext*); +#define ENAOB01_GET_7E00_1(thisx) ((thisx)->params & 0x7E00) +#define ENAOB01_GET_7E00_2(thisx) (((thisx)->params & 0x7E00) >> 9) + typedef struct EnAob01 { - /* 0x0000 */ Actor actor; - /* 0x0144 */ EnAob01ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x2FC]; + /* 0x000 */ Actor actor; + /* 0x144 */ EnAob01ActionFunc actionFunc; + /* 0x148 */ SkelAnime skelAnime; + /* 0x18C */ ColliderCylinder collider; + /* 0x1D8 */ Path* unk_1D8[14]; + /* 0x210 */ u16 unk_210; + /* 0x212 */ Vec3s jointTable[16]; + /* 0x272 */ Vec3s morphTable[16]; + /* 0x2D2 */ u16 unk_2D2; + /* 0x2D4 */ Vec3s unk_2D4; + /* 0x2DA */ Vec3s unk_2DA; + /* 0x2E0 */ Vec3s unk_2E0; + /* 0x2E6 */ Vec3s unk_2E6; + /* 0x2EC */ Vec3s unk_2EC; + /* 0x2F2 */ Vec3s unk_2F2; + /* 0x2F8 */ s16 unk_2F8[16]; + /* 0x318 */ s16 unk_318[16]; + /* 0x338 */ UNK_TYPE1 unk338[0xB6]; + /* 0x3EE */ s16 unk_3EE; + /* 0x3F0 */ s16 unk_3F0; + /* 0x3F4 */ Actor* unk_3F4; + /* 0x3F8 */ Actor* unk_3F8[14]; + /* 0x430 */ s16 unk_430; + /* 0x432 */ s16 unk_432; + /* 0x434 */ s32 unk_434; + /* 0x438 */ UNK_TYPE1 unk438[4]; + /* 0x43C */ s32 unk_43C; + /* 0x440 */ s16 unk_440; } EnAob01; // size = 0x444 extern const ActorInit En_Aob_01_InitVars; diff --git a/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c b/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c index bd2e07b57..bacb29395 100644 --- a/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c +++ b/src/overlays/actors/ovl_En_Arrow/z_en_arrow.c @@ -1,5 +1,5 @@ /* - * File z_en_arrow.c + * File: z_en_arrow.c * Overlay: ovl_En_Arrow * Description: Arrows and other projectiles */ diff --git a/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.c b/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.c index 9e7f4be9c..5eca6c796 100644 --- a/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.c +++ b/src/overlays/actors/ovl_En_Attack_Niw/z_en_attack_niw.c @@ -1,5 +1,5 @@ /* - * File z_en_attack_niw.c + * File: z_en_attack_niw.c * Overlay: ovl_En_Attack_Niw * Description: Attacking cucco */ diff --git a/src/overlays/actors/ovl_En_Az/z_en_az.c b/src/overlays/actors/ovl_En_Az/z_en_az.c index 5af1dac54..c5f687498 100644 --- a/src/overlays/actors/ovl_En_Az/z_en_az.c +++ b/src/overlays/actors/ovl_En_Az/z_en_az.c @@ -1,5 +1,5 @@ /* - * File z_en_az.c + * File: z_en_az.c * Overlay: ovl_En_Az * Description: Beaver Bros */ diff --git a/src/overlays/actors/ovl_En_Az/z_en_az.h b/src/overlays/actors/ovl_En_Az/z_en_az.h index 17b2b85fa..89d7c1a09 100644 --- a/src/overlays/actors/ovl_En_Az/z_en_az.h +++ b/src/overlays/actors/ovl_En_Az/z_en_az.h @@ -10,7 +10,7 @@ typedef void (*EnAzActionFunc)(struct EnAz*, GlobalContext*); typedef struct EnAz { /* 0x0000 */ Actor actor; /* 0x0144 */ EnAzActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x290]; + /* 0x0148 */ char unk_148[0x290]; } EnAz; // size = 0x3D8 extern const ActorInit En_Az_InitVars; diff --git a/src/overlays/actors/ovl_En_Baba/z_en_baba.c b/src/overlays/actors/ovl_En_Baba/z_en_baba.c index afe4f44ca..4593ec4b0 100644 --- a/src/overlays/actors/ovl_En_Baba/z_en_baba.c +++ b/src/overlays/actors/ovl_En_Baba/z_en_baba.c @@ -1,5 +1,5 @@ /* - * File z_en_baba.c + * File: z_en_baba.c * Overlay: ovl_En_Baba * Description: Bomb Shop Lady */ diff --git a/src/overlays/actors/ovl_En_Baguo/z_en_baguo.c b/src/overlays/actors/ovl_En_Baguo/z_en_baguo.c index 1e84a0f7b..c776dc696 100644 --- a/src/overlays/actors/ovl_En_Baguo/z_en_baguo.c +++ b/src/overlays/actors/ovl_En_Baguo/z_en_baguo.c @@ -5,6 +5,8 @@ */ #include "z_en_baguo.h" +#include "objects/object_gmo/object_gmo.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x00000005 @@ -106,16 +108,11 @@ static DamageTable sDamageTable = { /* Powder Keg */ DMG_ENTRY(1, NEJIRON_DMGEFF_KILL), }; -extern Gfx D_060014C8; -extern Gfx D_060018C8; -extern Gfx D_06001CC8; -extern SkeletonHeader D_060020E8; - void EnBaguo_Init(Actor* thisx, GlobalContext* globalCtx) { EnBaguo* this = THIS; ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 0.0f); - SkelAnime_Init(globalCtx, &this->skelAnime, &D_060020E8, NULL, this->jointTable, this->morphTable, 3); + SkelAnime_Init(globalCtx, &this->skelAnime, &gNejironSkel, NULL, this->jointTable, this->morphTable, 3); this->actor.hintId = 0xB; this->maxDistanceFromHome = 240.0f; this->maxDistanceFromHome += this->actor.world.rot.z * 40.0f; @@ -203,8 +200,8 @@ void EnBaguo_Idle(EnBaguo* this, GlobalContext* globalCtx) { yaw = this->actor.yawTowardsPlayer - this->actor.world.rot.y; absoluteYaw = ABS_ALT(yaw); - Math_Vec3f_Copy(&this->targetRotation, &D_801D15B0); - Math_Vec3f_Copy(&this->currentRotation, &D_801D15B0); + Math_Vec3f_Copy(&this->targetRotation, &gZeroVec3f); + Math_Vec3f_Copy(&this->currentRotation, &gZeroVec3f); if (absoluteYaw < 0x2000) { this->targetRotation.x = 2000.0f; } else { @@ -390,7 +387,7 @@ void EnBaguo_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, } void EnBaguo_DrawBody(Actor* thisx, GlobalContext* globalCtx) { - static TexturePtr sEyeTextures[] = { &D_060014C8, &D_060018C8, &D_06001CC8 }; + static TexturePtr sEyeTextures[] = { &gNejironEyeOpenTex, &gNejironEyeHalfTex, &gNejironEyeClosedTex }; EnBaguo* this = THIS; Gfx* gfx; s32 eyeIndex; @@ -483,7 +480,7 @@ void EnBaguo_DrawRockParticles(EnBaguo* this, GlobalContext* globalCtx) { Matrix_Scale(particle->scale, particle->scale, particle->scale, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gDPSetPrimColor(POLY_OPA_DISP++, 0, 1, 255, 255, 255, 255); - gSPDisplayList(POLY_OPA_DISP++, &D_0401FA40); + gSPDisplayList(POLY_OPA_DISP++, &gameplay_keep_DL_01FA40); } } CLOSE_DISPS(gfxCtx); diff --git a/src/overlays/actors/ovl_En_Bal/z_en_bal.c b/src/overlays/actors/ovl_En_Bal/z_en_bal.c index aa48ac9c6..dbfa561c6 100644 --- a/src/overlays/actors/ovl_En_Bal/z_en_bal.c +++ b/src/overlays/actors/ovl_En_Bal/z_en_bal.c @@ -1,7 +1,7 @@ /* - * File z_en_bal.c + * File: z_en_bal.c * Overlay: ovl_En_Bal - * Description: Tingle With Balloon + * Description: Tingle with Balloon */ #include "z_en_bal.h" diff --git a/src/overlays/actors/ovl_En_Bat/z_en_bat.c b/src/overlays/actors/ovl_En_Bat/z_en_bat.c index de2330bb8..a419d2901 100644 --- a/src/overlays/actors/ovl_En_Bat/z_en_bat.c +++ b/src/overlays/actors/ovl_En_Bat/z_en_bat.c @@ -1,5 +1,5 @@ /* - * File z_en_bat.c + * File: z_en_bat.c * Overlay: ovl_En_Bat * Description: Bad Bat */ diff --git a/src/overlays/actors/ovl_En_Bat/z_en_bat.h b/src/overlays/actors/ovl_En_Bat/z_en_bat.h index d1f949f44..2ccaaa892 100644 --- a/src/overlays/actors/ovl_En_Bat/z_en_bat.h +++ b/src/overlays/actors/ovl_En_Bat/z_en_bat.h @@ -10,7 +10,7 @@ typedef void (*EnBatActionFunc)(struct EnBat*, GlobalContext*); typedef struct EnBat { /* 0x0000 */ Actor actor; /* 0x0144 */ EnBatActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x94]; + /* 0x0148 */ char unk_148[0x94]; } EnBat; // size = 0x1DC extern const ActorInit En_Bat_InitVars; diff --git a/src/overlays/actors/ovl_En_Bb/z_en_bb.c b/src/overlays/actors/ovl_En_Bb/z_en_bb.c index cfbb8240e..cd8c7cac8 100644 --- a/src/overlays/actors/ovl_En_Bb/z_en_bb.c +++ b/src/overlays/actors/ovl_En_Bb/z_en_bb.c @@ -1,5 +1,5 @@ /* - * File z_en_bb.c + * File: z_en_bb.c * Overlay: ovl_En_Bb * Description: Blue Bubble */ diff --git a/src/overlays/actors/ovl_En_Bba_01/z_en_bba_01.c b/src/overlays/actors/ovl_En_Bba_01/z_en_bba_01.c index 5a393e7c2..0ee8d32e3 100644 --- a/src/overlays/actors/ovl_En_Bba_01/z_en_bba_01.c +++ b/src/overlays/actors/ovl_En_Bba_01/z_en_bba_01.c @@ -1,7 +1,7 @@ /* - * File z_en_bba_01.c + * File: z_en_bba_01.c * Overlay: ovl_En_Bba_01 - * Description: + * Description: Unused Bomb Shop Lady NPC */ #include "z_en_bba_01.h" diff --git a/src/overlays/actors/ovl_En_Bba_01/z_en_bba_01.h b/src/overlays/actors/ovl_En_Bba_01/z_en_bba_01.h index 157ac7eaf..20416b4f9 100644 --- a/src/overlays/actors/ovl_En_Bba_01/z_en_bba_01.h +++ b/src/overlays/actors/ovl_En_Bba_01/z_en_bba_01.h @@ -10,7 +10,7 @@ typedef void (*EnBba01ActionFunc)(struct EnBba01*, GlobalContext*); typedef struct EnBba01 { /* 0x0000 */ Actor actor; /* 0x0144 */ EnBba01ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x4D4]; + /* 0x0148 */ char unk_148[0x4D4]; } EnBba01; // size = 0x61C extern const ActorInit En_Bba_01_InitVars; diff --git a/src/overlays/actors/ovl_En_Bbfall/z_en_bbfall.c b/src/overlays/actors/ovl_En_Bbfall/z_en_bbfall.c index 97c44ce5f..080579156 100644 --- a/src/overlays/actors/ovl_En_Bbfall/z_en_bbfall.c +++ b/src/overlays/actors/ovl_En_Bbfall/z_en_bbfall.c @@ -1,5 +1,5 @@ /* - * File z_en_bbfall.c + * File: z_en_bbfall.c * Overlay: ovl_En_Bbfall * Description: Red Bubble */ diff --git a/src/overlays/actors/ovl_En_Bee/z_en_bee.c b/src/overlays/actors/ovl_En_Bee/z_en_bee.c index eeb8af33c..1bf4d8d8c 100644 --- a/src/overlays/actors/ovl_En_Bee/z_en_bee.c +++ b/src/overlays/actors/ovl_En_Bee/z_en_bee.c @@ -1,5 +1,5 @@ /* - * File z_en_bee.c + * File: z_en_bee.c * Overlay: ovl_En_Bee * Description: Giant Bee */ diff --git a/src/overlays/actors/ovl_En_Bh/z_en_bh.c b/src/overlays/actors/ovl_En_Bh/z_en_bh.c index fdffeca26..ff6cb047d 100644 --- a/src/overlays/actors/ovl_En_Bh/z_en_bh.c +++ b/src/overlays/actors/ovl_En_Bh/z_en_bh.c @@ -1,7 +1,7 @@ /* - * File z_en_bh.c + * File: z_en_bh.c * Overlay: ovl_En_Bh - * Description: Brown Bird + * Description: Brown Bird (on the Moon) */ #include "z_en_bh.h" diff --git a/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c b/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c index 364e1205f..65ef97e26 100644 --- a/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c +++ b/src/overlays/actors/ovl_En_Bigokuta/z_en_bigokuta.c @@ -1,5 +1,5 @@ /* - * File z_en_bigokuta.c + * File: z_en_bigokuta.c * Overlay: ovl_En_Bigokuta * Description: Big Octo */ diff --git a/src/overlays/actors/ovl_En_Bigpamet/z_en_bigpamet.c b/src/overlays/actors/ovl_En_Bigpamet/z_en_bigpamet.c index a1d663f61..7608bed53 100644 --- a/src/overlays/actors/ovl_En_Bigpamet/z_en_bigpamet.c +++ b/src/overlays/actors/ovl_En_Bigpamet/z_en_bigpamet.c @@ -1,5 +1,5 @@ /* - * File z_en_bigpamet.c + * File: z_en_bigpamet.c * Overlay: ovl_En_Bigpamet * Description: Gekko & Snapper Miniboss - Snapper */ diff --git a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c index b11647ddf..43b7d3feb 100644 --- a/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c +++ b/src/overlays/actors/ovl_En_Bigpo/z_en_bigpo.c @@ -1,10 +1,12 @@ /* - * File z_en_bigpo.c - * Overlay: ovl_En_Bigpi - * Description: Big Poe. Leader of the Poes, found under Dampe's house and in Beneath the Well + * File: z_en_bigpo.c + * Overlay: ovl_En_Bigpo + * Description: Big Poe. Found under Dampe's house and in Beneath the Well */ #include "z_en_bigpo.h" +#include "objects/object_bigpo/object_bigpo.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x00001215 @@ -32,6 +34,7 @@ void EnBigpo_SpawnCutsceneStage6(EnBigpo* this, GlobalContext* globalCtx); void EnBigpo_SpawnCutsceneStage7(EnBigpo* this); void EnBigpo_SpawnCutsceneStage8(EnBigpo* this, GlobalContext* globalCtx); +s32 EnBigpo_ApplyDamage(EnBigpo* this, GlobalContext* globalCtx); void EnBigpo_LowerCutsceneSubCamera(EnBigpo* this, GlobalContext* globalCtx); void EnBigpo_WellWaitForProximity(EnBigpo* this, GlobalContext* globalCtx); void EnBigpo_WaitCutsceneQueue(EnBigpo* this, GlobalContext* globalCtx); @@ -48,7 +51,6 @@ void EnBigpo_SpinAttack(EnBigpo* this, GlobalContext* globalCtx); void EnBigpo_SetupSpinDown(EnBigpo* this); void EnBigpo_SpinningDown(EnBigpo* this, GlobalContext* globalCtx); void EnBigpo_CheckHealth(EnBigpo* this, GlobalContext* globalCtx); -s32 EnBigpo_ApplyDamage(EnBigpo* this, GlobalContext* globalCtx); void EnBigpo_SetupDeath(EnBigpo* this); void EnBigpo_BurnAwayDeath(EnBigpo* this, GlobalContext* globalCtx); void EnBigpo_SetupLanternDrop(EnBigpo* this, GlobalContext* globalCtx); @@ -80,17 +82,6 @@ void EnBigpo_DrawLantern(Actor* thisx, GlobalContext* globalCtx); void EnBigpo_DrawCircleFlames(Actor* thisx, GlobalContext* globalCtx); void EnBigpo_RevealedFire(Actor* thisx, GlobalContext* globalCtx); -extern AnimationHeader D_06001360; -extern SkeletonHeader D_06005C18; -extern AnimationHeader D_06000924; -extern AnimationHeader D_06000924; -extern AnimationHeader D_06000454; -extern Gfx D_060041A0; -extern Gfx D_06001BB0; -extern Gfx D_060058B8; -extern Gfx D_060042C8; -extern Gfx D_060043F8; - extern const ActorInit En_Bigpo_InitVars; const ActorInit En_Bigpo_InitVars = { @@ -203,7 +194,7 @@ void EnBigpo_Init(Actor* thisx, GlobalContext* globalCtx2) { return; } - SkelAnime_Init(globalCtx, &this->skelAnime, &D_06005C18, &D_06000924, this->jointTable, this->morphTable, + SkelAnime_Init(globalCtx, &this->skelAnime, &gBigpoSkeleton, &gBigpoFloatAnim, this->jointTable, this->morphTable, ENBIGPO_LIMBCOUNT); Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); CollisionCheck_SetInfo(&thisx->colChkInfo, &sDamageTable, &sColChkInfoInit); @@ -244,7 +235,7 @@ void EnBigpo_Destroy(Actor* thisx, GlobalContext* globalCtx) { if ((this->actor.params != ENBIGPO_POSSIBLEFIRE) && (this->actor.params != ENBIGPO_CHOSENFIRE) && (this->actor.params != ENBIGPO_REVEALEDFIRE) && (this->actor.params != ENBIGPO_UNK5)) { - // if NOT a fire type, *ENBIGPO_REGULAR and ENBIGPO_SUMMONED combat types only) + // if NOT a fire type, *ENBIGPO_REGULAR and ENBIGPO_SUMMONED (combat types only) if (1) {} globalCtx2 = globalCtx; for (fireCount = 0; fireCount < ARRAY_COUNT(this->fires); fireCount++) { @@ -254,7 +245,7 @@ void EnBigpo_Destroy(Actor* thisx, GlobalContext* globalCtx) { } } -void func_80B61914(EnBigpo* this) { +void EnBigpo_RotateSpawnCutsceneFires(EnBigpo* this) { EnBigpoFireEffect* firePtr; s32 i; @@ -275,7 +266,9 @@ void EnBigpo_UpdateSpin(EnBigpo* this) { } } -// Lowers the position/eye of the camera during the Big Poe spawn cutscene +/* + * Lowers the position/eye of the camera during the Big Poe spawn cutscene + */ void EnBigpo_LowerCutsceneSubCamera(EnBigpo* this, GlobalContext* globalContext) { Camera* subCam; @@ -330,7 +323,7 @@ void EnBigpo_SpawnCutsceneStage1(EnBigpo* this, GlobalContext* globalCtx) { this->actor.draw = EnBigpo_DrawCircleFlames; this->actor.shape.rot.y = BINANG_ROT180(this->actor.yawTowardsPlayer); - func_80B61914(this); + EnBigpo_RotateSpawnCutsceneFires(this); for (i = 0; i < ARRAY_COUNT(this->fires); i++) { this->fires[i].pos.y = this->actor.world.pos.y; @@ -383,7 +376,7 @@ void EnBigpo_SpawnCutsceneStage4(EnBigpo* this, GlobalContext* globalCtx) { this->actor.velocity.y += 0.25f; } this->actor.shape.rot.y += this->rotVelocity; - func_80B61914(this); + EnBigpo_RotateSpawnCutsceneFires(this); if (1) {} for (i = 0; i < ARRAY_COUNT(this->fires); i++) { @@ -402,7 +395,7 @@ void EnBigpo_SpawnCutsceneStage4(EnBigpo* this, GlobalContext* globalCtx) { * big poe starts to visibly appear */ void EnBigpo_SpawnCutsceneStage5(EnBigpo* this) { - Animation_PlayLoop(&this->skelAnime, &D_06001360); + Animation_PlayLoop(&this->skelAnime, &gBigpoAwakenStretchAnim); this->actor.draw = EnBigpo_DrawMainBigpo; Actor_SetScale(&this->actor, 0.014f); Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_APPEAR); @@ -420,7 +413,7 @@ void EnBigpo_SpawnCutsceneStage6(EnBigpo* this, GlobalContext* globalCtx) { SkelAnime_Update(&this->skelAnime); this->actor.shape.rot.y += this->rotVelocity; alphaPlus = this->mainColor.a + 10; // decrease transparency - func_80B61914(this); + EnBigpo_RotateSpawnCutsceneFires(this); if (alphaPlus >= 90) { this->rotVelocity -= 0x80; this->actor.velocity.y -= 0.25f; @@ -471,7 +464,7 @@ void EnBigpo_SpawnCutsceneStage8(EnBigpo* this, GlobalContext* globalCtx) { Play_CameraSetAtEye(globalCtx, MAIN_CAM, &subCam->at, &subCam->eye); this->cutsceneSubCamId = SUBCAM_FREE; if (this->actor.params == ENBIGPO_SUMMONED) { - dampe = func_ActorCategoryIterateById(globalCtx, NULL, ACTORCAT_NPC, ACTOR_EN_TK); + dampe = SubS_FindActor(globalCtx, NULL, ACTORCAT_NPC, ACTOR_EN_TK); if (dampe != NULL) { // if dampe exists, switch to viewing his running away cutscene dampe->params = this->actor.cutscene; @@ -516,7 +509,7 @@ void EnBigpo_SetupWarpIn(EnBigpo* this, GlobalContext* globalCtx) { s16 randomYaw = (Rand_Next() >> 0x14) + this->actor.yawTowardsPlayer; Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKIDS_APPEAR); - Animation_PlayLoop(&this->skelAnime, &D_06001360); + Animation_PlayLoop(&this->skelAnime, &gBigpoAwakenStretchAnim); this->rotVelocity = 0x2000; this->actor.world.pos.x = (Math_SinS(randomYaw) * distance) + player->actor.world.pos.x; this->actor.world.pos.z = (Math_CosS(randomYaw) * distance) + player->actor.world.pos.z; @@ -543,7 +536,7 @@ void EnBigpo_WarpingIn(EnBigpo* this, GlobalContext* globalCtx) { } void EnBigpo_SetupIdleFlying(EnBigpo* this) { - Animation_MorphToLoop(&this->skelAnime, &D_06000924, -5.0f); + Animation_MorphToLoop(&this->skelAnime, &gBigpoFloatAnim, -5.0f); // if poe missed attack, idle 4 seconds, otherwise its reappearing: attack immediately this->idleTimer = (this->actionFunc == EnBigpo_SpinningDown) ? 80 : 0; this->hoverHeightCycleTimer = 40; @@ -654,7 +647,7 @@ void EnBigpo_SpinningDown(EnBigpo* this, GlobalContext* globalCtx) { * called by EnBigpo_ApplyDamage */ void EnBigpo_HitStun(EnBigpo* this) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_06000454, -6.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &gBigpoShockAnim, -6.0f); func_800BCB70(&this->actor, 0x4000, 0xFF, 0, 0x10); this->collider.base.acFlags &= ~AC_ON; func_800BE504(&this->actor, &this->collider); @@ -714,13 +707,13 @@ void EnBigpo_BurnAwayDeath(EnBigpo* this, GlobalContext* globalCtx) { // not sure what we're turning this into, but its based on the timer modifiedTimer = ((f32)((this->idleTimer * 10) + 80) * 1.4000001f); - func_800B3030(globalCtx, &tempVec, &D_80B6506C, &D_801D15B0, modifiedTimer, 0, 2); + func_800B3030(globalCtx, &tempVec, &D_80B6506C, &gZeroVec3f, modifiedTimer, 0, 2); tempVec.x = (2.0f * this->actor.world.pos.x) - tempVec.x; tempVec.z = (2.0f * this->actor.world.pos.z) - tempVec.z; - func_800B3030(globalCtx, &tempVec, &D_80B6506C, &D_801D15B0, modifiedTimer, 0, 2); + func_800B3030(globalCtx, &tempVec, &D_80B6506C, &gZeroVec3f, modifiedTimer, 0, 2); tempVec.x = this->actor.world.pos.x; tempVec.z = this->actor.world.pos.z; - func_800B3030(globalCtx, &tempVec, &D_80B6506C, &D_801D15B0, modifiedTimer, 0, 2); + func_800B3030(globalCtx, &tempVec, &D_80B6506C, &gZeroVec3f, modifiedTimer, 0, 2); } else if (this->idleTimer >= 28) { EnBigpo_SetupLanternDrop(this, globalCtx); @@ -764,7 +757,8 @@ void EnBigpo_LanternFalling(EnBigpo* this, GlobalContext* globalCtx) { Actor_SetSwitchFlag(globalCtx, this->switchFlags); } - EffectSsHahen_SpawnBurst(globalCtx, &this->actor.world.pos, 6.0f, 0, 1, 1, 15, OBJECT_BIGPO, 10, &D_060041A0); + EffectSsHahen_SpawnBurst(globalCtx, &this->actor.world.pos, 6.0f, 0, 1, 1, 15, OBJECT_BIGPO, 10, + gBigpoDrawLanternFallingDL); EnBigpo_SpawnScoopSoul(this); } } @@ -1252,7 +1246,7 @@ void EnBigpo_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, if ((this->actionFunc == EnBigpo_BurnAwayDeath) && (this->idleTimer >= 2) && (limbIndex == 8)) { gSPMatrix((*gfx)++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList((*gfx)++, &D_060058B8); + gSPDisplayList((*gfx)++, &gBigpoDrawCrispyBodyDL); } if (limbIndex == 7) { @@ -1305,7 +1299,7 @@ void EnBigpo_DrawMainBigpo(Actor* thisx, GlobalContext* globalCtx) { // fully visible OR fully transparent dispHead = POLY_OPA_DISP; gSPDisplayList(dispHead, &sSetupDL[6 * 0x19]); - gSPSegment(&dispHead[1], 0x0C, &D_801AEFA0); + gSPSegment(&dispHead[1], 0x0C, &D_801AEFA0); // empty display list for no transparency gSPSegment(&dispHead[2], 0x08, Gfx_EnvColor(globalCtx->state.gfxCtx, this->mainColor.r, this->mainColor.g, this->mainColor.b, this->mainColor.a)); @@ -1315,7 +1309,7 @@ void EnBigpo_DrawMainBigpo(Actor* thisx, GlobalContext* globalCtx) { } else { dispHead = POLY_XLU_DISP; gSPDisplayList(dispHead, &sSetupDL[6 * 0x19]); - gSPSegment(&dispHead[1], 0x0C, &D_801AEF88); + gSPSegment(&dispHead[1], 0x0C, &D_801AEF88); // transparency display list gSPSegment(&dispHead[2], 0x08, Gfx_EnvColor(globalCtx->state.gfxCtx, this->mainColor.r, this->mainColor.g, this->mainColor.b, this->mainColor.a)); @@ -1360,7 +1354,7 @@ void EnBigpo_DrawScoopSoul(Actor* thisx, GlobalContext* globalCtx) { gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, &D_06001BB0); + gSPDisplayList(POLY_XLU_DISP++, &gBigpoDrawSoulDL); CLOSE_DISPS(globalCtx->state.gfxCtx); } @@ -1384,7 +1378,7 @@ void EnBigpo_DrawLantern(Actor* thisx, GlobalContext* globalCtx) { magnitude2 = (magnitude > 1.0f) ? (20.0f / magnitude) : (20.0f); Math_Vec3f_Scale(&vec1, magnitude2); } else { - Math_Vec3f_Copy(&vec1, &D_801D15B0); + Math_Vec3f_Copy(&vec1, &gZeroVec3f); } { @@ -1412,9 +1406,9 @@ void EnBigpo_DrawLantern(Actor* thisx, GlobalContext* globalCtx) { gSPMatrix(&dispHead[3], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(&dispHead[4], &D_060042C8); + gSPDisplayList(&dispHead[4], &gBigpoDrawLanternMainDL); - gSPDisplayList(&dispHead[5], &D_060043F8); + gSPDisplayList(&dispHead[5], &gBigpoDrawLanternPurpleTopDL); // fully transparent OR fully invisible if ((this->mainColor.a == 255) || (this->mainColor.a == 0)) { @@ -1461,7 +1455,7 @@ void EnBigpo_DrawCircleFlames(Actor* thisx, GlobalContext* globalCtx) { gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, &D_0407D590); // flame displaylist + gSPDisplayList(POLY_XLU_DISP++, &gGameplayKeepDrawFlameDL); } CLOSE_DISPS(globalCtx->state.gfxCtx); @@ -1488,7 +1482,7 @@ void EnBigpo_RevealedFire(Actor* thisx, GlobalContext* globalCtx) { gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, &D_0407D590); // flame displaylist + gSPDisplayList(POLY_XLU_DISP++, &gGameplayKeepDrawFlameDL); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.c b/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.c index 2d2ad5a3f..0133b303a 100644 --- a/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.c +++ b/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.c @@ -1,10 +1,12 @@ /* - * File z_en_bigslime.c + * File: z_en_bigslime.c * Overlay: ovl_En_Bigslime - * Description: Mad Jelly (miniboss) + * Description: Mad Jelly & Gekko Miniboss: Fused Jellies & Gekko */ #include "z_en_bigslime.h" +#include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" +#include "objects/object_bigslime/object_bigslime.h" #define FLAGS 0x00000235 @@ -12,40 +14,200 @@ void EnBigslime_Init(Actor* thisx, GlobalContext* globalCtx); void EnBigslime_Destroy(Actor* thisx, GlobalContext* globalCtx); -void EnBigslime_Update(Actor* thisx, GlobalContext* globalCtx); -void EnBigslime_Draw(Actor* thisx, GlobalContext* globalCtx); +void EnBigslime_UpdateGekko(Actor* thisx, GlobalContext* globalCtx); +void EnBigslime_DrawGekko(Actor* thisx, GlobalContext* globalCtx); -void func_808E6E80(EnBigslime* this, GlobalContext* globalCtx); -void func_808E6F50(EnBigslime* this, GlobalContext* globalCtx); -void func_808E7048(EnBigslime* this, GlobalContext* globalCtx); -void func_808E71FC(EnBigslime* this, GlobalContext* globalCtx); -void func_808E7354(EnBigslime* this, GlobalContext* globalCtx); -void func_808E7B80(EnBigslime* this, GlobalContext* globalCtx); -void func_808E84DC(EnBigslime* this, GlobalContext* globalCtx); -void func_808E89CC(EnBigslime* this, GlobalContext* globalCtx); -void func_808E8CCC(EnBigslime* this, GlobalContext* globalCtx); -void func_808E91EC(EnBigslime* this, GlobalContext* globalCtx); -void func_808E97D0(EnBigslime* this, GlobalContext* globalCtx); -void func_808E9AE0(EnBigslime* this, GlobalContext* globalCtx); -void func_808E9DD0(EnBigslime* this, GlobalContext* globalCtx); -void func_808E9FC0(EnBigslime* this, GlobalContext* globalCtx); -void func_808EA1C8(EnBigslime* this, GlobalContext* globalCtx); -void func_808EA2D0(EnBigslime* this, GlobalContext* globalCtx); -void func_808EA5E8(EnBigslime* this, GlobalContext* globalCtx); -void func_808EA7A4(EnBigslime* this, GlobalContext* globalCtx); -void func_808EA860(EnBigslime* this, GlobalContext* globalCtx); -void func_808EA9B8(EnBigslime* this, GlobalContext* globalCtx); -void func_808EAA8C(EnBigslime* this, GlobalContext* globalCtx); -void func_808EAB74(EnBigslime* this, GlobalContext* globalCtx); -void func_808EACEC(EnBigslime* this, GlobalContext* globalCtx); -void func_808EB0A8(EnBigslime* this, GlobalContext* globalCtx); -void func_808EB24C(EnBigslime* this, GlobalContext* globalCtx); -void func_808EB574(EnBigslime* this, GlobalContext* globalCtx); -void func_808EB708(EnBigslime* this, GlobalContext* globalCtx); -void func_808EB804(EnBigslime* this, GlobalContext* globalCtx); -void func_808EB8B4(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_EndCutscene(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_CutsceneStartBattle(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupCutsceneNoticePlayer(EnBigslime* this); +void EnBigslime_CutsceneNoticePlayer(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupCallMinislime(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_CallMinislime(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_MoveOnCeiling(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupDrop(EnBigslime* this); +void EnBigslime_Drop(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetTargetVtxToWideCone(EnBigslime* this); +void EnBigslime_SquishFlat(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupSquishFlat(EnBigslime* this); +void EnBigslime_SetTargetVtxToThinCone(EnBigslime* this); +void EnBigslime_SetTargetVtxToInverseCone(EnBigslime* this); +void EnBigslime_SetTargetVtxToStaticVtx(EnBigslime* this); +void EnBigslime_SetupRise(EnBigslime* this); +void EnBigslime_Rise(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_CutsceneGrabPlayer(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupAttackPlayerInBigslime(EnBigslime* this); +void EnBigslime_AttackPlayerInBigslime(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupWindupThrowPlayer(EnBigslime* this); +void EnBigslime_WindupThrowPlayer(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupSetDynamicVtxThrowPlayer(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetDynamicVtxThrowPlayer(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupFrozenGround(EnBigslime* this); +void EnBigslime_FrozenGround(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_Freeze(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_Melt(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupFrozenFall(EnBigslime* this); +void EnBigslime_FrozenFall(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupJumpGekko(EnBigslime* this); +void EnBigslime_JumpGekko(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupIdleLookAround(EnBigslime* this); +void EnBigslime_IdleLookAround(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupIdleNoticePlayer(EnBigslime* this); +void EnBigslime_IdleNoticePlayer(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupThrowMinislime(EnBigslime* this); +void EnBigslime_DamageGekko(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_StunGekko(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_CutsceneFormBigslime(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupFormBigslime(EnBigslime* this); +void EnBigslime_FormBigslime(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_CutsceneDefeat(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupGekkoDespawn(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_GekkoDespawn(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupFrogSpawn(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_FrogSpawn(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupDespawn(EnBigslime* this); +void EnBigslime_Despawn(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupInitEntrance(EnBigslime* this); +void EnBigslime_InitEntrance(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_ThrowMinislime(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_SetupCutscene(EnBigslime* this); +void EnBigslime_PlayCutscene(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_AddIceShardEffect(EnBigslime* this, GlobalContext* globalCtx); +void EnBigslime_UpdateBigslime(Actor* thisx, GlobalContext* globalCtx); +void EnBigslime_DrawBigslime(Actor* thisx, GlobalContext* globalCtx); +void EnBigslime_DrawShatteringEffects(EnBigslime* this, GlobalContext* globalCtx); + +/* + * Bigslime Spherical Vtx Data: + * - The vtx data for Bigslime is put directly into the overlay + * - This vtx is directly manipulated in a significant number of functions in this overlay + * - The initialized vtx data has the following properties: (some of this data may change as overlay functions are + * called) + * -- It is a sphere with radius 1000 + * -- There are 162 vertices numbered top to bottom along the y-axis, + * with vertex 0 being the top apex, and vertex 161 being the bottom apex + * -- There are 4 entire copies of the sphere + * --- The first 3 copies are identical + * --- All 4 copies have identical coordinates and number of vertices + * --- See below (variants) for the uses of these copies + * + * Vtx Rings: + * - The vtx mesh was designed to be seperated into distint "rings" of vertices and faces + * from top to bottom at discrete y-intervals + * - These different rings of vertices lie in the xzPlane along discrete y-direction steps of the sphere + * -- There are the single apex nodes at the top (vertex 0 y-coordiante 1000) and bottom (vertex 161 + * y-coordiante -1000) + * -- There are a cluster of vertices (vertex 1-5) which all have y-coordinate 962 + * and form a ring of vertices in the xz-plane + * -- There are a cluster of vertices (vertex 6-15) which all have y-coordinate around 870 + * and form a ring of vertices in the xz-plane + * -- So on and so forth (See sVtxRingStartIndex) + * -- BIGSLIME_NUM_RING_VTX: There are a total of 13 rings of vertices including the two single apex vertex + * -- BIGSLIME_NUM_RING_FACES: There are a total of 12 rings of faces between the rings of vertices + * - A collider is assigned to each of the 12 rings of faces for bigslime + * + * Three Variants of the Spherical Vtx: + * Static (1 copy): + * - Fixed mesh, no values are ever modified + * - Used as reference to store the original vertices + * - Never drawn, only used in calculations + * Dynamic (2 copies): + * - Coordinate are updated and deformed, mesh is drawn as the deforming Fused Jelly. + * - Initially Identical to Static. + * - Two copies are used that alternate every frame and copies over coordinates/normals immediately. + * One copy is the version that is drawn, and the other copy is updated in the background + * - Alpha values remain fixed + * Target (1 copy): + * - Used to define the target vertices/shape for the dynamic vertices to smoothly step to. + * - When frozen: + * -- The current target vertices are set to the current dynamic vertices + * -- These are the vertices that are used to draw the frozen Fused Jelly + * -- The alpha values are used for the frozen effects alpha + */ + +// Reference data: used to store the original vertices +static Vtx sBigslimeStaticVtx[BIGSLIME_NUM_VTX] = { +#include "overlays/ovl_En_Bigslime/sBigslimeStaticVtx.vtx.inc" +}; + +// Dynamic data: used to draw the real shape and has 2 states +static Vtx sBigslimeDynamicVtx[2][BIGSLIME_NUM_VTX] = { + { +#include "overlays/ovl_En_Bigslime/sBigslimeDynamicState0Vtx.vtx.inc" + }, + { +#include "overlays/ovl_En_Bigslime/sBigslimeDynamicState1Vtx.vtx.inc" + }, +}; + +// Target data: used to define the shape the dynamic vertices morph to +static Vtx sBigslimeTargetVtx[BIGSLIME_NUM_VTX] = { +#include "overlays/ovl_En_Bigslime/sBigslimeTargetVtx.vtx.inc" +}; + +/* + * Triangle face + * Connectivity matrix for mesh above. Covers every triangle in the sphere + * 320 triangles x 3 vertices per triangle + * Purpose: indices to calculate/update normal vector for lighting calculations + * "EnBigslimeTri" struct based on "Tri" struct from gbi.h, but without the flag + */ +static EnBigslimeTri sEnbigslimeTri[BIGSLIME_NUM_FACES] = { + { 0, 2, 1 }, { 1, 7, 6 }, { 1, 2, 7 }, { 2, 8, 7 }, { 6, 17, 16 }, { 6, 7, 17 }, + { 8, 19, 18 }, { 7, 8, 18 }, { 7, 18, 17 }, { 9, 21, 20 }, { 0, 3, 2 }, { 2, 9, 8 }, + { 2, 3, 9 }, { 3, 10, 9 }, { 8, 20, 19 }, { 8, 9, 20 }, { 10, 22, 21 }, { 9, 10, 21 }, + { 0, 4, 3 }, { 3, 11, 10 }, { 3, 4, 11 }, { 4, 12, 11 }, { 10, 23, 22 }, { 10, 11, 23 }, + { 12, 25, 24 }, { 11, 12, 24 }, { 11, 24, 23 }, { 13, 27, 26 }, { 0, 5, 4 }, { 4, 13, 12 }, + { 4, 5, 13 }, { 5, 14, 13 }, { 12, 26, 25 }, { 12, 13, 26 }, { 14, 28, 27 }, { 13, 14, 27 }, + { 0, 1, 5 }, { 5, 15, 14 }, { 5, 1, 15 }, { 1, 6, 15 }, { 14, 29, 28 }, { 14, 15, 29 }, + { 6, 16, 30 }, { 15, 6, 30 }, { 15, 30, 29 }, { 16, 32, 31 }, { 16, 17, 32 }, { 17, 33, 32 }, + { 17, 18, 33 }, { 18, 34, 33 }, { 18, 19, 34 }, { 19, 35, 34 }, { 19, 20, 36 }, { 20, 37, 36 }, + { 20, 21, 37 }, { 21, 38, 37 }, { 21, 22, 38 }, { 22, 39, 38 }, { 19, 36, 35 }, { 22, 40, 39 }, + { 22, 23, 40 }, { 23, 41, 40 }, { 23, 24, 41 }, { 24, 42, 41 }, { 24, 25, 42 }, { 25, 43, 42 }, + { 25, 26, 44 }, { 26, 45, 44 }, { 26, 27, 45 }, { 27, 46, 45 }, { 27, 28, 46 }, { 28, 47, 46 }, + { 25, 44, 43 }, { 28, 48, 47 }, { 28, 29, 48 }, { 29, 49, 48 }, { 29, 30, 49 }, { 30, 50, 49 }, + { 30, 16, 50 }, { 16, 31, 50 }, { 31, 32, 51 }, { 32, 52, 51 }, { 32, 33, 52 }, { 33, 53, 52 }, + { 33, 34, 53 }, { 34, 54, 53 }, { 34, 35, 54 }, { 35, 55, 54 }, { 35, 36, 55 }, { 36, 56, 55 }, + { 36, 37, 56 }, { 37, 57, 56 }, { 37, 38, 57 }, { 38, 58, 57 }, { 38, 39, 58 }, { 39, 59, 58 }, + { 39, 40, 59 }, { 40, 60, 59 }, { 40, 41, 60 }, { 41, 61, 60 }, { 41, 42, 61 }, { 42, 62, 61 }, + { 42, 43, 62 }, { 43, 63, 62 }, { 51, 72, 71 }, { 51, 52, 72 }, { 52, 73, 72 }, { 52, 53, 73 }, + { 53, 74, 73 }, { 53, 54, 74 }, { 54, 75, 74 }, { 54, 55, 75 }, { 55, 76, 75 }, { 55, 56, 76 }, + { 56, 77, 76 }, { 56, 57, 77 }, { 57, 78, 77 }, { 57, 58, 78 }, { 58, 79, 78 }, { 58, 59, 79 }, + { 59, 80, 79 }, { 59, 60, 80 }, { 60, 81, 80 }, { 60, 61, 81 }, { 61, 82, 81 }, { 61, 62, 82 }, + { 62, 83, 82 }, { 62, 63, 83 }, { 71, 72, 91 }, { 72, 92, 91 }, { 72, 73, 92 }, { 73, 93, 92 }, + { 73, 74, 93 }, { 74, 94, 93 }, { 74, 75, 94 }, { 75, 95, 94 }, { 75, 76, 95 }, { 76, 96, 95 }, + { 76, 77, 96 }, { 77, 97, 96 }, { 77, 78, 97 }, { 78, 98, 97 }, { 78, 79, 98 }, { 79, 99, 98 }, + { 79, 80, 99 }, { 80, 100, 99 }, { 80, 81, 100 }, { 81, 101, 100 }, { 81, 82, 101 }, { 82, 102, 101 }, + { 82, 83, 102 }, { 83, 103, 102 }, { 91, 112, 111 }, { 91, 92, 112 }, { 92, 113, 112 }, { 92, 93, 113 }, + { 93, 114, 113 }, { 93, 94, 114 }, { 94, 115, 114 }, { 94, 95, 115 }, { 95, 116, 115 }, { 95, 96, 116 }, + { 96, 117, 116 }, { 96, 97, 117 }, { 97, 118, 117 }, { 97, 98, 118 }, { 98, 119, 118 }, { 98, 99, 119 }, + { 99, 120, 119 }, { 99, 100, 120 }, { 100, 121, 120 }, { 100, 101, 121 }, { 101, 122, 121 }, { 101, 102, 122 }, + { 102, 123, 122 }, { 102, 103, 123 }, { 43, 44, 63 }, { 44, 64, 63 }, { 44, 45, 64 }, { 45, 65, 64 }, + { 45, 46, 65 }, { 46, 66, 65 }, { 46, 47, 66 }, { 47, 67, 66 }, { 47, 48, 67 }, { 48, 68, 67 }, + { 48, 49, 68 }, { 49, 69, 68 }, { 49, 50, 69 }, { 50, 70, 69 }, { 50, 31, 70 }, { 31, 51, 70 }, + { 63, 84, 83 }, { 63, 64, 84 }, { 64, 85, 84 }, { 64, 65, 85 }, { 65, 86, 85 }, { 65, 66, 86 }, + { 66, 87, 86 }, { 66, 67, 87 }, { 67, 88, 87 }, { 67, 68, 88 }, { 68, 89, 88 }, { 68, 69, 89 }, + { 69, 90, 89 }, { 69, 70, 90 }, { 70, 71, 90 }, { 70, 51, 71 }, { 83, 84, 103 }, { 84, 104, 103 }, + { 84, 85, 104 }, { 85, 105, 104 }, { 85, 86, 105 }, { 86, 106, 105 }, { 86, 87, 106 }, { 87, 107, 106 }, + { 87, 88, 107 }, { 88, 108, 107 }, { 88, 89, 108 }, { 89, 109, 108 }, { 89, 90, 109 }, { 90, 110, 109 }, + { 90, 71, 110 }, { 71, 91, 110 }, { 103, 124, 123 }, { 103, 104, 124 }, { 104, 125, 124 }, { 104, 105, 125 }, + { 105, 126, 125 }, { 105, 106, 126 }, { 106, 127, 126 }, { 106, 107, 127 }, { 107, 128, 127 }, { 107, 108, 128 }, + { 108, 129, 128 }, { 108, 109, 129 }, { 109, 130, 129 }, { 109, 110, 130 }, { 110, 111, 130 }, { 110, 91, 111 }, + { 161, 160, 156 }, { 155, 146, 160 }, { 146, 156, 160 }, { 146, 147, 156 }, { 144, 145, 155 }, { 145, 146, 155 }, + { 145, 131, 146 }, { 131, 147, 146 }, { 131, 132, 147 }, { 134, 135, 149 }, { 161, 156, 157 }, { 147, 148, 156 }, + { 148, 157, 156 }, { 148, 149, 157 }, { 132, 133, 147 }, { 133, 148, 147 }, { 133, 134, 148 }, { 134, 149, 148 }, + { 161, 157, 158 }, { 149, 150, 157 }, { 150, 158, 157 }, { 150, 151, 158 }, { 135, 136, 149 }, { 136, 150, 149 }, + { 136, 137, 150 }, { 137, 151, 150 }, { 137, 138, 151 }, { 140, 141, 153 }, { 161, 158, 159 }, { 151, 152, 158 }, + { 152, 159, 158 }, { 152, 153, 159 }, { 138, 139, 151 }, { 139, 152, 151 }, { 139, 140, 152 }, { 140, 153, 152 }, + { 161, 159, 160 }, { 153, 154, 159 }, { 154, 160, 159 }, { 154, 155, 160 }, { 141, 142, 153 }, { 142, 154, 153 }, + { 142, 143, 154 }, { 143, 155, 154 }, { 143, 144, 155 }, { 111, 131, 145 }, { 111, 112, 131 }, { 112, 132, 131 }, + { 112, 113, 132 }, { 113, 114, 132 }, { 114, 133, 132 }, { 114, 115, 133 }, { 115, 116, 134 }, { 116, 135, 134 }, + { 116, 117, 135 }, { 117, 118, 135 }, { 118, 136, 135 }, { 118, 119, 136 }, { 115, 134, 133 }, { 119, 137, 136 }, + { 119, 120, 137 }, { 120, 138, 137 }, { 120, 121, 138 }, { 121, 122, 138 }, { 122, 139, 138 }, { 122, 123, 139 }, + { 139, 123, 140 }, { 140, 123, 124 }, { 140, 124, 141 }, { 141, 124, 125 }, { 141, 125, 126 }, { 141, 126, 142 }, + { 142, 127, 143 }, { 143, 127, 128 }, { 143, 128, 144 }, { 144, 128, 129 }, { 144, 129, 130 }, { 144, 130, 145 }, + { 142, 126, 127 }, { 130, 111, 145 }, +}; -#if 0 const ActorInit En_Bigslime_InitVars = { ACTOR_EN_BIGSLIME, ACTORCAT_BOSS, @@ -54,289 +216,2940 @@ const ActorInit En_Bigslime_InitVars = { sizeof(EnBigslime), (ActorFunc)EnBigslime_Init, (ActorFunc)EnBigslime_Destroy, - (ActorFunc)EnBigslime_Update, - (ActorFunc)EnBigslime_Draw, + (ActorFunc)EnBigslime_UpdateGekko, + (ActorFunc)EnBigslime_DrawGekko, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_808F02A0 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_NO_PUSH | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x20000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_NO_PUSH | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x20000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 30, 60, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit D_808F02CC = { 10, 100, 100, 50 }; +static CollisionCheckInfoInit sColChkInfoInit = { 10, 100, 100, 50 }; -// static DamageTable sDamageTable = { -static DamageTable D_808F02D4 = { - /* Deku Nut */ DMG_ENTRY(0, 0x1), - /* Deku Stick */ DMG_ENTRY(1, 0x0), - /* Horse trample */ DMG_ENTRY(0, 0x0), - /* Explosives */ DMG_ENTRY(1, 0xF), - /* Zora boomerang */ DMG_ENTRY(1, 0x0), - /* Normal arrow */ DMG_ENTRY(1, 0x0), - /* UNK_DMG_0x06 */ DMG_ENTRY(0, 0x0), - /* Hookshot */ DMG_ENTRY(0, 0xE), - /* Goron punch */ DMG_ENTRY(1, 0xF), - /* Sword */ DMG_ENTRY(1, 0x0), - /* Goron pound */ DMG_ENTRY(1, 0xF), - /* Fire arrow */ DMG_ENTRY(1, 0x2), - /* Ice arrow */ DMG_ENTRY(1, 0x3), - /* Light arrow */ DMG_ENTRY(2, 0x4), - /* Goron spikes */ DMG_ENTRY(1, 0xF), - /* Deku spin */ DMG_ENTRY(0, 0xD), - /* Deku bubble */ DMG_ENTRY(1, 0x0), - /* Deku launch */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x1), - /* Zora barrier */ DMG_ENTRY(0, 0x5), - /* Normal shield */ DMG_ENTRY(0, 0x0), - /* Light ray */ DMG_ENTRY(0, 0x0), - /* Thrown object */ DMG_ENTRY(1, 0xF), - /* Zora punch */ DMG_ENTRY(1, 0x0), - /* Spin attack */ DMG_ENTRY(1, 0x0), - /* Sword beam */ DMG_ENTRY(1, 0x0), - /* Normal Roll */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x1B */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x1C */ DMG_ENTRY(0, 0x0), - /* Unblockable */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x1E */ DMG_ENTRY(0, 0x0), - /* Powder Keg */ DMG_ENTRY(1, 0xF), +typedef enum { + /* 0x0 */ BIGSLIME_DMGEFF_NONE, + /* 0x0 */ BIGSLIME_DMGEFF_STUN, + /* 0x2 */ BIGSLIME_DMGEFF_FIRE, + /* 0x3 */ BIGSLIME_DMGEFF_ICE, + /* 0x4 */ BIGSLIME_DMGEFF_LIGHT, + /* 0x5 */ BIGSLIME_DMGEFF_ELECTRIC_STUN, + /* 0xD */ BIGSLIME_DMGEFF_DEKU_STUN = 0xD, + /* 0xE */ BIGSLIME_DMGEFF_HOOKSHOT, + /* 0xF */ BIGSLIME_DMGEFF_BREAK_ICE, +} BigslimeDamageEffect; + +static DamageTable sDamageTable = { + /* Deku Nut */ DMG_ENTRY(0, BIGSLIME_DMGEFF_STUN), + /* Deku Stick */ DMG_ENTRY(1, BIGSLIME_DMGEFF_NONE), + /* Horse trample */ DMG_ENTRY(0, BIGSLIME_DMGEFF_NONE), + /* Explosives */ DMG_ENTRY(1, BIGSLIME_DMGEFF_BREAK_ICE), + /* Zora boomerang */ DMG_ENTRY(1, BIGSLIME_DMGEFF_NONE), + /* Normal arrow */ DMG_ENTRY(1, BIGSLIME_DMGEFF_NONE), + /* UNK_DMG_0x06 */ DMG_ENTRY(0, BIGSLIME_DMGEFF_NONE), + /* Hookshot */ DMG_ENTRY(0, BIGSLIME_DMGEFF_HOOKSHOT), + /* Goron punch */ DMG_ENTRY(1, BIGSLIME_DMGEFF_BREAK_ICE), + /* Sword */ DMG_ENTRY(1, BIGSLIME_DMGEFF_NONE), + /* Goron pound */ DMG_ENTRY(1, BIGSLIME_DMGEFF_BREAK_ICE), + /* Fire arrow */ DMG_ENTRY(1, BIGSLIME_DMGEFF_FIRE), + /* Ice arrow */ DMG_ENTRY(1, BIGSLIME_DMGEFF_ICE), + /* Light arrow */ DMG_ENTRY(2, BIGSLIME_DMGEFF_LIGHT), + /* Goron spikes */ DMG_ENTRY(1, BIGSLIME_DMGEFF_BREAK_ICE), + /* Deku spin */ DMG_ENTRY(0, BIGSLIME_DMGEFF_DEKU_STUN), + /* Deku bubble */ DMG_ENTRY(1, BIGSLIME_DMGEFF_NONE), + /* Deku launch */ DMG_ENTRY(0, BIGSLIME_DMGEFF_NONE), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, BIGSLIME_DMGEFF_STUN), + /* Zora barrier */ DMG_ENTRY(0, BIGSLIME_DMGEFF_ELECTRIC_STUN), + /* Normal shield */ DMG_ENTRY(0, BIGSLIME_DMGEFF_NONE), + /* Light ray */ DMG_ENTRY(0, BIGSLIME_DMGEFF_NONE), + /* Thrown object */ DMG_ENTRY(1, BIGSLIME_DMGEFF_BREAK_ICE), + /* Zora punch */ DMG_ENTRY(1, BIGSLIME_DMGEFF_NONE), + /* Spin attack */ DMG_ENTRY(1, BIGSLIME_DMGEFF_NONE), + /* Sword beam */ DMG_ENTRY(1, BIGSLIME_DMGEFF_NONE), + /* Normal Roll */ DMG_ENTRY(0, BIGSLIME_DMGEFF_NONE), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, BIGSLIME_DMGEFF_NONE), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, BIGSLIME_DMGEFF_NONE), + /* Unblockable */ DMG_ENTRY(0, BIGSLIME_DMGEFF_NONE), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, BIGSLIME_DMGEFF_NONE), + /* Powder Keg */ DMG_ENTRY(1, BIGSLIME_DMGEFF_BREAK_ICE), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_808F0338[] = { +// Start vtx numbers for each ring in the vtx sphere +static s32 sVtxRingStartIndex[] = { + 0, 1, 6, 16, 31, 51, 71, 91, 111, 131, 146, 156, 161, BIGSLIME_NUM_VTX, +}; + +static AnimationHeader* sGekkoAttackAnimations[] = { + &gGekkoJabPunchAnim, + &gGekkoHookPunchAnim, + &gGekkoKickAnim, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_S8(hintId, 95, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(targetArrowOffset, -13221, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_CONTINUE), ICHAIN_U8(targetMode, 5, ICHAIN_STOP), }; -#endif - -extern ColliderCylinderInit D_808F02A0; -extern CollisionCheckInfoInit D_808F02CC; -extern DamageTable D_808F02D4; -extern InitChainEntry D_808F0338[]; - -extern UNK_TYPE D_060010F4; -extern UNK_TYPE D_06001B08; -extern UNK_TYPE D_0600276C; -extern UNK_TYPE D_06002E0C; -extern UNK_TYPE D_0600347C; -extern UNK_TYPE D_060039C4; -extern UNK_TYPE D_060066B4; -extern UNK_TYPE D_060069FC; -extern UNK_TYPE D_06007790; -extern UNK_TYPE D_0600F048; -extern UNK_TYPE D_0600F990; -extern UNK_TYPE D_0600FB40; -extern UNK_TYPE D_06010530; -extern UNK_TYPE D_06011050; -extern UNK_TYPE D_060113B0; - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/EnBigslime_Init.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/EnBigslime_Destroy.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E5388.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E5430.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E5484.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E574C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E5988.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E5A00.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E5BB0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E5ED4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E601C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E616C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E62B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E64D4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6538.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6570.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E670C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6828.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E68AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E69AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E69F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6A70.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6B08.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6B68.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6C18.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6C44.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6C70.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6CC8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6D58.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6E80.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6F08.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6F50.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E6FE0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E7048.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E7154.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E71FC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E732C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E7354.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E75D8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E7770.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E7AF8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E7B80.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E7D68.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E8064.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E836C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E844C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E84DC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E88B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E89CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E8C38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E8CCC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E90A4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E91EC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E9778.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E97D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E994C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E9AE0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E9DA8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E9DD0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E9F38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808E9FC0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA14C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA1C8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA264.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA2D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA538.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA5E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA748.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA7A4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA80C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA860.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA8FC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EA9B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EAA40.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EAA8C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EAAF8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EAB74.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EABCC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EACEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EAEBC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB0A8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB178.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB24C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB328.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB574.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB690.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB708.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB7F0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB804.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB83C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB8B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EB9E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EBBE4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EBED0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EC158.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EC354.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/EnBigslime_Update.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EC708.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808EC990.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808ECD14.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808ED07C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/EnBigslime_Draw.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bigslime/func_808ED3F4.s") +void EnBigslime_Init(Actor* thisx, GlobalContext* globalCtx) { + // gSaveContext.weekEventReg[KEY] = VALUE + // KEY | VALUE + static s32 isFrogReturnedFlags[] = { + (32 << 8) | 0x40, // Woodfall Temple Frog Returned + (32 << 8) | 0x80, // Great Bay Temple Frog Returned + (33 << 8) | 0x01, // Southern Swamp Frog Returned + (33 << 8) | 0x02, // Laundry Pool Frog Returned + }; + EnBigslime* this = THIS; + GlobalContext* globalCtx2 = globalCtx; + s32 i; + + Actor_ProcessInitChain(&this->actor, sInitChain); + CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGekkoSkel, &gGekkoLookAroundAnim, this->jointTable, + this->morphTable, GEKKO_LIMB_MAX); + + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + Collider_InitAndSetCylinder(globalCtx, &this->bigslimeCollider[i], &this->actor, &sCylinderInit); + } + + this->bigslimeCollider[0].base.atFlags &= ~AT_ON; + Collider_InitAndSetCylinder(globalCtx, &this->gekkoCollider, &this->actor, &sCylinderInit); + this->gekkoCollider.base.colType = COLTYPE_HIT6; + this->gekkoCollider.info.elemType = ELEMTYPE_UNK1; + this->gekkoCollider.base.atFlags &= ~AT_ON; + this->gekkoCollider.base.ocFlags1 &= ~OC1_NO_PUSH; + this->actor.params = CLAMP(this->actor.params, 1, 4); + + if (Actor_GetRoomCleared(globalCtx, globalCtx->roomCtx.currRoom.num)) { + Actor_MarkForDeath(&this->actor); + if (!(gSaveContext.weekEventReg[isFrogReturnedFlags[this->actor.params - 1] >> 8] & + (u8)isFrogReturnedFlags[this->actor.params - 1])) { + Actor_Spawn(&globalCtx2->actorCtx, globalCtx, ACTOR_EN_MINIFROG, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, this->actor.shape.rot.y, 0, + this->actor.params); + } + } else { + this->cutscene = this->actor.cutscene; + this->actor.scale.x = this->actor.scale.z = 0.15f; + this->actor.scale.y = 0.075f; + this->vtxScaleX = this->vtxScaleZ = 0.015000001f; + this->actor.home.pos.x = GBT_ROOM_5_CENTER_X; + this->actor.home.pos.y = GBT_ROOM_5_MAX_Y - 75.0f; + this->actor.home.pos.z = GBT_ROOM_5_CENTER_Z; + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + this->minislime[i] = (EnMinislime*)Actor_SpawnAsChild(&globalCtx2->actorCtx, &this->actor, globalCtx, + ACTOR_EN_MINISLIME, 0.0f, 0.0f, 0.0f, 0, 0, 0, i); + if (this->minislime[i] == NULL) { + for (i = i - 1; i >= 0; i--) { + Actor_MarkForDeath(&this->minislime[i]->actor); + } + + Actor_MarkForDeath(&this->actor); + return; + } + } + + this->minislimeFrozenTexAnim = Lib_SegmentedToVirtual(&gMinislimeFrozenTexAnim); + this->bigslimeFrozenTexAnim = Lib_SegmentedToVirtual(&gBigslimeFrozenTexAnim); + this->iceShardTexAnim = Lib_SegmentedToVirtual(&gBigslimeIceShardTexAnim); + this->actor.world.pos.y = GBT_ROOM_5_MIN_Y; + this->actor.flags &= ~1; + this->actor.shape.shadowAlpha = 255; + this->gekkoScale = 0.007f; + this->actor.shape.rot.y = 0; + this->minislimeToThrow = this->minislime[0]; + EnBigslime_SetupInitEntrance(this); + } +} + +void EnBigslime_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnBigslime* this = THIS; + s32 i; + + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + Collider_DestroyCylinder(globalCtx, &this->bigslimeCollider[i]); + } + + Collider_DestroyCylinder(globalCtx, &this->gekkoCollider); + func_801A72CC(&this->gekkoProjectedPos); +} + +void EnBigslime_DynamicVtxCopyState(EnBigslime* this) { + Vtx* dynamicVtxDest; + Vtx* dynamicVtxSrc; + s32 i; + s32 j; + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtxDest = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + dynamicVtxSrc = &sBigslimeDynamicVtx[this->dynamicVtxState ^ 1][i]; + for (j = 0; j < 3; j++) { + dynamicVtxDest->n.ob[j] = dynamicVtxSrc->n.ob[j]; + dynamicVtxDest->n.n[j] = dynamicVtxSrc->n.n[j]; + } + } +} + +void EnBigslime_Vec3fNormalize(Vec3f* vec) { + f32 magnitude = Math3D_Vec3fMagnitude(vec); + + if (magnitude > 1.0f) { + Math_Vec3f_Scale(vec, 1.0f / magnitude); + } +} + +/** + * Updates the surface normal vector of each vertex in the fused jelly mesh + * each frame as the dynamic vtx is constantly changing shape + */ +void EnBigslime_UpdateSurfaceNorm(EnBigslime* this) { + Vec3f vtxNorm[BIGSLIME_NUM_VTX]; + Vec3f vecTriEdge1; + Vec3f vecTriEdge2; + Vec3f vecTriNorm; + Vec3f* vtxNormAddr; + Vtx* dynamicVtx; + Vtx* dynamicVtx12; + Vtx* dynamicVtx0; + s32 i; + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + Math_Vec3f_Copy(&vtxNorm[i], &gZeroVec3f); + } + + for (i = 0; i < BIGSLIME_NUM_FACES; i++) { + dynamicVtx0 = &sBigslimeDynamicVtx[this->dynamicVtxState][sEnbigslimeTri[i].v[0]]; + dynamicVtx12 = &sBigslimeDynamicVtx[this->dynamicVtxState][sEnbigslimeTri[i].v[1]]; + vecTriEdge1.x = dynamicVtx12->n.ob[0] - dynamicVtx0->n.ob[0]; + vecTriEdge1.y = dynamicVtx12->n.ob[1] - dynamicVtx0->n.ob[1]; + vecTriEdge1.z = dynamicVtx12->n.ob[2] - dynamicVtx0->n.ob[2]; + + dynamicVtx12 = &sBigslimeDynamicVtx[this->dynamicVtxState][sEnbigslimeTri[i].v[2]]; + vecTriEdge2.x = dynamicVtx12->n.ob[0] - dynamicVtx0->n.ob[0]; + vecTriEdge2.y = dynamicVtx12->n.ob[1] - dynamicVtx0->n.ob[1]; + vecTriEdge2.z = dynamicVtx12->n.ob[2] - dynamicVtx0->n.ob[2]; + + Math3D_CrossProduct(&vecTriEdge1, &vecTriEdge2, &vecTriNorm); + EnBigslime_Vec3fNormalize(&vecTriNorm); + + Math_Vec3f_Sum(&vtxNorm[sEnbigslimeTri[i].v[0]], &vecTriNorm, &vtxNorm[sEnbigslimeTri[i].v[0]]); + Math_Vec3f_Sum(&vtxNorm[sEnbigslimeTri[i].v[1]], &vecTriNorm, &vtxNorm[sEnbigslimeTri[i].v[1]]); + Math_Vec3f_Sum(&vtxNorm[sEnbigslimeTri[i].v[2]], &vecTriNorm, &vtxNorm[sEnbigslimeTri[i].v[2]]); + } + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + vtxNormAddr = &vtxNorm[i]; + EnBigslime_Vec3fNormalize(vtxNormAddr); + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + dynamicVtx->n.n[0] = vtxNormAddr->x * 120.0f; + dynamicVtx->n.n[1] = vtxNormAddr->y * 120.0f; + dynamicVtx->n.n[2] = vtxNormAddr->z * 120.0f; + } +} + +void EnBigslime_GetMaxMinVertices(EnBigslime* this, Vec3f* vtxMax, Vec3f* vtxMin) { + Vtx* dynamicVtx; + s16 vtxMaxX = 0; + s16 vtxMaxY = 0; + s16 vtxMaxZ = 0; + s16 vtxMinX = 0; + s16 vtxMinY = 0; + s16 vtxMinZ = 0; + s32 i; + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + + if (vtxMaxX < dynamicVtx->n.ob[0]) { + vtxMaxX = dynamicVtx->n.ob[0]; + } else if (vtxMinX > dynamicVtx->n.ob[0]) { + vtxMinX = dynamicVtx->n.ob[0]; + } + + if (vtxMaxY < dynamicVtx->n.ob[1]) { + vtxMaxY = dynamicVtx->n.ob[1]; + } else if (vtxMinY > dynamicVtx->n.ob[1]) { + vtxMinY = dynamicVtx->n.ob[1]; + } + + if (vtxMaxZ < dynamicVtx->n.ob[2]) { + vtxMaxZ = dynamicVtx->n.ob[2]; + } else if (vtxMinZ > dynamicVtx->n.ob[2]) { + vtxMinZ = dynamicVtx->n.ob[2]; + } + } + + vtxMax->x = vtxMaxX * this->actor.scale.x; + vtxMax->y = vtxMaxY * this->actor.scale.y; + vtxMax->z = vtxMaxZ * this->actor.scale.z; + + vtxMin->x = vtxMinX * this->actor.scale.x; + vtxMin->y = vtxMinY * this->actor.scale.y; + vtxMin->z = vtxMinZ * this->actor.scale.z; +} + +void EnBigslime_UpdateScale(EnBigslime* this, Vec3f* vtxMax, Vec3f* vtxMin) { + if (vtxMin->x < vtxMax->x) { + this->vtxScaleX = vtxMax->x * (0.100000005f / BIGSLIME_RADIUS_F); + } else { + this->vtxScaleX = -vtxMin->x * (0.100000005f / BIGSLIME_RADIUS_F); + } + + if (vtxMin->z < vtxMax->z) { + this->vtxScaleZ = vtxMax->z * (0.100000005f / BIGSLIME_RADIUS_F); + } else { + this->vtxScaleZ = -vtxMin->z * (0.100000005f / BIGSLIME_RADIUS_F); + } +} + +/** + * Checks the world position against all walls, the floor, and the ceiling to ensure + * bigslime is not outside this range. Accounts only for the world position, and the + * maximum and minimum verticies. If any boundaries are crossed, the world position + * and bgCheckFlags are updated accordingly. + * + * Differs from EnBigslime_CheckVtxWallBoundaries by checking and updating + * a single world position instead of checking and updating individual vertices + */ +void EnBigslime_CheckRoomBoundaries(EnBigslime* this, Vec3f* vtxMax, Vec3f* vtxMin) { + f32 worldPosX; + f32 vtxMaxX; + f32 vtxMinX; + f32 worldPosZ; + f32 vtxMaxZ; + f32 vtxMinZ; + + this->actor.bgCheckFlags &= ~(0x2 | 0x8 | 0x10); + if ((this->actor.world.pos.y + vtxMax->y) > GBT_ROOM_5_MAX_Y) { + this->actor.world.pos.y = GBT_ROOM_5_MAX_Y - vtxMax->y; + this->actor.bgCheckFlags |= 0x10; + } + + if ((this->actor.world.pos.y + vtxMin->y) <= GBT_ROOM_5_MIN_Y) { + this->actor.world.pos.y = GBT_ROOM_5_MIN_Y - vtxMin->y; + if (!(this->actor.bgCheckFlags & 1)) { + this->actor.bgCheckFlags |= 2; + } + + this->actor.bgCheckFlags |= 1; + } else { + this->actor.bgCheckFlags &= ~1; + } + + if ((this->actionFunc != EnBigslime_Freeze) || !(this->actor.bgCheckFlags & 1)) { + worldPosX = this->actor.world.pos.x; + vtxMaxX = vtxMax->x; + if (GBT_ROOM_5_MAX_X < (worldPosX + vtxMaxX)) { + this->actor.bgCheckFlags |= 8; + this->actor.world.pos.x = GBT_ROOM_5_MAX_X - vtxMaxX; + } else { + vtxMinX = vtxMin->x; + if ((worldPosX + vtxMinX) < GBT_ROOM_5_MIN_X) { + this->actor.world.pos.x = GBT_ROOM_5_MIN_X - vtxMinX; + this->actor.bgCheckFlags |= 8; + } + } + + worldPosZ = this->actor.world.pos.z; + vtxMaxZ = vtxMax->z; + if (GBT_ROOM_5_MAX_Z < (worldPosZ + vtxMaxZ)) { + this->actor.bgCheckFlags |= 8; + this->actor.world.pos.z = GBT_ROOM_5_MAX_Z - vtxMaxZ; + } else { + vtxMinZ = vtxMin->z; + if ((worldPosZ + vtxMinZ) < GBT_ROOM_5_MIN_Z) { + this->actor.world.pos.z = GBT_ROOM_5_MIN_Z - vtxMinZ; + this->actor.bgCheckFlags |= 8; + } + } + } +} + +void EnBigslime_UpdateBigslimeCollider(EnBigslime* this, GlobalContext* globalCtx) { + Vtx* dynamicVtx; + f32 xzDist; + s16 vtxRingMaxY[BIGSLIME_NUM_RING_VTX]; + s16 vtxRingMinY[BIGSLIME_NUM_RING_VTX]; + f32 vtxRingMaxXZDist[BIGSLIME_NUM_RING_VTX]; + Cylinder16* dim; + f32 maxScaleXScaleZ = (this->actor.scale.z < this->actor.scale.x ? this->actor.scale.x : this->actor.scale.z); + s32 i; + s32 j; + + for (i = 0; i < BIGSLIME_NUM_RING_VTX; i++) { + vtxRingMaxY[i] = -30000; + vtxRingMinY[i] = 30000; + vtxRingMaxXZDist[i] = 0.0f; + + for (j = sVtxRingStartIndex[i]; j < sVtxRingStartIndex[i + 1]; j++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][j]; + if (vtxRingMaxY[i] < dynamicVtx->n.ob[1]) { + vtxRingMaxY[i] = dynamicVtx->n.ob[1]; + } + + if (vtxRingMinY[i] > dynamicVtx->n.ob[1]) { + vtxRingMinY[i] = dynamicVtx->n.ob[1]; + } + + xzDist = sqrtf(SQ(dynamicVtx->n.ob[0]) + SQ(dynamicVtx->n.ob[2])); + if (vtxRingMaxXZDist[i] < xzDist) { + vtxRingMaxXZDist[i] = xzDist; + } + } + } + + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + dim = &this->bigslimeCollider[i].dim; + dim->pos.y = (vtxRingMinY[i + 1] * this->actor.scale.y) + this->actor.world.pos.y; + dim->height = (vtxRingMaxY[i] - vtxRingMinY[i + 1]) * this->actor.scale.y; + dim->radius = maxScaleXScaleZ * + (vtxRingMaxXZDist[i] < vtxRingMaxXZDist[i + 1] ? vtxRingMaxXZDist[i + 1] : vtxRingMaxXZDist[i]); + dim->height = CLAMP_MIN(dim->height, 1); + dim->pos.x = this->actor.world.pos.x; + dim->pos.z = this->actor.world.pos.z; + } + + if (this->bigslimeCollider[0].base.atFlags & AT_ON) { + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->bigslimeCollider[i].base); + } + } + + if (this->bigslimeCollider[0].base.acFlags & AC_ON) { + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->bigslimeCollider[i].base); + } + } + + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->bigslimeCollider[i].base); + } +} + +void EnBigslime_AddWavySurface(EnBigslime* this) { + s32 randInt; + f32 randFloat; + s32 i; + + this->wavySurfaceTimer = 24; + randInt = (s32)(Rand_ZeroOne() * 6.0f) >> 1; + randFloat = (Rand_ZeroOne() * 40.0f) + 50.0f; + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + if ((i % 6) == 0) { + randFloat = (Rand_ZeroOne() * 40.0f) + 50.0f; + } + + this->vtxSurfacePerturbation[i] = sin_rad((randInt + i) * (M_PI / 3)) * randFloat * 0.001f; + } +} + +void EnBigslime_UpdateWavySurface(EnBigslime* this) { + f32 vtxSurfaceWave; + Vtx* staticVtx; + Vtx* dynamicVtx; + s32 i; + s32 j; + + if (this->wavySurfaceTimer == 0) { + EnBigslime_AddWavySurface(this); + } + + this->wavySurfaceTimer--; + vtxSurfaceWave = sin_rad(this->wavySurfaceTimer * (M_PI / 12)); + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + staticVtx = &sBigslimeStaticVtx[i]; + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + for (j = 0; j < 3; j++) { + // Formula: dynamicVtx = staticVtx * (1 + sin * perturbation) + dynamicVtx->n.ob[j] = + staticVtx->n.ob[j] + (s32)(vtxSurfaceWave * staticVtx->n.ob[j] * this->vtxSurfacePerturbation[i]); + } + } +} + +void EnBigslime_InitFallMinislime(EnBigslime* this) { + EnMinislime* minislime; + s32 i; + + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + minislime = this->minislime[i]; + minislime->actor.params = MINISLIME_INIT_FALL; + minislime->actor.world.pos.x = randPlusMinusPoint5Scaled(80.0f) + (GBT_ROOM_5_MIN_X + ((i % 4) + 1) * 192.0f); + minislime->actor.world.pos.y = Rand_ZeroFloat(250.0f) + (GBT_ROOM_5_CENTER_Y + 50.0f); + minislime->actor.world.pos.z = randPlusMinusPoint5Scaled(80.0f) + (GBT_ROOM_5_MIN_Z + ((i / 4) + 1) * 192.0f); + } + + this->minislimeState = MINISLIME_ACTIVE_INIT_STATE; +} + +void EnBigslime_SetMinislimeBreakLocation(EnBigslime* this) { + // Minislime spawn at these vertices when Frozen Bigslime Shatters + static s32 minislimeSpawnVtx[] = { + 7, 9, 11, 13, 15, // 5 equally spaced vertices on vtx ring 2 from top + 52, 56, 60, 64, 68, // 5 equally spaced vertices on vtx ring 5 from top + 94, 98, 102, 106, 110, // 5 equally spaced vertices on vtx ring 7 from top + }; + Vtx* dynamicVtx; + EnMinislime* minislime; + s32 i; + + this->minislimeState = MINISLIME_ACTIVE_CONTINUE_STATE; + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][minislimeSpawnVtx[i]]; + minislime = this->minislime[i]; + minislime->actor.params = MINISLIME_BREAK_BIGSLIME; + minislime->actor.world.pos.x = (dynamicVtx->n.ob[0] * this->actor.scale.x) + this->actor.world.pos.x; + minislime->actor.world.pos.y = (dynamicVtx->n.ob[1] * this->actor.scale.y) + this->actor.world.pos.y; + minislime->actor.world.pos.z = (dynamicVtx->n.ob[2] * this->actor.scale.z) + this->actor.world.pos.z; + minislime->actor.world.rot.x = 0x1000 + 0x333 * (MINISLIME_NUM_SPAWN - i); + } +} + +void EnBigslime_SetPlayerParams(EnBigslime* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (player->stateFlags2 & 0x80) { + player->actor.parent = NULL; + player->unk_AE8 = 100; + func_800B8D98(globalCtx, &this->actor, 10.0f, this->actor.world.rot.y, 10.0f); + } +} + +void EnBigslime_EndThrowMinislime(EnBigslime* this) { + if (this->actionFunc == EnBigslime_ThrowMinislime && + this->minislimeToThrow->actor.params == MINISLIME_SETUP_GEKKO_THROW) { + this->minislimeToThrow->actor.params = MINISLIME_IDLE; + } +} + +void EnBigslime_BreakIntoMinislime(EnBigslime* this, GlobalContext* globalCtx) { + s32 i; + s16 quake = Quake_Add(GET_ACTIVE_CAM(globalCtx), 3); + + Quake_SetSpeed(quake, 20000); + Quake_SetQuakeValues(quake, 15, 0, 0, 0); + Quake_SetCountdown(quake, 15); + func_8013ECE0(this->actor.xyzDistToPlayerSq, 180, 20, 100); + this->bigslimeCollider[0].base.atFlags &= ~AT_ON; + this->gekkoCollider.base.acFlags &= ~(AC_ON | AC_HIT); + + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + this->bigslimeCollider[i].base.acFlags &= ~AC_HIT; + } + + EnBigslime_SetMinislimeBreakLocation(this); + this->actor.update = EnBigslime_UpdateGekko; + this->actor.draw = EnBigslime_DrawGekko; + this->actor.gravity = -2.0f; + EnBigslime_SetPlayerParams(this, globalCtx); + EnBigslime_EndCutscene(this, globalCtx); + this->actor.colChkInfo.mass = 50; + this->actor.flags &= ~(0x1 | 0x400); + this->actor.flags |= 0x200; + this->actor.hintId = 95; + this->gekkoRot.x = 0; + this->gekkoRot.y = 0; + this->actor.bgCheckFlags &= ~1; + this->formBigslimeTimer = 2; + EnBigslime_AddIceShardEffect(this, globalCtx); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_B_SLIME_BREAK); + EnBigslime_SetupJumpGekko(this); +} + +/** + * Smoothly moves the camera to a side view and keeps it there + * as bigslime grabs player and the Gekko melee-attacks player + */ +void EnBigslime_UpdateCameraGrabPlayer(EnBigslime* this, GlobalContext* globalCtx) { + Camera* subCam = Play_GetCamera(globalCtx, this->subCamId); + Vec3f subCamEye; + Vec3f subCamAt; + + Math_Vec3f_Copy(&subCamEye, &subCam->eye); + Math_Vec3f_Copy(&subCamAt, &subCam->at); + + Math_StepToF(&subCamEye.x, (Math_SinS(this->subCamYawGrabPlayer) * 250.0f) + this->actor.world.pos.x, 10.0f); + Math_StepToF(&subCamEye.y, GBT_ROOM_5_MIN_Y + 187.5f, 10.0f); + Math_StepToF(&subCamEye.z, (Math_CosS(this->subCamYawGrabPlayer) * 250.0f) + this->actor.world.pos.z, 10.0f); + + Math_StepToF(&subCamAt.x, this->actor.world.pos.x, 10.0f); + Math_StepToF(&subCamAt.y, GBT_ROOM_5_MIN_Y + 87.5f, 10.0f); + Math_StepToF(&subCamAt.z, this->actor.world.pos.z, 10.0f); + + Play_CameraSetAtEye(globalCtx, this->subCamId, &subCamAt, &subCamEye); +} + +/** + * Takes the camera eye and instantaneously moves it 10% closer to the focus point "at". + * This gives the camera a "jerk" feeling + * Used everytime player is hit inside of bigslime while being grabbed + */ +void EnBigslime_JerkCameraPlayerHit(EnBigslime* this, GlobalContext* globalCtx) { + Camera* subCam = Play_GetCamera(globalCtx, this->subCamId); + Vec3f subCamEye; + + Math_Vec3f_Diff(&subCam->eye, &subCam->at, &subCamEye); + Math_Vec3f_Scale(&subCamEye, 0.9f); + Math_Vec3f_Sum(&subCamEye, &subCam->at, &subCamEye); + Play_CameraSetAtEye(globalCtx, this->subCamId, &subCam->at, &subCamEye); +} + +/** + * Performs the camera motion for the intro cutscene as the player enters the room + * and the battle starts. Positions the camera slightly offset from player, + * then zooms into the Gekko until the Gekko calls the minislimes down from the ceiling + */ +void EnBigslime_UpdateCameraIntroCs(EnBigslime* this, GlobalContext* globalCtx, s32 noticeTimer) { + Camera* subCam = Play_GetCamera(globalCtx, this->subCamId); + Vec3f subCamEye; + f32 zoom = (noticeTimer * 19.0f) + 67.0f; + s16 yawOffset = this->actor.yawTowardsPlayer + (noticeTimer * 0x31); + + subCamEye.x = Math_SinS(yawOffset) * zoom + subCam->at.x; + subCamEye.z = Math_CosS(yawOffset) * zoom + subCam->at.z; + subCamEye.y = subCam->at.y + -4.0f + (noticeTimer * 2.0f); + + Play_CameraSetAtEye(globalCtx, this->subCamId, &subCam->at, &subCamEye); +} + +/** + * Takes the camera and makes the focus point (at) point at bigslime, who is on the + * center of the roof. This is used when the minislimes merges into bigslime. + */ +void EnBigslime_UpdateCameraFormingBigslime(EnBigslime* this, GlobalContext* globalCtx) { + Play_CameraSetAtEye(globalCtx, this->subCamId, &this->actor.focus.pos, + &Play_GetCamera(globalCtx, this->subCamId)->eye); +} + +void EnBigslime_EndCutscene(EnBigslime* this, GlobalContext* globalCtx) { + Camera* subCam; + + if (this->subCamId != MAIN_CAM) { + subCam = Play_GetCamera(globalCtx, this->subCamId); + Play_CameraSetAtEye(globalCtx, MAIN_CAM, &subCam->at, &subCam->eye); + this->subCamId = MAIN_CAM; + ActorCutscene_Stop(this->cutscene); + this->cutscene = ActorCutscene_GetAdditionalCutscene(this->actor.cutscene); + func_800B724C(globalCtx, &this->actor, 6); + } +} + +void EnBigslime_Scale(EnBigslime* this, s16 pitch, f32 xzScale, f32 yScale) { + this->actor.scale.x = ((Math_SinS(pitch) * xzScale) + 1.5f) * 0.1f; // = 0.15f + 0.1f * xzScale * sin(pitch) + this->actor.scale.y = ((Math_CosS(pitch) * yScale) + 0.75f) * 0.1f; // = 0.075f + 0.1f * yScale * cos(pitch) + this->actor.scale.z = 0.3f - this->actor.scale.x; // = 0.15f - 0.1f * xzScale * sin(pitch) +} + +/** + * Set the params used by the floor shockwave when bigslime shatters into minislime + */ +void EnBigslime_InitShockwave(EnBigslime* this, GlobalContext* globalCtx) { + globalCtx->envCtx.unk_C3 = 3; + Math_Vec3f_Copy(&this->frozenPos, &this->actor.world.pos); + this->frozenPos.y = GBT_ROOM_5_MIN_Y; + this->shockwaveAlpha = 235; + this->shockwaveScale = 0.025f; +} + +/** + * Restores bigslime behaviour to the state before it was frozen + */ +void EnBigslime_SetTargetVtxFromPreFrozen(EnBigslime* this) { + this->bigslimeCollider[0].base.acFlags |= AC_ON; + this->actionFunc = this->actionFuncStored; + this->skelAnime.playSpeed = 1.0f; + if (this->actionFunc == EnBigslime_SquishFlat) { + this->bigslimeCollider[0].base.atFlags |= AT_ON; + EnBigslime_SetTargetVtxToWideCone(this); + } else if (this->actionFunc == EnBigslime_Rise) { + if (this->riseCounter == 0) { + EnBigslime_SetTargetVtxToThinCone(this); + } else if (this->riseCounter == 1) { + EnBigslime_SetTargetVtxToInverseCone(this); + } else { + EnBigslime_SetTargetVtxToStaticVtx(this); + } + } +} + +/** + * Plays the standard Gekko sound effects without reverb + */ +void EnBigslime_GekkoSfxOutsideBigslime(EnBigslime* this, u16 sfxId) { + func_8019F1C0(&this->gekkoProjectedPos, sfxId); +} + +/** + * Adds reverb to Gekko sound effects when enclosed by bigslime + */ +void EnBigslime_GekkoSfxInsideBigslime(EnBigslime* this, u16 sfxId) { + func_8019F420(&this->gekkoProjectedPos, sfxId); +} + +void EnBigslime_GekkoFreeze(EnBigslime* this) { + this->gekkoDrawEffect = GEKKO_DRAW_EFFECT_FROZEN; + this->gekkoCollider.base.colType = COLTYPE_HIT3; + this->gekkoCollider.info.elemType = ELEMTYPE_UNK0; + this->stunTimer = 2; + this->unk_38C = 0.75f; + this->unk_390 = 1.125f; + this->unk_388 = 1.0f; + this->actor.flags &= ~0x200; +} + +void EnBigslime_GekkoThaw(EnBigslime* this, GlobalContext* globalCtx) { + if (this->gekkoDrawEffect == GEKKO_DRAW_EFFECT_FROZEN) { + this->gekkoDrawEffect = GEKKO_DRAW_EFFECT_THAW; + this->gekkoCollider.base.colType = COLTYPE_HIT6; + this->gekkoCollider.info.elemType = ELEMTYPE_UNK1; + this->unk_388 = 0.0f; + func_800BF7CC(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), 2, 0.3f, 0.2f); + this->actor.flags |= 0x200; + } +} + +void EnBigslime_SetupCutsceneStartBattle(EnBigslime* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Camera* subCam = Play_GetCamera(globalCtx, this->subCamId); + + globalCtx->envCtx.unk_C3 = 4; + Animation_PlayLoop(&this->skelAnime, &gGekkoLookAroundAnim); + + this->bigslimeCollider[0].base.atFlags &= ~AT_ON; + this->bigslimeCollider[0].base.acFlags &= ~AC_ON; + + Math_Vec3f_Copy(&subCam->at, &this->actor.focus.pos); + func_800B7298(globalCtx, &this->actor, 4); + + player->actor.shape.rot.y = this->actor.yawTowardsPlayer + 0x8000; + player->actor.world.pos.x = Math_SinS(this->actor.yawTowardsPlayer) * 347.0f + this->actor.world.pos.x; + player->actor.world.pos.z = Math_CosS(this->actor.yawTowardsPlayer) * 347.0f + this->actor.world.pos.z; + + EnBigslime_UpdateCameraIntroCs(this, globalCtx, 25); + + this->gekkoRot.y = this->actor.yawTowardsPlayer + 0x8000; + this->isInitJump = false; + this->actionFunc = EnBigslime_CutsceneStartBattle; +} + +void EnBigslime_CutsceneStartBattle(EnBigslime* this, GlobalContext* globalCtx) { + if (this->isAnimUpdate) { + EnBigslime_SetupCutsceneNoticePlayer(this); + } else if (!this->isInitJump && Math_ScaledStepToS(&this->gekkoRot.y, this->actor.yawTowardsPlayer, 0x200)) { + Animation_PlayOnce(&this->skelAnime, &gGekkoSurpriseJumpAnim); + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_JUMP); + this->isInitJump = true; + } +} + +void EnBigslime_SetupCutsceneNoticePlayer(EnBigslime* this) { + Animation_PlayLoop(&this->skelAnime, &gGekkoNervousIdleAnim); + this->noticeTimer = 25; + this->actionFunc = EnBigslime_CutsceneNoticePlayer; +} + +void EnBigslime_CutsceneNoticePlayer(EnBigslime* this, GlobalContext* globalCtx) { + if (this->noticeTimer != 0) { + this->noticeTimer--; + } + + EnBigslime_UpdateCameraIntroCs(this, globalCtx, this->noticeTimer); + if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 4.0f)) { + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EV_WALK_WATER); + } + + if (this->noticeTimer == 0) { + EnBigslime_SetupCallMinislime(this, globalCtx); + } +} + +void EnBigslime_SetupCallMinislime(EnBigslime* this, GlobalContext* globalCtx) { + Animation_MorphToPlayOnce(&this->skelAnime, &gGekkoCallAnim, 5.0f); + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_GREET); + this->callTimer = 0; + func_800B7298(globalCtx, &this->actor, 7); + this->actionFunc = EnBigslime_CallMinislime; +} + +void EnBigslime_CallMinislime(EnBigslime* this, GlobalContext* globalCtx) { + if (this->callTimer > 0) { + this->callTimer--; + if (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 4.0f)) { + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EV_WALK_WATER); + } + + if (this->callTimer == 0) { + EnBigslime_EndCutscene(this, globalCtx); + this->formBigslimeTimer = 2; + this->actor.flags |= 1; + EnBigslime_SetupIdleNoticePlayer(this); + } + } else if (this->isAnimUpdate) { + Animation_PlayLoop(&this->skelAnime, &gGekkoNervousIdleAnim); + EnBigslime_UpdateCameraIntroCs(this, globalCtx, 25); + func_801A2E54(0x38); + EnBigslime_InitFallMinislime(this); + globalCtx->envCtx.unk_C3 = 0xFF; + this->callTimer = 35; + func_800B7298(globalCtx, &this->actor, 4); + } +} + +void EnBigslime_SetupMoveOnCeiling(EnBigslime* this) { + Animation_PlayLoop(&this->skelAnime, &gGekkoSwimForwardAnim); + this->actor.gravity = 0.0f; + this->actor.velocity.y = 20.0f; + + if (this->subCamId != MAIN_CAM) { + this->actor.speedXZ = 0.0f; + this->ceilingMoveTimer = 20; + } else { + this->ceilingMoveTimer = 320; + this->actor.speedXZ = 5.0f; + } + + this->wavySurfaceTimer = 0; + this->bigslimeCollider[0].base.acFlags |= AC_ON; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->actor.flags &= ~0x200; + this->actionFunc = EnBigslime_MoveOnCeiling; +} + +void EnBigslime_MoveOnCeiling(EnBigslime* this, GlobalContext* globalCtx) { + s16 pitch; // polar (zenith) angle + + Math_ScaledStepToS(&this->gekkoRot.x, 0, 0x400); + this->ceilingMoveTimer--; + pitch = this->ceilingMoveTimer * 0x800; + EnBigslime_Scale(this, pitch, 0.04f, 0.04f); + EnBigslime_UpdateWavySurface(this); + + if (this->subCamId != MAIN_CAM) { + if (this->ceilingMoveTimer == 0) { + EnBigslime_EndCutscene(this, globalCtx); + this->ceilingMoveTimer = 320; + } + } else if ((this->actor.xzDistToPlayer < 250.0f) || (this->ceilingMoveTimer == 0)) { + EnBigslime_SetupDrop(this); + } else { + this->actor.speedXZ = (fabsf(Math_SinS(pitch)) * 3.0f) + 5.0f; + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 10, 0x800, 0x80); + this->gekkoRot.y = this->actor.world.rot.y; + } +} + +void EnBigslime_SetupDrop(EnBigslime* this) { + this->actor.velocity.y = 0.0f; + this->ceilingDropTimer = 30; + this->actor.speedXZ = 0.0f; + this->actionFunc = EnBigslime_Drop; +} + +void EnBigslime_Drop(EnBigslime* this, GlobalContext* globalCtx) { + Vtx* staticVtx; + Vtx* dynamicVtx; + s32 i; + + Math_ScaledStepToS(&this->gekkoRot.x, 0x4000, 0x400); + if (this->ceilingDropTimer != 0) { + s32 requiredScopeTemp; + + this->ceilingDropTimer--; + this->ceilingMoveTimer--; + EnBigslime_UpdateWavySurface(this); + EnBigslime_Scale(this, this->ceilingMoveTimer * 0x4000, 0.2f, 0.15); + this->actor.scale.z = this->actor.scale.x; + if (this->ceilingDropTimer == 0) { + this->actor.gravity = -2.0f; + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_DOWN); + this->rotation = 0; + } + } else if (this->actor.bgCheckFlags & 1) { + EnBigslime_SetupSquishFlat(this); + } else { + Math_StepToF(&this->actor.scale.x, 0.15f, 0.0025f); + Math_StepToF(&this->actor.scale.y, 0.080000006f, 0.0025f); + Math_StepToF(&this->actor.scale.z, 0.15f, 0.0025f); + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + staticVtx = &sBigslimeStaticVtx[i]; + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + if (i > 145) { + Math_StepToS(&dynamicVtx->n.ob[1], staticVtx->n.ob[1] * 0.9f, 5); + } else if (i < 16) { + Math_StepToS(&dynamicVtx->n.ob[1], staticVtx->n.ob[1] * 1.3f, 5); + } else { + Math_StepToS(&dynamicVtx->n.ob[1], staticVtx->n.ob[1], 5); + } + Math_StepToS(&dynamicVtx->n.ob[0], staticVtx->n.ob[0], 5); + Math_StepToS(&dynamicVtx->n.ob[2], staticVtx->n.ob[2], 5); + } + } +} + +/** + * Checks each individual vertex to see if it is outside the walls of the room. + * If it is, updates the vertex to be back inside the boundary of the room. + * Also raises the vertex in the y-direction 100 units in model-space for a single wall + * and 200 unites in the y-direction for two walls i.e a corner. + * + * Differs from EnBigslime_CheckRoomBoundaries by checking and updating + * individual vertices instead of checking and updating a single world position + */ +void EnBigslime_CheckVtxWallBoundaries(EnBigslime* this) { + Vtx* dynamicVtx; + f32 vtxX; + f32 vtxZ; + s32 collisionCounter; + s32 i; + s16 updateVtxY; + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + vtxX = dynamicVtx->n.ob[0] * this->actor.scale.x; + vtxZ = dynamicVtx->n.ob[2] * this->actor.scale.z; + collisionCounter = 0; + if ((this->actor.world.pos.x + vtxX) > GBT_ROOM_5_MAX_X) { + dynamicVtx->n.ob[0] = (GBT_ROOM_5_MAX_X - this->actor.world.pos.x) / this->actor.scale.x; + collisionCounter++; + } else if ((this->actor.world.pos.x + vtxX) < GBT_ROOM_5_MIN_X) { + dynamicVtx->n.ob[0] = (GBT_ROOM_5_MIN_X - this->actor.world.pos.x) / this->actor.scale.x; + collisionCounter++; + } + + if ((this->actor.world.pos.z + vtxZ) > GBT_ROOM_5_MAX_Z) { + dynamicVtx->n.ob[2] = (GBT_ROOM_5_MAX_Z - this->actor.world.pos.z) / this->actor.scale.z; + collisionCounter++; + } else if ((this->actor.world.pos.z + vtxZ) < GBT_ROOM_5_MIN_Z) { + dynamicVtx->n.ob[2] = (GBT_ROOM_5_MIN_Z - this->actor.world.pos.z) / this->actor.scale.z; + collisionCounter++; + } + + if (dynamicVtx->n.ob[1] != -BIGSLIME_RADIUS_S) { + updateVtxY = collisionCounter * 100; + dynamicVtx->n.ob[1] += updateVtxY; + } + } +} + +/** + * This sets the target vertices into a wide cone shape + * + * Notes: + * - The flat surface of the cone is in the xz-plane at y = -1000 + * - The radius of the flat surface of the cone is 1000 units + * - The apex/point of the cone is at the point (0, 1000, 0) + * - It is wide because it is smooth and thicker near the apex than a standard cone + */ +void EnBigslime_SetTargetVtxToWideCone(EnBigslime* this) { + Vtx* staticVtx; + Vtx* targetVtx; + s16 vtxY; + f32 xzDist; + f32 xzScaleVtx; + s32 i; + s32 j; + + for (i = 0; i < BIGSLIME_NUM_RING_FACES / 2; i++) { + vtxY = (((cos_rad(i * (M_PI / 6)) + 1.0f) * 0.925f) + -0.85f) * BIGSLIME_RADIUS_F; + for (j = sVtxRingStartIndex[i]; j < sVtxRingStartIndex[i + 1]; j++) { + staticVtx = &sBigslimeStaticVtx[j]; + targetVtx = &sBigslimeTargetVtx[j]; + xzDist = sqrtf(SQ(staticVtx->n.ob[0]) + SQ(staticVtx->n.ob[2])); + + if (xzDist > 1.0f) { + xzScaleVtx = (BIGSLIME_RADIUS_F / (5.0f * xzDist)) * i; + } else { + xzScaleVtx = 200.0f * i; // only taken when i = 0, making 200.0f useless + } + + targetVtx->n.ob[0] = staticVtx->n.ob[0] * xzScaleVtx; + targetVtx->n.ob[2] = staticVtx->n.ob[2] * xzScaleVtx; + targetVtx->n.ob[1] = vtxY; + } + } + + for (; i < BIGSLIME_NUM_RING_VTX; i++) { + vtxY = ((cos_rad((i - BIGSLIME_NUM_RING_FACES / 2) * (M_PI / 16)) * 0.05f) + -1.0f) * BIGSLIME_RADIUS_F; + for (j = sVtxRingStartIndex[i]; j < sVtxRingStartIndex[i + 1]; j++) { + staticVtx = &sBigslimeStaticVtx[j]; + targetVtx = &sBigslimeTargetVtx[j]; + xzDist = sqrtf(SQ(staticVtx->n.ob[0]) + SQ(staticVtx->n.ob[2])); + if (xzDist > 1.0f) { + xzScaleVtx = (BIGSLIME_RADIUS_F / (8.0f * xzDist)) * (14 - i); + } else { + // only taken when j = 161, but gets immediately written over (bottom vtx of the sphere) + xzScaleVtx = 125.0f * (14 - i); + } + + targetVtx->n.ob[0] = staticVtx->n.ob[0] * xzScaleVtx; + targetVtx->n.ob[2] = staticVtx->n.ob[2] * xzScaleVtx; + targetVtx->n.ob[1] = vtxY; + } + } + + // Bottom vtx of the sphere + sBigslimeTargetVtx[BIGSLIME_NUM_VTX - 1].n.ob[0] = 0; + sBigslimeTargetVtx[BIGSLIME_NUM_VTX - 1].n.ob[2] = 0; + sBigslimeTargetVtx[BIGSLIME_NUM_VTX - 1].n.ob[1] = -BIGSLIME_RADIUS_S; +} + +void EnBigslime_SetupSquishFlat(EnBigslime* this) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_B_SLIME_JUMP2); + this->squishFlatTimer = 20; + this->actor.scale.x = 0.2f; + this->actor.scale.z = 0.2f; + this->actor.scale.y = 0.05f; + this->actor.world.pos.y = GBT_ROOM_5_MIN_Y + 50.0f; + EnBigslime_SetTargetVtxToWideCone(this); + EnBigslime_CheckVtxWallBoundaries(this); + this->bigslimeCollider[0].base.atFlags |= AT_ON; + this->actionFunc = EnBigslime_SquishFlat; +} + +/** + * Squishes flat like a pancake to try and grab player + * + * Notes: + * - The vtx shape of Fused Jelly starts from a wide cone shape + * - The squishing occurs throught the large changes in &this->actor.scale + */ +void EnBigslime_SquishFlat(EnBigslime* this, GlobalContext* globalCtx) { + Player* player; + Vtx* dynamicVtx; + Vtx* targetVtx; + s32 i; + + this->squishFlatTimer--; + Math_ScaledStepToS(&this->gekkoRot.x, 0, 0x400); + Math_SmoothStepToF(&this->actor.scale.x, 0.35f, 0.4f, 0.035f, 0.0034999999f); + Math_SmoothStepToF(&this->actor.scale.y, 0.030000001f, 0.4f, 0.0030000003f, 0.0003f); + this->actor.scale.z = this->actor.scale.x; + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + targetVtx = &sBigslimeTargetVtx[i]; + Math_SmoothStepToS(&dynamicVtx->n.ob[0], targetVtx->n.ob[0], 5, 40, 5); + Math_SmoothStepToS(&dynamicVtx->n.ob[2], targetVtx->n.ob[2], 5, 40, 5); + Math_SmoothStepToS(&dynamicVtx->n.ob[1], targetVtx->n.ob[1], 2, 600, 3); + } + + EnBigslime_CheckVtxWallBoundaries(this); + + // Checks if any collider is interacting with player. If so, player is grabbed + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + if (this->bigslimeCollider[i].base.atFlags & AT_HIT) { + break; + } + } + + if (i != BIGSLIME_NUM_RING_FACES) { + player = GET_PLAYER(globalCtx); + if (globalCtx->grabPlayer(globalCtx, player)) { + player->actor.parent = &this->actor; + EnBigslime_SetupCutscene(this); + return; + } + } + + if (this->squishFlatTimer == 0) { + EnBigslime_SetupRise(this); + } +} + +/** + * This sets the target vertices into a thin cone shape + * + * Notes: + * - The flat surface of the cone is in the xz-plane at y = -1000 + * - The radius of the flat surface of the cone is 1000 units + * - The apex/point of the cone is at the point (0, 1000, 0) + * - It is thin because it is smooth and thinner near the apex than a standard cone + */ +void EnBigslime_SetTargetVtxToThinCone(EnBigslime* this) { + Vtx* targetVtx; + Vtx* staticVtx; + f32 xzDistVtx; + f32 xzScaleVtx; + s32 i; + s32 j; + s16 upperSphereCos; + f32 lowerSphereCos; + s32 targetVtxY; + + // Top vtx of the sphere + sBigslimeTargetVtx[0].n.ob[1] = BIGSLIME_RADIUS_S; + sBigslimeTargetVtx[0].n.ob[0] = 0; + sBigslimeTargetVtx[0].n.ob[2] = 0; + + for (i = 1; i < BIGSLIME_NUM_RING_FACES / 2; i++) { + upperSphereCos = (((cos_rad((i - 1) * (M_PI / 5)) + 1.0f) * 0.925f) + -0.85f) * BIGSLIME_RADIUS_F; + for (j = sVtxRingStartIndex[i]; j < sVtxRingStartIndex[i + 1]; j++) { + staticVtx = &sBigslimeStaticVtx[j]; + targetVtx = &sBigslimeTargetVtx[j]; + xzDistVtx = sqrtf(SQ(staticVtx->n.ob[0]) + SQ(staticVtx->n.ob[2])); + xzDistVtx = (BIGSLIME_RADIUS_F / (5.0f * xzDistVtx)) * i; + // xzDistVtx is always less than 500.0f + xzScaleVtx = + xzDistVtx < 500.0f ? xzDistVtx * 0.75f : BIGSLIME_RADIUS_F - ((BIGSLIME_RADIUS_F - xzDistVtx) * 0.75f); + + targetVtx->n.ob[0] = staticVtx->n.ob[0] * xzScaleVtx; + targetVtx->n.ob[2] = staticVtx->n.ob[2] * xzScaleVtx; + targetVtx->n.ob[1] = upperSphereCos; + } + } + + for (; i < BIGSLIME_NUM_RING_FACES; i++) { + lowerSphereCos = cos_rad((i - BIGSLIME_NUM_RING_FACES / 2) * (M_PI / BIGSLIME_NUM_RING_FACES)); + for (j = sVtxRingStartIndex[i]; j < sVtxRingStartIndex[i + 1]; j++) { + staticVtx = &sBigslimeStaticVtx[j]; + targetVtx = &sBigslimeTargetVtx[j]; + targetVtx->n.ob[0] = staticVtx->n.ob[0]; + targetVtx->n.ob[2] = staticVtx->n.ob[2]; + targetVtxY = (s16)(((lowerSphereCos * 0.05f) + -1.0f) * BIGSLIME_RADIUS_F); + targetVtx->n.ob[1] = targetVtxY; + } + } + + // Bottom vtx of the sphere + sBigslimeTargetVtx[BIGSLIME_NUM_VTX - 1].n.ob[1] = -BIGSLIME_RADIUS_S; + sBigslimeTargetVtx[BIGSLIME_NUM_VTX - 1].n.ob[0] = 0; + sBigslimeTargetVtx[BIGSLIME_NUM_VTX - 1].n.ob[2] = 0; +} + +/** + * This sets the target vertices into a thin inverse cone shape + * + * Notes: + * - The flat surface of the cone is in the xz-plane at y = +1000 + * - The radius of the flat surface of the cone is 1000 units + * - The apex/point of the cone is at the point (0, -1000, 0) + * - It is thin because it is smooth and thinner near the apex than a standard cone + */ +void EnBigslime_SetTargetVtxToInverseCone(EnBigslime* this) { + Vtx* targetVtx; + Vtx* staticVtx; + f32 xzDistVtx; + f32 upperSphereCos; + s16 lowerSphereCos; + f32 xzScaleVtx; + s32 i; + s32 j; + s32 vtxY; + + // Top vtx of the sphere + sBigslimeTargetVtx[0].n.ob[1] = BIGSLIME_RADIUS_S; + sBigslimeTargetVtx[0].n.ob[0] = 0; + sBigslimeTargetVtx[0].n.ob[2] = 0; + + for (i = 1; i < BIGSLIME_NUM_RING_FACES / 2; i++) { + upperSphereCos = cos_rad((i - 1) * (M_PI / 10)); + for (j = sVtxRingStartIndex[i]; j < sVtxRingStartIndex[i + 1]; j++) { + staticVtx = &sBigslimeStaticVtx[j]; + targetVtx = &sBigslimeTargetVtx[j]; + targetVtx->n.ob[0] = staticVtx->n.ob[0]; + targetVtx->n.ob[2] = staticVtx->n.ob[2]; + vtxY = (s16)(((upperSphereCos * 0.1f) + 0.9f) * BIGSLIME_RADIUS_F); + targetVtx->n.ob[1] = vtxY; + } + } + + for (; i < BIGSLIME_NUM_RING_FACES; i++) { + lowerSphereCos = + (((cos_rad((i - BIGSLIME_NUM_RING_FACES / 2) * (M_PI / 5)) + 1) * 0.925f) + -1.0f) * BIGSLIME_RADIUS_F; + for (j = sVtxRingStartIndex[i]; j < sVtxRingStartIndex[i + 1]; j++) { + staticVtx = &sBigslimeStaticVtx[j]; + targetVtx = &sBigslimeTargetVtx[j]; + xzDistVtx = sqrtf(SQ(staticVtx->n.ob[0]) + SQ(staticVtx->n.ob[2])); + xzDistVtx = (BIGSLIME_RADIUS_F / (6.0f * xzDistVtx)) * (BIGSLIME_NUM_RING_FACES - i); + // xzDistVtx is always less than 500.0f + xzScaleVtx = + xzDistVtx < 500.0f ? xzDistVtx * 0.75f : BIGSLIME_RADIUS_F - ((BIGSLIME_RADIUS_F - xzDistVtx) * 0.75f); + + targetVtx->n.ob[0] = staticVtx->n.ob[0] * xzScaleVtx; + targetVtx->n.ob[2] = staticVtx->n.ob[2] * xzScaleVtx; + targetVtx->n.ob[1] = lowerSphereCos; + } + } + + // Bottom vtx of the sphere + sBigslimeTargetVtx[BIGSLIME_NUM_VTX - 1].n.ob[1] = -BIGSLIME_RADIUS_S; + sBigslimeTargetVtx[BIGSLIME_NUM_VTX - 1].n.ob[0] = 0; + sBigslimeTargetVtx[BIGSLIME_NUM_VTX - 1].n.ob[2] = 0; +} + +void EnBigslime_SetTargetVtxToStaticVtx(EnBigslime* this) { + s32 i; + Vtx* staticVtx; + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + staticVtx = &sBigslimeStaticVtx[i]; + sBigslimeTargetVtx[i].n.ob[0] = staticVtx->n.ob[0]; + sBigslimeTargetVtx[i].n.ob[2] = staticVtx->n.ob[2]; + sBigslimeTargetVtx[i].n.ob[1] = staticVtx->n.ob[1]; + } +} + +void EnBigslime_SetupRise(EnBigslime* this) { + Animation_PlayLoop(&this->skelAnime, &gGekkoSwimForwardAnim); + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_JUMP_ABOVE); + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_UTSUBO_APPEAR_TRG); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_B_SLIME_JUMP1); + this->riseCounter = 0; + this->bigslimeCollider[0].base.atFlags &= ~AT_ON; + this->actor.gravity = 0.0f; + this->actor.velocity.y = 0.0f; + EnBigslime_SetTargetVtxToThinCone(this); + this->actor.world.rot.y = this->gekkoRot.y; + this->actionFunc = EnBigslime_Rise; +} + +/** + * Moves Fused Jelly from a squish pancake on the floor to the ceiling + * + * Notes: + * - When riseCounter == 0, Fused Jelly is un-squishing into a thin cone shape + * - When riseCounter == 1, Fused Jelly is deforming into an inverse thin cone shape + * - When riseCounter == 2 to 9, Fused Jelly is returning to its default spherical shape + * - When riseCounter == 10, Fused Jelly starts moving on the ceiling + */ +void EnBigslime_Rise(EnBigslime* this, GlobalContext* globalCtx) { + Vtx* dynamicVtx; + Vtx* targetVtx; + s32 i; + + if (this->riseCounter < 2) { + Math_SmoothStepToF(&this->actor.scale.x, 0.13f, 0.2f, 0.039f, 0.0038999997f); + Math_ScaledStepToS(&this->gekkoRot.x, -0x4000, 0x400); + } else { + Math_SmoothStepToF(&this->actor.scale.x, 0.15f, 0.4f, 0.015000001f, 0.0015f); + Math_ScaledStepToS(&this->gekkoRot.x, 0, 0x400); + } + + this->actor.scale.z = this->actor.scale.x; + EnBigslime_CheckVtxWallBoundaries(this); + if (this->riseCounter == 0) { + if (Math_SmoothStepToF(&this->actor.scale.y, 0.3f, 0.5f, 0.015000001f, 0.00075f) < 0.01f) { + this->riseCounter = 1; + EnBigslime_SetTargetVtxToInverseCone(this); + } + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + targetVtx = &sBigslimeTargetVtx[i]; + Math_SmoothStepToS(&dynamicVtx->n.ob[1], targetVtx->n.ob[1], 5, 550, 3); + Math_SmoothStepToS(&dynamicVtx->n.ob[0], targetVtx->n.ob[0], 5, 40, 5); + Math_SmoothStepToS(&dynamicVtx->n.ob[2], targetVtx->n.ob[2], 5, 40, 5); + } + + } else if (this->riseCounter == 1) { + if (Math_SmoothStepToF(&this->actor.scale.y, 0.075f, 0.4f, 0.0075000003f, 0.00075f) < 0.01f) { + EnBigslime_SetTargetVtxToStaticVtx(this); + this->riseCounter++; + } + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + targetVtx = &sBigslimeTargetVtx[i]; + Math_SmoothStepToS(&dynamicVtx->n.ob[1], targetVtx->n.ob[1], 5, 50, 3); + Math_SmoothStepToS(&dynamicVtx->n.ob[0], targetVtx->n.ob[0], 5, 40, 5); + Math_SmoothStepToS(&dynamicVtx->n.ob[2], targetVtx->n.ob[2], 5, 40, 5); + } + + this->actor.world.pos.y = GBT_ROOM_5_MAX_Y - (this->actor.scale.y * BIGSLIME_RADIUS_F); + } else if (this->riseCounter == 10) { + EnBigslime_SetupMoveOnCeiling(this); + } else { + this->riseCounter++; + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + targetVtx = &sBigslimeTargetVtx[i]; + Math_SmoothStepToS(&dynamicVtx->n.ob[1], targetVtx->n.ob[1], 5, 550, 3); + Math_SmoothStepToS(&dynamicVtx->n.ob[0], targetVtx->n.ob[0], 5, 40, 5); + Math_SmoothStepToS(&dynamicVtx->n.ob[2], targetVtx->n.ob[2], 5, 40, 5); + } + } + + EnBigslime_CheckVtxWallBoundaries(this); + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 10, 0x800, 0x80); +} + +void EnBigslime_SetupCutsceneGrabPlayer(EnBigslime* this, GlobalContext* globalCtx) { + Camera* mainCam = Play_GetCamera(globalCtx, MAIN_CAM); + s16 yaw; + + Play_CameraSetAtEye(globalCtx, this->subCamId, &mainCam->at, &mainCam->eye); + this->grabPlayerTimer = 15; + this->wavySurfaceTimer = 0; + this->bigslimeCollider[0].base.atFlags &= ~AT_ON; + this->actor.world.rot.y = Actor_YawToPoint(&this->actor, &this->actor.home.pos); + yaw = func_800DFCDC(GET_ACTIVE_CAM(globalCtx)) - this->actor.world.rot.y; + + if (yaw > 0x4000) { + this->subCamYawGrabPlayer = -0x2000; + } else if (yaw > 0) { + this->subCamYawGrabPlayer = -0x6000; + } else if (yaw < -0x4000) { + this->subCamYawGrabPlayer = 0x2000; + } else { + this->subCamYawGrabPlayer = 0x6000; + } + + this->subCamYawGrabPlayer += this->actor.world.rot.y; + Animation_PlayLoop(&this->skelAnime, &gGekkoBoxingStanceAnim); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_B_SLIME_EAT); + this->actionFunc = EnBigslime_CutsceneGrabPlayer; +} + +void EnBigslime_CutsceneGrabPlayer(EnBigslime* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 invgrabPlayerTimer; + f32 magPosXZOffset; + Vtx* dynamicVtx; + s32 i; + s32 j; + + player->unk_AE8 = 0; + Math_ScaledStepToS(&this->gekkoRot.x, 0, 0x400); + EnBigslime_UpdateCameraGrabPlayer(this, globalCtx); + if (this->grabPlayerTimer > 0) { + invgrabPlayerTimer = 1.0f / this->grabPlayerTimer; + + this->actor.scale.x = F32_LERPIMP(this->actor.scale.x, 0.15f, invgrabPlayerTimer); + this->actor.scale.y = F32_LERPIMP(this->actor.scale.y, 0.075f, invgrabPlayerTimer); + this->actor.scale.z = this->actor.scale.x; + + player->actor.world.pos.x = F32_LERPIMP(player->actor.world.pos.x, this->actor.world.pos.x, invgrabPlayerTimer); + player->actor.world.pos.z = F32_LERPIMP(player->actor.world.pos.z, this->actor.world.pos.z, invgrabPlayerTimer); + player->actor.world.pos.y = F32_LERPIMP( + player->actor.world.pos.y, this->actor.world.pos.y + this->actor.scale.y * -500.0f, invgrabPlayerTimer); + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + + // loop over x, y, z + for (j = 0; j < 3; j++) { + // Linearly interpolate dynamicVtx --> staticVtx + dynamicVtx->n.ob[j] += + (s16)((sBigslimeStaticVtx[i].n.ob[j] - dynamicVtx->n.ob[j]) * invgrabPlayerTimer); + } + } + + invgrabPlayerTimer = (15 - this->grabPlayerTimer) / 15.0f; + magPosXZOffset = invgrabPlayerTimer * -50.0f; + this->gekkoPosOffset.x = Math_SinS(this->gekkoRot.y) * magPosXZOffset; + this->gekkoPosOffset.y = invgrabPlayerTimer * -40.0f; + this->gekkoPosOffset.z = Math_CosS(this->gekkoRot.y) * magPosXZOffset; + this->grabPlayerTimer--; + if (this->grabPlayerTimer == 0) { + EnBigslime_SetupAttackPlayerInBigslime(this); + } + } +} + +void EnBigslime_SetupAttackPlayerInBigslime(EnBigslime* this) { + Animation_PlayOnce(&this->skelAnime, sGekkoAttackAnimations[(s32)Rand_ZeroFloat(3.0f) % 3]); + this->numGekkoMeleeAttacks = (s32)Rand_ZeroFloat(3.0f) + 1; + this->numGekkoPosGrabPlayer = 6; + this->actionFunc = EnBigslime_AttackPlayerInBigslime; +} + +void EnBigslime_AttackPlayerInBigslime(EnBigslime* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 pitch = this->scaleFactor * 0x3333; // polar (zenith) angle + + player->unk_AE8 = 0; + Math_ScaledStepToS(&this->gekkoRot.x, 0, 0x400); + EnBigslime_UpdateCameraGrabPlayer(this, globalCtx); + EnBigslime_UpdateWavySurface(this); + + if (this->scaleFactor != 0) { + this->scaleFactor--; + } + + // Checks to see if it's the frame of impact + if (((this->skelAnime.animation == &gGekkoJabPunchAnim) && + Animation_OnFrame(&this->skelAnime, 2.0f)) || // Jab punch makes impact on frame 2 of animation + ((this->skelAnime.animation == &gGekkoHookPunchAnim) && + Animation_OnFrame(&this->skelAnime, 9.0f)) || // Hook Punch makes impact on frames 9 of animation + ((this->skelAnime.animation == &gGekkoKickAnim) && + Animation_OnFrame(&this->skelAnime, 2.0f))) { // Kick makes impact on frame 2 of animation + this->scaleFactor = 10; + player->actor.world.pos.x += 20.0f * Math_SinS(this->gekkoRot.y); + player->actor.world.pos.z += 20.0f * Math_CosS(this->gekkoRot.y); + EnBigslime_JerkCameraPlayerHit(this, globalCtx); + if (this->skelAnime.animation == &gGekkoKickAnim) { + EnBigslime_GekkoSfxInsideBigslime(this, NA_SE_EN_FROG_KICK); + } else { + EnBigslime_GekkoSfxInsideBigslime(this, NA_SE_EN_FROG_PUNCH1); + } + } else { + Math_StepToF(&player->actor.world.pos.x, this->actor.world.pos.x, 4.0f); + Math_StepToF(&player->actor.world.pos.z, this->actor.world.pos.z, 4.0f); + } + + EnBigslime_Scale(this, pitch, ((this->scaleFactor * 0.08f) + 0.2f) * 0.15f, + ((this->scaleFactor * 0.08f) + 0.2f) * 0.05f); + player->actor.world.pos.y = this->actor.world.pos.y + (this->actor.scale.y * -500.0f); + if (this->isAnimUpdate) { + this->numGekkoMeleeAttacks--; + if (this->numGekkoMeleeAttacks == 0) { + this->numGekkoPosGrabPlayer--; + + if ((gSaveContext.health < 5) || (this->numGekkoPosGrabPlayer == 0)) { + this->numGekkoPosGrabPlayer = 0; + this->gekkoRot.y = this->actor.world.rot.y; + this->gekkoPosOffset.x = Math_SinS(this->gekkoRot.y) * -50.0f; + this->gekkoPosOffset.z = Math_CosS(this->gekkoRot.y) * -50.0f; + EnBigslime_SetupWindupThrowPlayer(this); + return; + } + + globalCtx->damagePlayer(globalCtx, -4); + func_800B8E58(&player->actor, player->ageProperties->unk_92 + 0x6805); + this->gekkoRot.y += (s16)(Rand_S16Offset(0x4000, 0x4000) * (Rand_ZeroOne() < 0.5f ? -1 : 1)); + this->gekkoPosOffset.x = Math_SinS(this->gekkoRot.y) * -50.0f; + this->gekkoPosOffset.z = Math_CosS(this->gekkoRot.y) * -50.0f; + this->numGekkoMeleeAttacks = (s32)Rand_ZeroFloat(3.0f) + 1; + } + Animation_PlayOnce(&this->skelAnime, sGekkoAttackAnimations[((s32)Rand_ZeroFloat(3.0f) % 3)]); + } + + func_800B9010(&this->actor, NA_SE_EN_B_SLIME_PUNCH_MOVE - SFX_FLAG); +} + +/** + * Calculates the surface perturbation (multiplicative offset from the static vertices) + * used to update dynamic vertices when bigslime is about to throw/eject player from inside + * at the end of the grab-player cutscene + * + * A unit normal vector (unitVec) is used to represent the direction player will be thrown. + * This unit vector has the following spherical coordinates: + * - radius = 1 + * - yaw (azimuthal angle) = this->actor.world.rot.y + * - pitch (polar/zenith angle) = M_PI / 4 + * + * This unit normal vector is converted into x-y-z coordinates and dot-producted with + * the model coordinates of each individual vertex. The surface perturbation is then + * set to be linearly proportional to this dot product + * + * This leads to the bending shape observed during windup as player is about being thrown out of bigslime + */ +void EnBigslime_SetupWindupThrowPlayer(EnBigslime* this) { + Vtx* dynamicVtx; + f32 dotXYZ; + f32 unitVecX = Math_SinS(this->actor.world.rot.y) * M_SQRT1_2; + f32 unitVecZ = Math_CosS(this->actor.world.rot.y) * M_SQRT1_2; + s32 i; + + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + + // vector dot product between each dynamicVtx and the unit normal vector describing player's thrown direction + dotXYZ = (dynamicVtx->n.ob[0] * unitVecX + dynamicVtx->n.ob[1] * M_SQRT1_2 + dynamicVtx->n.ob[2] * unitVecZ) * + 0.001f; + if (dotXYZ < 0.01f) { + this->vtxSurfacePerturbation[i] = 0.0f; + } else { + this->vtxSurfacePerturbation[i] = dotXYZ * 0.5f; + } + } + + this->windupPunchTimer = 27; + Animation_PlayOnce(&this->skelAnime, &gGekkoWindupPunchAnim); + EnBigslime_GekkoSfxInsideBigslime(this, NA_SE_EN_FROG_PUNCH2); + this->actionFunc = EnBigslime_WindupThrowPlayer; +} + +void EnBigslime_WindupThrowPlayer(EnBigslime* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 scale; + f32 invWindupPunchTimer; + Vtx* dynamicVtx; + Vtx* staticVtx; + s32 i; + s32 j; + + this->windupPunchTimer--; + EnBigslime_UpdateCameraGrabPlayer(this, globalCtx); + if (this->windupPunchTimer > 0) { + invWindupPunchTimer = 1.0f / this->windupPunchTimer; + scale = cos_rad(this->windupPunchTimer * (M_PI / 27)) + 1.0f; + player->actor.world.pos.y = this->actor.world.pos.y + (this->actor.scale.y * -500.0f); + + // Linearly interpolate gekkoRot.y --> this->actor.world.rot.y + this->gekkoRot.y += (s16)((s16)(this->actor.world.rot.y - this->gekkoRot.y) * invWindupPunchTimer); + this->gekkoPosOffset.x = Math_SinS(this->gekkoRot.y) * -50.0f; + this->gekkoPosOffset.z = Math_CosS(this->gekkoRot.y) * -50.0f; + } else { + if (this->windupPunchTimer == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_B_SLIME_REVERSE); + EnBigslime_GekkoSfxInsideBigslime(this, NA_SE_EN_FROG_PUNCH1); + } + + scale = 0.5f - cos_rad(-this->windupPunchTimer * (M_PI / 5)) * 0.5f; + if (this->windupPunchTimer == -5) { + if (player->stateFlags2 & 0x80) { + player->actor.parent = NULL; + player->unk_AE8 = 100; + } + + player->actor.velocity.y = 0.0f; + func_800B8D50(globalCtx, &this->actor, 10.0f, this->actor.world.rot.y, 10.0f, 4); + EnBigslime_SetupSetDynamicVtxThrowPlayer(this, globalCtx); + } + + player->actor.world.pos.x = + (Math_SinS(this->actor.world.rot.y) * (1060.5f * this->actor.scale.x) * scale) + this->actor.world.pos.x; + player->actor.world.pos.z = + (Math_CosS(this->actor.world.rot.y) * (1060.5f * this->actor.scale.z) * scale) + this->actor.world.pos.z; + player->actor.world.pos.y = + this->actor.world.pos.y + (this->actor.scale.y * -500.0f) + (1060.5f * this->actor.scale.y * scale); + invWindupPunchTimer = 1.0f / (this->windupPunchTimer + 6); + // this->gekkoPosOffset *= (1 - invWindupPunchTimer) + this->gekkoPosOffset.x -= this->gekkoPosOffset.x * invWindupPunchTimer; + this->gekkoPosOffset.y -= this->gekkoPosOffset.y * invWindupPunchTimer; + this->gekkoPosOffset.z -= this->gekkoPosOffset.z * invWindupPunchTimer; + scale = 2.0f - (3.0f * scale); + } + + // Deforming Bigslime during the final windup punch while grabbing player using vtxSurfacePerturbation + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + staticVtx = &sBigslimeStaticVtx[i]; + if (this->vtxSurfacePerturbation[i] != 0.0f) { + if (this->windupPunchTimer > 0) { + // loop over x, y, z + for (j = 0; j < 3; j++) { + // Linearly interpolate dynamicVtx --> staticVtx * (1 - scale * vtxSurfacePerturbation) + dynamicVtx->n.ob[j] += (s16)( + ((staticVtx->n.ob[j] - (s32)(scale * staticVtx->n.ob[j] * this->vtxSurfacePerturbation[i])) - + dynamicVtx->n.ob[j]) * + invWindupPunchTimer); + } + } else { + // loop over x, y, z + for (j = 0; j < 3; j++) { + // Directly set dynamicVtx --> staticVtx * (1 - scale * vtxSurfacePerturbation) + dynamicVtx->n.ob[j] = + staticVtx->n.ob[j] - (s32)((scale * staticVtx->n.ob[j]) * this->vtxSurfacePerturbation[i]); + } + } + } else { + if (this->windupPunchTimer > 0) { + // loop over x, y, z + for (j = 0; j < 3; j++) { + // Linearly interpolate dynamicVtx --> staticVtx + dynamicVtx->n.ob[j] += (s16)((staticVtx->n.ob[j] - dynamicVtx->n.ob[j]) * invWindupPunchTimer); + } + } + } + } +} + +void EnBigslime_SetupSetDynamicVtxThrowPlayer(EnBigslime* this, GlobalContext* globalCtx) { + this->grabPlayerTimer = 10; + EnBigslime_SetTargetVtxToWideCone(this); + EnBigslime_CheckVtxWallBoundaries(this); + EnBigslime_EndCutscene(this, globalCtx); + this->actionFunc = EnBigslime_SetDynamicVtxThrowPlayer; +} + +/** + * Restores bigslime to wide cone after player is thrown + */ +void EnBigslime_SetDynamicVtxThrowPlayer(EnBigslime* this, GlobalContext* globalCtx) { + f32 invThrowPlayerTimer; + Vtx* targetVtx; + Vtx* dynamicVtx; + s32 i; + s32 j; + + this->throwPlayerTimer--; + if (this->throwPlayerTimer > 0) { + invThrowPlayerTimer = 1.0f / this->throwPlayerTimer; + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + targetVtx = &sBigslimeTargetVtx[i]; + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + + // loop over x, y, z + for (j = 0; j < 3; j++) { + // Linearly interpolate dynamicVtx --> targetVtx + dynamicVtx->n.ob[j] += (s16)((targetVtx->n.ob[j] - dynamicVtx->n.ob[j]) * invThrowPlayerTimer); + } + } + + this->actor.scale.x = F32_LERPIMP(this->actor.scale.x, 0.2f, invThrowPlayerTimer); + this->actor.scale.y = F32_LERPIMP(this->actor.scale.y, 0.05f, invThrowPlayerTimer); + this->actor.scale.z = this->actor.scale.x; + EnBigslime_CheckVtxWallBoundaries(this); + } + + if (this->throwPlayerTimer == 0) { + EnBigslime_SetupRise(this); + } +} + +/** + * Sets the frozen effect as a seed on the bottom 4 nodes of a sphere + * The frozen effect is initially set to be dimmer the farther from the initial seed you are + */ +void EnBigslime_SetupFreeze(EnBigslime* this) { + Vtx* targetVtx; + Vtx* dynamicVtx; + s32 i; + s32 j; + + this->actor.speedXZ = 0.0f; + this->freezeTimer = 40; + if (this->actor.bgCheckFlags & 1) { + this->actor.velocity.y = 0.0f; + this->actor.gravity = 0.0f; + } else if ((this->actionFunc == EnBigslime_Rise) && (this->riseCounter < 2)) { + this->actor.gravity = -2.0f; + } + + this->bigslimeCollider[0].base.atFlags &= ~AT_ON; + this->bigslimeCollider[0].base.acFlags &= ~AC_ON; + + // Resets frozen effect alpha to 0 + for (i = 0; i < BIGSLIME_NUM_VTX; i++) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][i]; + targetVtx = &sBigslimeTargetVtx[i]; + for (j = 0; j < 3; j++) { + targetVtx->n.ob[j] = dynamicVtx->n.ob[j]; + } + targetVtx->n.a = 0; + } + + // Initalizes frozen effect alpha near bottom of sphere by increasing levels of alpha + for (i = 0; i < 20; i++) { + sBigslimeTargetVtx[i + 138].n.a = 10 * i; + } + + // Initalizes/seeds frozen effect alpha in bottom 4 nodes in vtx sphere to highest level of alpha + for (i = 0; i < 4; i++) { + sBigslimeTargetVtx[i + 158].n.a = 200; + } + + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + this->bigslimeCollider[i].base.ocFlags1 &= ~OC1_NO_PUSH; + } + + this->actionFuncStored = this->actionFunc; + this->actionFunc = EnBigslime_Freeze; +} + +/** + * Propogates the frozen effect from the seed at the bottom out through all vertices + */ +void EnBigslime_Freeze(EnBigslime* this, GlobalContext* globalCtx) { + f32 randFloat; + Vtx* targetVtx; + Vtx* dynamicVtx; + s32 vtxIceUpdate; + s32 vtxIceSeed; + s32 j; + + if (this->freezeTimer) { + this->freezeTimer--; + } + + this->skelAnime.playSpeed = this->freezeTimer / 40.0f; + vtxIceSeed = this->freezeTimer * 4; + for (vtxIceUpdate = 0; vtxIceUpdate < 4; vtxIceUpdate++, vtxIceSeed++) { + if (vtxIceSeed < BIGSLIME_NUM_VTX) { + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][vtxIceSeed]; + targetVtx = &sBigslimeTargetVtx[vtxIceSeed]; + randFloat = randPlusMinusPoint5Scaled(40.0f); + dynamicVtx->n.ob[0] += (s16)(randFloat / this->actor.scale.x); + dynamicVtx->n.ob[1] += (s16)(randFloat / this->actor.scale.y); + dynamicVtx->n.ob[2] += (s16)(randFloat / this->actor.scale.z); + if (((dynamicVtx->n.ob[1] * this->actor.scale.y) + this->actor.world.pos.y) < GBT_ROOM_5_MIN_Y) { + dynamicVtx->n.ob[1] = ((GBT_ROOM_5_MIN_Y - this->actor.world.pos.y) / this->actor.scale.y) - 1.0f; + } + + for (j = 0; j < 3; j++) { + targetVtx->n.ob[j] = dynamicVtx->n.ob[j]; + } + } + } + + for (vtxIceUpdate = 4; vtxIceUpdate < BIGSLIME_NUM_VTX; vtxIceUpdate++) { + sBigslimeTargetVtx[vtxIceUpdate - 4].n.a = sBigslimeTargetVtx[vtxIceUpdate].n.a; + } + + func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + if (this->actor.bgCheckFlags & 2) { + if (this->freezeTimer == 0) { + EnBigslime_BreakIntoMinislime(this, globalCtx); + } else { + this->bigslimeCollider[0].base.acFlags |= AC_ON; + EnBigslime_AddIceShardEffect(this, globalCtx); + EnBigslime_SetupSquishFlat(this); + } + } else if (this->freezeTimer == 0) { + if (!(this->actor.bgCheckFlags & 1)) { + EnBigslime_SetupFrozenFall(this); + } else { + EnBigslime_SetupFrozenGround(this); + } + } +} + +void EnBigslime_SetupFrozenGround(EnBigslime* this) { + this->freezeTimer = 80; + this->bigslimeCollider[0].base.acFlags |= AC_ON; + this->actionFunc = EnBigslime_FrozenGround; +} + +void EnBigslime_FrozenGround(EnBigslime* this, GlobalContext* globalCtx) { + f32 invFreezerTimer; + s32 randSign; + f32 randFloat; + + this->freezeTimer--; + if (this->freezeTimer == 0) { + EnBigslime_AddIceShardEffect(this, globalCtx); + EnBigslime_SetTargetVtxFromPreFrozen(this); + } else if (this->freezeTimer == 40) { + Math_Vec3f_Copy(&this->frozenPos, &this->actor.world.pos); + } else if ((this->freezeTimer < 20) || ((this->freezeTimer < 40) && ((this->freezeTimer % 2) != 0))) { + invFreezerTimer = 1.0f / this->freezeTimer; + + // clang-format off + randFloat = Rand_ZeroFloat(4.0f * invFreezerTimer); + randSign = Rand_ZeroOne() < 0.5f ? -1 : 1; \ + this->actor.world.pos.x = randSign * (1.0f + invFreezerTimer + randFloat) + this->frozenPos.x; + // clang-format on + + randFloat = Rand_ZeroFloat(4.0f * invFreezerTimer); + randSign = Rand_ZeroOne() < 0.5f ? -1 : 1; + this->actor.world.pos.z = randSign * (1.0f + invFreezerTimer + randFloat) + this->frozenPos.z; + } +} + +void EnBigslime_SetupMelt(EnBigslime* this) { + s32 i; + + this->bigslimeCollider[0].base.acFlags &= ~AC_ON; + for (i = 0; i < 2; i++) { + sBigslimeTargetVtx[i].n.a = 0; + } + + for (i = 0; i < 20; i++) { + sBigslimeTargetVtx[i + 2].n.a = 10 * i; + } + + this->meltCounter = 0; + this->actionFunc = EnBigslime_Melt; +} + +void EnBigslime_Melt(EnBigslime* this, GlobalContext* globalCtx) { + static Vec3f iceSmokeVelocity = { 0.0f, 2.0f, 0.0f }; + Vec3f iceSmokePos; + Vtx* targetVtx; + Vtx* dynamicVtx; + s32 i; + + this->meltCounter++; + if ((this->meltCounter < 70) && ((this->meltCounter % 2) != 0)) { + dynamicVtx = + &sBigslimeDynamicVtx[this->dynamicVtxState][(s32)Rand_ZeroFloat(BIGSLIME_NUM_VTX) % BIGSLIME_NUM_VTX]; + iceSmokePos.x = (dynamicVtx->n.ob[0] * this->actor.scale.x) + this->actor.world.pos.x; + iceSmokePos.y = (dynamicVtx->n.ob[1] * this->actor.scale.y) + this->actor.world.pos.y; + iceSmokePos.z = (dynamicVtx->n.ob[2] * this->actor.scale.z) + this->actor.world.pos.z; + EffectSsIceSmoke_Spawn(globalCtx, &iceSmokePos, &iceSmokeVelocity, &gZeroVec3f, 600); + } + + func_800B9010(&this->actor, NA_SE_EV_ICE_MELT_LEVEL - SFX_FLAG); + for (i = 159; i >= 0; i--) { + sBigslimeTargetVtx[i + 2].n.a = sBigslimeTargetVtx[i].n.a; + } + + if (this->meltCounter == 100) { + EnBigslime_SetTargetVtxFromPreFrozen(this); + } else if (this->meltCounter == 50) { + globalCtx->envCtx.unk_C3 = 0xFF; + } +} + +void EnBigslime_SetupFrozenFall(EnBigslime* this) { + s32 i; + + this->bigslimeCollider[0].base.atFlags |= AT_ON; + this->actor.gravity = -2.0f; + this->actor.velocity.y = 0.0f; + + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + this->bigslimeCollider[i].base.ocFlags1 |= OC1_NO_PUSH; + } + + this->actionFunc = EnBigslime_FrozenFall; +} + +void EnBigslime_FrozenFall(EnBigslime* this, GlobalContext* globalCtx) { + s32 i; + + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + if (this->bigslimeCollider[i].base.atFlags & AT_HIT) { + break; + } + } + + if (i != BIGSLIME_NUM_RING_FACES) { + func_800B8D50(globalCtx, &this->actor, 7.0f, this->actor.yawTowardsPlayer, 5.0f, 0x10); + } + + if (this->actor.bgCheckFlags & 1) { + EnBigslime_BreakIntoMinislime(this, globalCtx); + } +} + +void EnBigslime_SetupJumpGekko(EnBigslime* this) { + Animation_PlayLoop(&this->skelAnime, &gGekkoJumpForwardAnim); + this->actor.speedXZ = 8.0f; + this->jumpTimer = 100; + this->actor.world.rot.y = this->gekkoRot.y; + this->gekkoYaw = this->actor.yawTowardsPlayer + 0x8000; + this->actionFunc = EnBigslime_JumpGekko; +} + +void EnBigslime_JumpGekko(EnBigslime* this, GlobalContext* globalCtx) { + s16 yaw; + s16 yawDiff; + + if (this->actor.bgCheckFlags & 1) { + this->gekkoCollider.base.acFlags |= AC_ON; + this->actor.flags |= 1; + } + + this->jumpTimer--; + if (Animation_OnFrame(&this->skelAnime, 1.0f)) { + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_JUMP); + } else if (Animation_OnFrame(&this->skelAnime, 11.0f)) { + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EV_WALK_WATER); + } + + if (!(this->actor.bgCheckFlags & 1) || ((this->skelAnime.curFrame > 1.0f) && (this->skelAnime.curFrame < 12.0f))) { + this->actor.speedXZ = 8.0f; + } else { + this->actor.speedXZ = 0.0f; + } + + if (Math_SmoothStepToS(&this->actor.world.rot.y, this->gekkoYaw, 5, 0x1000, 0x80) == 0) { + if (Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) > 240.0f) { + yaw = Actor_YawToPoint(&this->actor, &this->actor.home.pos); + yawDiff = yaw - (s16)(this->actor.yawTowardsPlayer + 0x8000); + this->gekkoYaw = + ABS_ALT(yawDiff) < 0x3000 ? yaw : (yawDiff / 2) + (s16)(this->actor.yawTowardsPlayer + 0x8000); + } else { + this->gekkoYaw = this->actor.yawTowardsPlayer + 0x8000; + } + } + + this->gekkoRot.y = this->actor.world.rot.y; + if (this->jumpTimer == 0) { + if (this->formBigslimeTimer == 0) { + EnBigslime_SetupCutscene(this); + } else { + this->formBigslimeTimer--; + EnBigslime_SetupIdleLookAround(this); + } + } else if ((this->actor.xzDistToPlayer > 300.0f) && (this->gekkoCollider.base.ocFlags1 & OC1_HIT)) { + if ((this->gekkoCollider.base.oc->params == MINISLIME_IDLE) && + (this->gekkoCollider.base.oc->id == ACTOR_EN_MINISLIME)) { + this->gekkoCollider.base.oc->params = MINISLIME_SETUP_GEKKO_THROW; + this->minislimeToThrow = (EnMinislime*)this->gekkoCollider.base.oc; + EnBigslime_SetupThrowMinislime(this); + } + } +} + +void EnBigslime_SetupIdleLookAround(EnBigslime* this) { + Animation_PlayOnce(&this->skelAnime, &gGekkoNervousIdleAnim); + this->idleTimer = 60; + this->actor.speedXZ = 0.0f; + if (BINANG_SUB(Actor_YawToPoint(&this->actor, &this->actor.home.pos), this->gekkoRot.y) > 0) { + this->gekkoYaw = this->gekkoRot.y + ((u32)Rand_Next() >> 20) + 0x2000; + } else { + this->gekkoYaw = this->gekkoRot.y - ((u32)Rand_Next() >> 20) - 0x2000; + } + this->actionFunc = EnBigslime_IdleLookAround; +} + +void EnBigslime_IdleLookAround(EnBigslime* this, GlobalContext* globalCtx) { + s16 yawDiff; + + this->idleTimer--; + if (this->isAnimUpdate) { + if (Rand_ZeroOne() < 0.25f) { + Animation_PlayOnce(&this->skelAnime, &gGekkoLookAroundAnim); + } else { + Animation_PlayOnce(&this->skelAnime, &gGekkoNervousIdleAnim); + } + } + + if ((this->skelAnime.animation == &gGekkoNervousIdleAnim) && + Math_ScaledStepToS(&this->gekkoRot.y, this->gekkoYaw, 0x400)) { + if (BINANG_SUB(Actor_YawToPoint(&this->actor, &this->actor.home.pos), this->gekkoRot.y) > 0) { + this->gekkoYaw = this->gekkoRot.y + ((u32)Rand_Next() >> 20) + 0x2000; + } else { + this->gekkoYaw = this->gekkoRot.y - ((u32)Rand_Next() >> 20) - 0x2000; + } + } + + yawDiff = this->actor.yawTowardsPlayer - this->gekkoRot.y; + if ((this->idleTimer == 0) || ((ABS_ALT(yawDiff) < 0x2800) && (this->actor.xzDistToPlayer < 240.0f))) { + EnBigslime_SetupIdleNoticePlayer(this); + } +} + +void EnBigslime_SetupIdleNoticePlayer(EnBigslime* this) { + Animation_PlayOnce(&this->skelAnime, &gGekkoSurpriseJumpAnim); + this->gekkoYaw = this->gekkoRot.y + 0x8000; + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_JUMP_MID); + this->actionFunc = EnBigslime_IdleNoticePlayer; +} + +void EnBigslime_IdleNoticePlayer(EnBigslime* this, GlobalContext* globalCtx) { + s16* yaw = &this->gekkoRot.y; + + if (this->skelAnime.curFrame > 10.0f) { + Math_ScaledStepToS(yaw, this->gekkoYaw, 0x800); + } + if (this->isAnimUpdate) { + EnBigslime_SetupJumpGekko(this); + } +} + +void EnBigslime_SetupThrowMinislime(EnBigslime* this) { + Animation_PlayOnce(&this->skelAnime, &gGekkoWindupPunchAnim); + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_HOLD_SLIME); + this->actor.speedXZ = 0.0f; + this->actionFunc = EnBigslime_ThrowMinislime; +} + +void EnBigslime_ThrowMinislime(EnBigslime* this, GlobalContext* globalCtx) { + s16 jumpTimerStored; + + Math_ScaledStepToS(&this->gekkoRot.y, this->actor.yawTowardsPlayer, 0x300); + if (Animation_OnFrame(&this->skelAnime, 27.0f) && + (this->minislimeToThrow->actor.params == MINISLIME_SETUP_GEKKO_THROW)) { + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_THROW_SLIME); + this->minislimeToThrow->actor.params = MINISLIME_GEKKO_THROW; + } + if (this->isAnimUpdate) { + jumpTimerStored = this->jumpTimer; // Stores jumpTimer so it doesn't get overwritten back to 100 + EnBigslime_SetupJumpGekko(this); + this->jumpTimer = jumpTimerStored; + } +} + +void EnBigslime_SetupDamageGekko(EnBigslime* this, s32 isNotFrozen) { + Animation_MorphToPlayOnce(&this->skelAnime, &gGekkoDamagedAnim, -3.0f); + this->gekkoCollider.base.acFlags &= ~AC_ON; + this->damageSpinTimer = 20; + this->actor.speedXZ = 10.0f; + this->actor.gravity = -2.0f; + this->actor.velocity.y = 0.0f; + if (isNotFrozen) { + func_800BE504(&this->actor, &this->gekkoCollider); + } + + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_DAMAGE); + if ((this->actor.flags & 0x2000) == 0x2000) { + this->actor.flags &= ~0x2000; + } + + this->actionFunc = EnBigslime_DamageGekko; +} + +/** + * Spins Gekko around as it takes damage + */ +void EnBigslime_DamageGekko(EnBigslime* this, GlobalContext* globalCtx) { + s32 damageSpinTimer; + + this->damageSpinTimer--; + damageSpinTimer = CLAMP_MAX(this->damageSpinTimer, 10); + this->gekkoRot.y += 0x300 * damageSpinTimer; + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f); + if (this->damageSpinTimer == 0) { + EnBigslime_SetupCutscene(this); + } +} + +void EnBigslime_SetupStunGekko(EnBigslime* this) { + if ((this->skelAnime.animation == &gGekkoJumpForwardAnim) || + (this->skelAnime.animation == &gGekkoSurpriseJumpAnim)) { + this->skelAnime.curFrame = 1.0f; + } + this->actionFunc = EnBigslime_StunGekko; + this->skelAnime.playSpeed = 0.0f; + this->actor.speedXZ = 0.0f; +} + +void EnBigslime_StunGekko(EnBigslime* this, GlobalContext* globalCtx) { + this->stunTimer--; + if (this->stunTimer == 0) { + if (this->gekkoDrawEffect == GEKKO_DRAW_EFFECT_FROZEN) { + EnBigslime_GekkoThaw(this, globalCtx); + EnBigslime_SetupDamageGekko(this, false); + } else { + this->gekkoCollider.base.acFlags &= ~AC_ON; + EnBigslime_SetupCutscene(this); + } + } +} + +void EnBigslime_SetupCutsceneFormBigslime(EnBigslime* this) { + Animation_PlayOnce(&this->skelAnime, &gGekkoJumpUpAnim); + this->gekkoCollider.base.acFlags &= ~AC_ON; + this->actor.world.rot.x = -Actor_PitchToPoint(&this->actor, &this->actor.home.pos); + this->actor.world.rot.y = Actor_YawToPoint(&this->actor, &this->actor.home.pos); + this->actionFunc = EnBigslime_CutsceneFormBigslime; + this->actor.speedXZ = 0.0f; +} + +void EnBigslime_CutsceneFormBigslime(EnBigslime* this, GlobalContext* globalCtx) { + EnBigslime_UpdateCameraFormingBigslime(this, globalCtx); + Math_ScaledStepToS(&this->gekkoRot.y, this->actor.world.rot.y, 0x800); + if (Animation_OnFrame(&this->skelAnime, 18.0f)) { + EnBigslime_SetupFormBigslime(this); + } +} + +void EnBigslime_SetupFormBigslime(EnBigslime* this) { + s32 i; + + this->actor.gravity = 0.0f; + this->gekkoRot.x = 0x4000 - this->actor.world.rot.x; + this->formBigslimeTimer = 0; + this->wavySurfaceTimer = 0; + this->actor.speedXZ = 25.0f; + this->gekkoRot.y = this->actor.world.rot.y; + this->formBigslimeCutsceneTimer = 2; + + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + this->minislime[i]->actor.params = MINISLIME_FORM_BIGSLIME; + } + + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + this->bigslimeCollider[i].base.ocFlags1 |= OC1_NO_PUSH; + } + + this->actor.update = EnBigslime_UpdateBigslime; + this->actor.draw = EnBigslime_DrawBigslime; + Actor_SetScale(&this->actor, 0.0f); + this->vtxScaleX = 0.0f; + this->vtxScaleZ = 0.0f; + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_JUMP_ABOVE); + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_UTSUBO_APPEAR_TRG); + this->actionFunc = EnBigslime_FormBigslime; +} + +void EnBigslime_FormBigslime(EnBigslime* this, GlobalContext* globalCtx) { + f32 xzScale; + f32 yScaleFactor; + s32 i; + + EnBigslime_UpdateWavySurface(this); + EnBigslime_UpdateCameraFormingBigslime(this, globalCtx); + if (this->formBigslimeCutsceneTimer < 0) { + Math_ScaledStepToS(&this->gekkoRot.x, 0, 0x400); + } else if (this->actor.world.pos.y > (GBT_ROOM_5_MAX_Y - 100.0f)) { + this->gekkoRot.x -= 0x4000; + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.home.pos); + this->actor.gravity = 0.0f; + this->actor.velocity.y = 0.0f; + this->actor.speedXZ = 0.0f; + Animation_PlayLoop(&this->skelAnime, &gGekkoSwimForwardAnim); + this->formBigslimeCutsceneTimer--; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_B_SLIME_COMBINE); + } else if (this->isAnimUpdate) { + this->formBigslimeCutsceneTimer--; + if (this->formBigslimeCutsceneTimer == 0) { + Animation_PlayLoop(&this->skelAnime, &gGekkoSwimUpAnim); + } + } + + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + if (this->minislime[i]->actor.params == MINISLIME_SETUP_DISAPPEAR) { + this->minislime[i]->actor.params = MINISLIME_DISAPPEAR; + this->minislimeCounter++; + } + } + + if (this->minislimeCounter > 0) { + yScaleFactor = sqrtf(this->minislimeCounter * (2.0f / 30.0f)) * 0.6f + 0.4f; + xzScale = 0.15f * yScaleFactor; + this->actor.scale.x = xzScale; + this->actor.scale.y = 0.079f * yScaleFactor; + this->actor.scale.z = xzScale; + } + + if (this->minislimeCounter == MINISLIME_NUM_SPAWN) { + this->minislimeState = MINISLIME_INACTIVE_STATE; + this->actor.hintId = 3; + EnBigslime_SetupMoveOnCeiling(this); + } +} + +void EnBigslime_SetupCutsceneDefeat(EnBigslime* this, GlobalContext* globalCtx) { + Vec3f subCamEye; + Vec3f subCamAt; + s32 i; + s16 yawOffset; + + Animation_Change(&this->skelAnime, &gGekkoDamagedAnim, 0.5f, 0.0f, + Animation_GetLastFrame(&gGekkoDamagedAnim.common), 3, 0.0f); + this->gekkoCollider.base.acFlags &= ~AC_ON; + this->defeatTimer = 60; + this->actor.speedXZ = 10.0f; + this->actor.gravity = -2.0f; + this->actor.velocity.y = 0.0f; + EnBigslime_GekkoSfxOutsideBigslime(this, NA_SE_EN_FROG_DEAD); + + // Points the camera at the defeated Gekko + subCamAt.x = this->actor.world.pos.x; + subCamAt.y = this->actor.world.pos.y + 40.0f; + subCamAt.z = this->actor.world.pos.z; + + if (BINANG_SUB(Actor_YawToPoint(&this->actor, &this->actor.home.pos), this->actor.world.rot.y) > 0) { + yawOffset = this->actor.world.rot.y + 0x4000; + } else { + yawOffset = this->actor.world.rot.y - 0x4000; + } + + // Moves the camera to the side of player and Gekko + subCamEye.x = (Math_SinS(yawOffset) * 250.0f) + subCamAt.x; + subCamEye.y = subCamAt.y + 60.0f; + subCamEye.z = (Math_CosS(yawOffset) * 250.0f) + subCamAt.z; + Play_CameraSetAtEye(globalCtx, this->subCamId, &subCamAt, &subCamEye); + + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + this->minislime[i]->actor.params = MINISLIME_DEFEAT_IDLE; + } + + this->actor.flags &= ~1; + EnBigslime_GekkoThaw(this, globalCtx); + this->actionFunc = EnBigslime_CutsceneDefeat; +} + +void EnBigslime_CutsceneDefeat(EnBigslime* this, GlobalContext* globalCtx) { + s32 defeatTimer; + Camera* subCam; + Vec3f subCamAt; + + this->defeatTimer--; + defeatTimer = CLAMP_MAX(this->defeatTimer, 10); + this->gekkoRot.y += 0x300 * defeatTimer; + if (Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f)) { + EnBigslime_SetupGekkoDespawn(this, globalCtx); + } else { + // Continue for the camera to follow Gekko as it spins in defeat + subCam = Play_GetCamera(globalCtx, this->subCamId); + subCamAt.x = this->actor.world.pos.x; + subCamAt.y = this->actor.world.pos.y + 40.0f; + subCamAt.z = this->actor.world.pos.z; + Play_CameraSetAtEye(globalCtx, this->subCamId, &subCamAt, &subCam->eye); + } +} + +void EnBigslime_SetupGekkoDespawn(EnBigslime* this, GlobalContext* globalCtx) { + Camera* subCam = Play_GetCamera(globalCtx, this->subCamId); + f32 magnitude; + f32 invMagnitude; + + Math_Vec3f_Diff(&subCam->eye, &subCam->at, &this->subCamDistToFrog); + magnitude = Math3D_Vec3fMagnitude(&this->subCamDistToFrog); + if (magnitude > 78.0f) { + invMagnitude = 1.0f / magnitude; + magnitude -= 77.0f; + magnitude /= 20.0f; + Math_Vec3f_Scale(&this->subCamDistToFrog, magnitude * invMagnitude); + } else { + Math_Vec3f_Copy(&this->subCamDistToFrog, &gZeroVec3f); + } + + this->shockwaveAlpha = 0; + this->despawnTimer = 20; + this->actionFunc = EnBigslime_GekkoDespawn; +} + +void EnBigslime_GekkoDespawn(EnBigslime* this, GlobalContext* globalCtx) { + Vec3f subCamEye; + Vec3f subCamAt; + Camera* subCam; + + this->despawnTimer--; + this->gekkoScale = this->despawnTimer * 0.00035000002f; + if (this->despawnTimer == 0) { + EnBigslime_SetupFrogSpawn(this, globalCtx); + } else { + subCam = Play_GetCamera(globalCtx, this->subCamId); + Math_Vec3f_Copy(&subCamAt, &subCam->at); + Math_Vec3f_Diff(&subCam->eye, &this->subCamDistToFrog, &subCamEye); + subCamEye.y -= 1.8f; + subCamAt.y -= 1.7f; + Play_CameraSetAtEye(globalCtx, this->subCamId, &subCamAt, &subCamEye); + } +} + +void EnBigslime_SetupFrogSpawn(EnBigslime* this, GlobalContext* globalCtx) { + static Color_RGBA8 dustPrimColor = { 250, 250, 250, 255 }; + static Color_RGBA8 dustEnvColor = { 180, 180, 180, 255 }; + static Vec3f hahenAccel = { 0.0f, -0.5f, 0.0f }; + Camera* subCam = Play_GetCamera(globalCtx, this->subCamId); + Vec3f* worldPos; + Vec3f dustPos; + Vec3f hahenVel; + s16 yaw = func_800DFCDC(GET_ACTIVE_CAM(globalCtx)); + s16 yawReverse = yaw + 0x8000; + s32 i; + + this->gekkoCollider.base.ocFlags1 &= ~OC1_ON; + + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_MINIFROG, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 0, yawReverse, 0, this->actor.params); + + dustPos.x = (Math_SinS(yawReverse) * 20.0f) + this->actor.world.pos.x; + dustPos.y = this->actor.world.pos.y + 20.0f; + worldPos = &this->actor.world.pos; + dustPos.z = (Math_CosS(yawReverse) * 20.0f) + this->actor.world.pos.z; + + Audio_PlaySoundAtPosition(globalCtx, worldPos, 40, NA_SE_EN_NPC_APPEAR); + + // dust cloud where the red frog appears + func_800B0DE0(globalCtx, &dustPos, &gZeroVec3f, &gZeroVec3f, &dustPrimColor, &dustEnvColor, 500, 50); + + for (i = 0; i < 25; i++) { + hahenVel.x = randPlusMinusPoint5Scaled(5.0f); + hahenVel.y = Rand_ZeroFloat(3.0f) + 4.0f; + hahenVel.z = randPlusMinusPoint5Scaled(5.0f); + EffectSsHahen_Spawn(globalCtx, worldPos, &hahenVel, &hahenAccel, 0, Rand_S16Offset(12, 3), HAHEN_OBJECT_DEFAULT, + 10, 0); + } + + this->spawnFrogTimer = 40; + Math_Vec3f_Diff(&subCam->eye, &subCam->at, &this->subCamDistToFrog); + this->actionFunc = EnBigslime_FrogSpawn; +} + +void EnBigslime_FrogSpawn(EnBigslime* this, GlobalContext* globalCtx) { + Camera* subCam = Play_GetCamera(globalCtx, this->subCamId); + Vec3f subCamEye; + f32 subCamZoom; + + this->spawnFrogTimer--; + + // Zoom the camera in and out at the newly spawned red frog + subCamZoom = sin_rad(this->spawnFrogTimer * (M_PI / 5)) * ((0.04f * (this->spawnFrogTimer * 0.1f)) + 0.02f) + 1.0f; + subCamEye.x = subCam->at.x + (this->subCamDistToFrog.x * subCamZoom); + subCamEye.z = subCam->at.z + (this->subCamDistToFrog.z * subCamZoom); + subCamEye.y = subCam->at.y + (this->subCamDistToFrog.y * subCamZoom); + Play_CameraSetAtEye(globalCtx, this->subCamId, &subCam->at, &subCamEye); + + if (this->spawnFrogTimer == 0) { + EnBigslime_EndCutscene(this, globalCtx); + EnBigslime_SetupDespawn(this); + } +} + +void EnBigslime_SetupDespawn(EnBigslime* this) { + s32 i; + + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + this->minislime[i]->actor.params = MINISLIME_DEFEAT_MELT; + } + + this->isDespawned = false; + this->gekkoCollider.base.ocFlags1 &= ~OC1_ON; + this->actionFunc = EnBigslime_Despawn; +} + +void EnBigslime_Despawn(EnBigslime* this, GlobalContext* globalCtx) { + s32 i; + s32 counter = 0; + + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + if (this->minislime[i]->actor.shape.shadowAlpha == 0) { + counter++; + } + } + + if (!this->isDespawned) { + Actor_SetRoomClearedTemp(globalCtx, globalCtx->roomCtx.currRoom.num); + this->isDespawned = true; + } + + if (counter == MINISLIME_NUM_SPAWN) { + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + this->minislime[i]->actor.params = MINISLIME_DESPAWN; + } + + Actor_MarkForDeath(&this->actor); + } +} + +void EnBigslime_SetupInitEntrance(EnBigslime* this) { + this->actionFunc = EnBigslime_InitEntrance; +} + +void EnBigslime_InitEntrance(EnBigslime* this, GlobalContext* globalCtx) { + if (globalCtx->roomCtx.prevRoom.num == -1) { + EnBigslime_SetupCutscene(this); + } +} + +void EnBigslime_SetupCutscene(EnBigslime* this) { + if (ActorCutscene_GetCurrentIndex() == 0x7D) { + ActorCutscene_Stop(0x7D); + } + + if (this->actor.colChkInfo.health == 0) { + this->cutscene = this->actor.cutscene; + } + + ActorCutscene_SetIntentToPlay(this->cutscene); + this->actionFuncStored = this->actionFunc; + this->actionFunc = EnBigslime_PlayCutscene; + this->actor.speedXZ = 0.0f; +} + +void EnBigslime_PlayCutscene(EnBigslime* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCurrentIndex() == 0x7D) { + ActorCutscene_Stop(0x7D); + ActorCutscene_SetIntentToPlay(this->cutscene); + } else if (ActorCutscene_GetCanPlayNext(this->cutscene)) { + ActorCutscene_Start(this->cutscene, &this->actor); + if (this->actionFuncStored != EnBigslime_SquishFlat) { + func_800B724C(globalCtx, &this->actor, 7); + } + + this->subCamId = ActorCutscene_GetCurrentCamera(this->cutscene); + if (this->actor.colChkInfo.health == 0) { + EnBigslime_SetupCutsceneDefeat(this, globalCtx); + } else if ((this->actionFuncStored == EnBigslime_DamageGekko) || + (this->actionFuncStored == EnBigslime_JumpGekko) || + (this->actionFuncStored == EnBigslime_StunGekko)) { + EnBigslime_SetupCutsceneFormBigslime(this); + } else if (this->actionFuncStored == EnBigslime_SquishFlat) { + EnBigslime_SetupCutsceneGrabPlayer(this, globalCtx); + } else { + EnBigslime_SetupCutsceneStartBattle(this, globalCtx); + } + } else { + ActorCutscene_SetIntentToPlay(this->cutscene); + } +} + +void EnBigslime_ApplyDamageEffectBigslime(EnBigslime* this, GlobalContext* globalCtx) { + s32 i; + + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + if (this->bigslimeCollider[i].base.acFlags & AC_HIT) { + this->bigslimeCollider[i].base.acFlags &= ~AC_HIT; + if (this->actionFunc == EnBigslime_FrozenGround) { + if (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_BREAK_ICE) { + EnBigslime_BreakIntoMinislime(this, globalCtx); + break; + } else if (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_FIRE) { + EnBigslime_SetPlayerParams(this, globalCtx); + EnBigslime_SetupMelt(this); + break; + } + } else { + if (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_ICE) { + EnMinislime* minislime; + + globalCtx->envCtx.unk_C3 = 2; + EnBigslime_SetPlayerParams(this, globalCtx); + this->rotation = 0; + EnBigslime_SetupFreeze(this); + minislime = (EnMinislime*)SubS_FindActor(globalCtx, NULL, ACTORCAT_ITEMACTION, ACTOR_ARROW_ICE); + if (minislime != NULL) { + minislime->shakeRefPos.z = -100.0f; + } + break; + } + + if ((this->actor.colChkInfo.damageEffect != BIGSLIME_DMGEFF_STUN) && (this->itemDropTimer == 0)) { + f32 randFloat = Rand_ZeroOne(); + + if (randFloat < 0.15f) { + Item_DropCollectible(globalCtx, &this->actor.world.pos, ITEM00_ARROWS_10); + } else if (randFloat < 0.3f) { + Item_DropCollectible(globalCtx, &this->actor.world.pos, ITEM00_MAGIC_SMALL); + } + this->itemDropTimer = 40; + } + } + } + } + + for (; i < BIGSLIME_NUM_RING_FACES; i++) { + this->bigslimeCollider[i].base.acFlags &= ~AC_HIT; + } +} + +void EnBigslime_ApplyDamageEffectGekko(EnBigslime* this, GlobalContext* globalCtx) { + if (this->gekkoCollider.base.acFlags & AC_HIT) { + this->gekkoCollider.base.acFlags &= ~AC_HIT; + if ((this->gekkoDrawEffect != GEKKO_DRAW_EFFECT_FROZEN) || + !(this->gekkoCollider.info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) { + EnBigslime_EndThrowMinislime(this); + if (this->actor.colChkInfo.damageEffect != BIGSLIME_DMGEFF_HOOKSHOT) { + if (Actor_ApplyDamage(&this->actor) == 0) { + func_800BE504(&this->actor, &this->gekkoCollider); + func_801A2ED8(); + Enemy_StartFinishingBlow(globalCtx, &this->actor); + this->gekkoCollider.base.acFlags &= ~AC_ON; + EnBigslime_GekkoThaw(this, globalCtx); + if ((this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_FIRE) || + (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_LIGHT)) { + this->unk_388 = 4.0f; + this->unk_38C = 0.75f; + if (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_FIRE) { + this->gekkoDrawEffect = GEKKO_DRAW_EFFECT_THAW; + } else { + this->gekkoDrawEffect = GEKKO_DRAW_EFFECT_LIGHT_ORBS; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, + this->gekkoCollider.info.bumper.hitPos.x, + this->gekkoCollider.info.bumper.hitPos.y, + this->gekkoCollider.info.bumper.hitPos.z, 0, 0, 0, CLEAR_TAG_LARGE_LIGHT_RAYS); + } + } else if (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_ICE) { + EnBigslime_GekkoFreeze(this); + } + EnBigslime_SetupCutscene(this); + } else if (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_ELECTRIC_STUN) { + this->stunTimer = 40; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->gekkoDrawEffect = GEKKO_DRAW_EFFECT_ELECTRIC_STUN; + this->unk_38C = 0.75f; + this->unk_388 = 2.0f; + EnBigslime_SetupStunGekko(this); + } else if (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_STUN || + this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_DEKU_STUN) { + this->stunTimer = 40; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + EnBigslime_SetupStunGekko(this); + } else if (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_ICE) { + EnBigslime_GekkoFreeze(this); + func_800BE504(&this->actor, &this->gekkoCollider); + EnBigslime_SetupStunGekko(this); + } else { + EnBigslime_GekkoThaw(this, globalCtx); + if ((this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_FIRE) || + (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_LIGHT)) { + this->unk_388 = 3.0f; + this->unk_38C = 0.75f; + if (this->actor.colChkInfo.damageEffect == BIGSLIME_DMGEFF_FIRE) { + this->gekkoDrawEffect = GEKKO_DRAW_EFFECT_THAW; + } else { + this->gekkoDrawEffect = GEKKO_DRAW_EFFECT_LIGHT_ORBS; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, + this->gekkoCollider.info.bumper.hitPos.x, + this->gekkoCollider.info.bumper.hitPos.y, + this->gekkoCollider.info.bumper.hitPos.z, 0, 0, 0, CLEAR_TAG_LARGE_LIGHT_RAYS); + } + } + EnBigslime_SetupDamageGekko(this, true); + } + } + } + } +} + +/** + * Adds ice shard effects and calls EnBigslime_InitShockwave + */ +void EnBigslime_AddIceShardEffect(EnBigslime* this, GlobalContext* globalCtx) { + Vtx* targetVtx = &sBigslimeTargetVtx[0]; + EnBigslimeIceShardEffect* iceShardEffect; + s32 i; + f32 randFloat; + s16 randPitch; // Elevation Angle + s16 vtxX; + s16 vtxZ; + f32 xzDist; + + for (i = 0; i < BIGSLIME_NUM_VTX; i++, targetVtx++) { + if (targetVtx->n.a > 0) { + iceShardEffect = &this->iceShardEffect[i]; + iceShardEffect->pos.x = (targetVtx->n.ob[0] * this->actor.scale.x) + this->actor.world.pos.x; + iceShardEffect->pos.y = (targetVtx->n.ob[1] * this->actor.scale.y) + this->actor.world.pos.y; + iceShardEffect->pos.z = (targetVtx->n.ob[2] * this->actor.scale.z) + this->actor.world.pos.z; + iceShardEffect->rotation.x = Rand_Next() >> 0x10; + iceShardEffect->rotation.y = Rand_Next() >> 0x10; + iceShardEffect->rotation.z = Rand_Next() >> 0x10; + iceShardEffect->isActive = true; + randPitch = Rand_S16Offset(0x1000, 0x3000); + vtxZ = targetVtx->n.ob[2]; + vtxX = targetVtx->n.ob[0]; + xzDist = sqrtf(SQ(vtxZ) + SQ(vtxX)); + randFloat = Rand_ZeroFloat(5.0f) + 14.0f; + if (xzDist > 1.0f) { + xzDist = Math_CosS(randPitch) * randFloat / xzDist; + } else { + xzDist = Math_CosS(randPitch) * randFloat; + } + + iceShardEffect->vel.x = targetVtx->n.ob[0] * xzDist; + iceShardEffect->vel.y = Math_SinS(randPitch) * randFloat; + iceShardEffect->vel.z = targetVtx->n.ob[2] * xzDist; + iceShardEffect->scale = 0.001f * (Rand_ZeroFloat(6.0f) + 2.0f); + } + } + + Audio_PlayActorSound2(&this->actor, NA_SE_EV_ICE_BROKEN); + EnBigslime_InitShockwave(this, globalCtx); +} + +/** + * Updates ice shard effects, shockwave effects, and actor damage draw effects + */ +void EnBigslime_UpdateEffects(EnBigslime* this) { + EnBigslimeIceShardEffect* iceShardEffect; + s32 i; + + // Update ice shards + for (i = 0; i < BIGSLIME_NUM_ICE_SHARD; i++) { + iceShardEffect = &this->iceShardEffect[i]; + if (iceShardEffect->isActive > false) { + iceShardEffect->vel.y += -1.0f; + Math_Vec3f_Sum(&iceShardEffect->pos, &iceShardEffect->vel, &iceShardEffect->pos); + if (iceShardEffect->pos.y < (GBT_ROOM_5_MIN_Y - 20.0f)) { + iceShardEffect->isActive = false; + } + iceShardEffect->rotation.x += (s16)(((u32)Rand_Next() >> 0x17) + 0x700); + iceShardEffect->rotation.y += (s16)(((u32)Rand_Next() >> 0x17) + 0x900); + iceShardEffect->rotation.z += (s16)(((u32)Rand_Next() >> 0x17) + 0xB00); + } + } + + // update shockwave + if (this->shockwaveAlpha > 0) { + this->shockwaveAlpha = (this->shockwaveAlpha - 10 < 0) ? 0 : (this->shockwaveAlpha - 10); + this->shockwaveScale += 0.0013f; + } + + // update actor damage draw effects + if (this->unk_388 > 0.0f) { + if ((this->gekkoDrawEffect != GEKKO_DRAW_EFFECT_FROZEN) && (this->actionFunc != EnBigslime_PlayCutscene)) { + Math_StepToF(&this->unk_388, 0.0f, 0.05f); + this->unk_38C = 0.375f * (this->unk_388 + 1.0f); + this->unk_38C = CLAMP_MAX(this->unk_38C, 0.75f); + } else if (!Math_StepToF(&this->unk_390, 0.75f, 0.01875f)) { + func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } + } +} + +void EnBigslime_UpdateBigslime(Actor* thisx, GlobalContext* globalCtx) { + EnBigslime* this = THIS; + s32 i; + Vec3f vtxMax; + Vec3f vtxMin; + + if (globalCtx->envCtx.unk_C3 == 3) { + globalCtx->envCtx.unk_C3 = 0xFF; + } + + func_8019F540(1); + this->dynamicVtxState ^= 1; + EnBigslime_DynamicVtxCopyState(this); + this->isAnimUpdate = SkelAnime_Update(&this->skelAnime); + if (this->actionFunc != EnBigslime_PlayCutscene) { + EnBigslime_ApplyDamageEffectBigslime(this, globalCtx); + } else { + for (i = 0; i < BIGSLIME_NUM_RING_FACES; i++) { + this->bigslimeCollider[i].base.acFlags &= ~AC_HIT; + } + } + + this->actionFunc(this, globalCtx); + + if (this->actionFunc != EnBigslime_FormBigslime) { + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + } else { + Actor_SetVelocityAndMoveXYRotation(&this->actor); + } + + if (this->actionFunc != EnBigslime_JumpGekko) { + EnBigslime_GetMaxMinVertices(this, &vtxMax, &vtxMin); + EnBigslime_UpdateScale(this, &vtxMax, &vtxMin); + EnBigslime_CheckRoomBoundaries(this, &vtxMax, &vtxMin); + EnBigslime_UpdateSurfaceNorm(this); + EnBigslime_UpdateBigslimeCollider(this, globalCtx); + } + + EnBigslime_UpdateEffects(this); + + if (this->itemDropTimer > 0) { + this->itemDropTimer--; + } +} + +void EnBigslime_UpdateGekko(Actor* thisx, GlobalContext* globalCtx) { + static s32 isGekkoOnGround = false; + EnBigslime* this = THIS; + Player* player; + s32 pad; + + if (globalCtx->envCtx.unk_C3 == 3) { + globalCtx->envCtx.unk_C3 = 0xFF; + } + + func_8019F540(0); + this->isAnimUpdate = SkelAnime_Update(&this->skelAnime); + if (this->actionFunc != EnBigslime_PlayCutscene) { + EnBigslime_ApplyDamageEffectGekko(this, globalCtx); + } else { + this->gekkoCollider.base.acFlags &= ~AC_HIT; + } + + this->actionFunc(this, globalCtx); + if (this->actionFunc != EnBigslime_FormBigslime) { + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + } else { + Actor_SetVelocityAndMoveXYRotation(&this->actor); + } + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 40.0f, 80.0f, 0x1F); + this->gekkoCollider.dim.pos.x = (s16)this->actor.world.pos.x; + this->gekkoCollider.dim.pos.z = (s16)this->actor.world.pos.z; + if (this->gekkoCollider.base.acFlags & AC_ON) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->gekkoCollider.base); + } + + if ((this->actor.update == EnBigslime_UpdateGekko) && (this->gekkoCollider.base.ocFlags1 & OC1_ON)) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->gekkoCollider.base); + } + + EnBigslime_UpdateEffects(this); + + if ((this->actionFunc != EnBigslime_StunGekko) && + (this->gekkoCollider.dim.pos.y < (s16)(3.0f + GBT_ROOM_5_MIN_Y))) { + Vec3f vtxNorm; + + if (((globalCtx->gameplayFrames % 4) == 0) || !isGekkoOnGround) { + player = GET_PLAYER(globalCtx); + vtxNorm.x = this->actor.world.pos.x; + vtxNorm.z = this->actor.world.pos.z; + vtxNorm.y = player->actor.world.pos.y + player->actor.depthInWater; + EffectSsGRipple_Spawn(globalCtx, &vtxNorm, 150, 550, 0); + isGekkoOnGround = true; + } + } else { + isGekkoOnGround = false; + } +} + +/** + * Related to transforming and drawing shadows + */ +void EnBigslime_SetSysMatrix(Vec3f* pos, GlobalContext* globalCtx, Gfx* shadowDList, f32 scaleX, f32 scalez, f32 scaleY, + s16 rotation, f32 alpha) { + f32 yDistMinY; + f32 xz; + MtxF* sysMatrix = Matrix_GetCurrentState(); + + yDistMinY = pos->y - scaleY - GBT_ROOM_5_MIN_Y; + yDistMinY = CLAMP((yDistMinY), 0.0f, (GBT_ROOM_5_CENTER_Y - GBT_ROOM_5_MIN_Y) / 2); + xz = 1.0f - (yDistMinY * (1.0f / 1550.0f)); + + OPEN_DISPS(globalCtx->state.gfxCtx); + POLY_OPA_DISP = Gfx_CallSetupDL(POLY_OPA_DISP, 0x2C); + sysMatrix->xx = xz; + sysMatrix->yy = 1.0f; + sysMatrix->zz = xz; + sysMatrix->xz = sysMatrix->xy = 0.0f; + sysMatrix->yz = sysMatrix->yx = 0.0f; + sysMatrix->zy = sysMatrix->zx = 0.0f; + sysMatrix->wx = pos->x; + sysMatrix->wy = GBT_ROOM_5_MIN_Y; + sysMatrix->wz = pos->z; + sysMatrix->xw = sysMatrix->yw = sysMatrix->zw = 0.0f; + sysMatrix->ww = 1.0f; + + Matrix_RotateY(rotation, MTXMODE_APPLY); + Matrix_Scale(scaleX, 1.0f, scalez, MTXMODE_APPLY); + if (shadowDList != gBigslimeShadowDL) { + gDPSetCombineLERP(POLY_OPA_DISP++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, COMBINED, 0, 0, 0, + COMBINED); + } + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 0, 0, 0, (u8)(alpha * xz)); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, shadowDList); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnBigslime_DrawMinislime(EnBigslime* this, GlobalContext* globalCtx) { + EnMinislime* minislime; + GlobalContext* globalCtx2 = globalCtx; + s32 pad; + s32 currIndex; + s32 i; + Lights* lights; + s32 indices[MINISLIME_NUM_SPAWN]; + + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + indices[i] = i; + } + + // Insertion sorting algorithm based on z projected Pos + for (i = 0; i < MINISLIME_NUM_SPAWN - 1; i++) { + if (this->minislime[indices[i]]->actor.projectedPos.z < this->minislime[indices[i + 1]]->actor.projectedPos.z) { + currIndex = indices[i]; + indices[i] = indices[i + 1]; + indices[i + 1] = currIndex; + if (i != 0) { + i -= 2; + } + } + } + + OPEN_DISPS(globalCtx->state.gfxCtx); + for (i = 0; i < MINISLIME_NUM_SPAWN; i++) { + minislime = this->minislime[indices[i]]; + lights = LightContext_NewLights(&globalCtx2->lightCtx, globalCtx->state.gfxCtx); + Lights_BindAll(lights, globalCtx2->lightCtx.listHead, &minislime->actor.world.pos, globalCtx); + Lights_Draw(lights, globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + func_800B8118(&minislime->actor, globalCtx, 0); + Matrix_SetStateRotationAndTranslation(minislime->actor.world.pos.x, minislime->actor.world.pos.y, + minislime->actor.world.pos.z, &minislime->actor.shape.rot); + Matrix_Scale(minislime->actor.scale.x, minislime->actor.scale.y, minislime->actor.scale.z, MTXMODE_APPLY); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, minislime->actor.shape.shadowAlpha); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, &gMinislimeNormalDL); + if (minislime->frozenAlpha > 0) { + Matrix_InsertTranslation(0.0f, (0.1f - minislime->frozenScale) * -4000.0f, 0.0f, 1); + Matrix_Scale(0.1f, minislime->frozenScale, 0.1f, MTXMODE_APPLY); + AnimatedMat_Draw(globalCtx, this->minislimeFrozenTexAnim); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, minislime->frozenAlpha); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, &gMinislimeFrozenDL); + } + + EnBigslime_SetSysMatrix(&minislime->actor.world.pos, globalCtx, gBigslimeShadowDL, + (minislime->actor.scale.x * 0.4f) * 0.1f, (minislime->actor.scale.z * 0.4f) * 0.1f, + minislime->actor.scale.y * 400.0f, minislime->actor.shape.rot.y, + minislime->actor.shape.shadowAlpha * (175.0f / 255.0f)); + } + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnBigslime_DrawBigslime(Actor* thisx, GlobalContext* globalCtx) { + // 28 equidistance-spaced vtx Points (uniformally over the sphere) + static EnBigslimeBubbles bubblesInfo[] = { + { 0, 0.3f }, { 6, 0.1f }, { 12, 0.45f }, { 18, 0.5f }, { 24, 0.6f }, { 30, 0.2f }, { 36, 0.4f }, + { 42, 0.25f }, { 48, 0.35f }, { 54, 0.65f }, { 60, 0.25f }, { 66, 0.55f }, { 72, 0.3f }, { 78, 0.1f }, + { 84, 0.45f }, { 90, 0.5f }, { 96, 0.6f }, { 102, 0.2f }, { 108, 0.4f }, { 114, 0.15f }, { 120, 0.35f }, + { 126, 0.65f }, { 132, 0.25f }, { 138, 0.3f }, { 144, 0.15f }, { 150, 0.45f }, { 156, 0.3f }, { 161, 0.25f }, + }; + EnBigslime* this = THIS; + EnBigslimeBubbles* bubblesInfoPtr; + Vtx* dynamicVtx; + MtxF* billboardMtxF; + s32 i; + + func_8012C2DC(globalCtx->state.gfxCtx); + func_800B8118(&this->actor, globalCtx, 0); + OPEN_DISPS(globalCtx->state.gfxCtx); + + // Draw Bigslime + gSPSegment(POLY_XLU_DISP++, 0x09, sBigslimeDynamicVtx[this->dynamicVtxState]); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, &gBigslimeNormalDL); + gSPDisplayList(POLY_XLU_DISP++, &gBigslimeVtxDL); + + // Draw frozen Bigslime + if ((this->actionFunc == EnBigslime_Freeze) || (this->actionFunc == EnBigslime_FrozenGround) || + (this->actionFunc == EnBigslime_FrozenFall) || (this->actionFunc == EnBigslime_Melt)) { + AnimatedMat_Draw(globalCtx, this->bigslimeFrozenTexAnim); + gSPSegment(POLY_XLU_DISP++, 0x09, sBigslimeTargetVtx); + gSPDisplayList(POLY_XLU_DISP++, &gBigslimeFrozenVtxDL); + gSPDisplayList(POLY_XLU_DISP++, &gBigslimeVtxDL); + } + + // Draw bubbles inside Bigslime + if (this->actor.scale.x > 0.0f) { + Matrix_SetCurrentState(&globalCtx->billboardMtxF); + Matrix_Scale(0.0050000003f, 0.0050000003f, 0.0050000003f, MTXMODE_APPLY); + billboardMtxF = Matrix_GetCurrentState(); + + for (i = 0; i < 28; i++) { + bubblesInfoPtr = &bubblesInfo[i]; + dynamicVtx = &sBigslimeDynamicVtx[this->dynamicVtxState][bubblesInfoPtr->v]; + billboardMtxF->wx = + dynamicVtx->n.ob[0] * this->actor.scale.x * bubblesInfoPtr->scaleVtx + this->actor.world.pos.x; + billboardMtxF->wy = + dynamicVtx->n.ob[1] * this->actor.scale.y * bubblesInfoPtr->scaleVtx + this->actor.world.pos.y; + billboardMtxF->wz = + dynamicVtx->n.ob[2] * this->actor.scale.z * bubblesInfoPtr->scaleVtx + this->actor.world.pos.z; + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, &gBigslimeBubbleDL); + } + } + CLOSE_DISPS(globalCtx->state.gfxCtx); + + EnBigslime_SetSysMatrix(&this->actor.world.pos, globalCtx, gBigslimeShadowDL, this->vtxScaleX, this->vtxScaleZ, + this->actor.scale.y * BIGSLIME_RADIUS_F, this->rotation, 175.0f); + EnBigslime_DrawGekko(&this->actor, globalCtx); +} + +void EnBigslime_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + /* value -1: Limb Not used + * value 0: GEKKO_LIMB_WAIST + * value 1: GEKKO_LIMB_L_SHIN + * value 2: GEKKO_LIMB_L_FOOT + * value 3: GEKKO_LIMB_R_SHIN + * value 4: GEKKO_LIMB_R_FOOT + * value 5: GEKKO_LIMB_L_UPPER_ARM + * value 6: GEKKO_LIMB_L_FOREARM + * value 7: GEKKO_LIMB_L_HAND + * value 8: GEKKO_LIMB_R_UPPER_ARM + * value 9: GEKKO_LIMB_R_FOREARM + * value 10: GEKKO_LIMB_R_HAND + * value 11: GEKKO_LIMB_JAW + */ + static s8 limbPosIndex[] = { + -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, 6, -1, 7, 8, 9, -1, 10, -1, 11, -1, -1, + }; + // Some kind of offset for the position of the Gekkos right foot + static Vec3f rightFootOffsetRef = { 1500.0f, 2200.0f, 0.0f }; + EnBigslime* this = THIS; + Vec3f rightFootOffset; + + if (limbIndex == GEKKO_LIMB_HEAD) { + Matrix_GetStateTranslation(&this->actor.focus.pos); + this->actor.focus.rot.y = this->gekkoRot.y; + } + + if (limbPosIndex[limbIndex] != -1) { + Matrix_GetStateTranslation(&this->limbPos[limbPosIndex[limbIndex]]); + } + + if (limbIndex == GEKKO_LIMB_R_ANKLE) { + Matrix_MultiplyVector3fByState(&rightFootOffsetRef, &rightFootOffset); + this->gekkoCollider.dim.pos.y = rightFootOffset.y; + } +} + +void EnBigslime_DrawGekko(Actor* thisx, GlobalContext* globalCtx) { + static Color_RGBA8 gekkoDamageColor = { 255, 0, 0, 0 }; + static Color_RGBA8 gekkoStunColor = { 0, 0, 255, 0 }; + Vec3f gekkoPos; + EnBigslime* this = THIS; + s32 pad; + + func_8012C28C(globalCtx->state.gfxCtx); + if (this->actionFunc == EnBigslime_DamageGekko) { + func_800AE434(globalCtx, &gekkoDamageColor, this->damageSpinTimer, 20); + } else if ((this->actionFunc == EnBigslime_CutsceneDefeat) || (this->actionFunc == EnBigslime_GekkoDespawn)) { + func_800AE434(globalCtx, &gekkoDamageColor, 20, 20); + } else if (this->actionFunc == EnBigslime_StunGekko) { + if (this->gekkoDrawEffect == GEKKO_DRAW_EFFECT_FROZEN) { + func_800AE434(globalCtx, &gekkoDamageColor, this->stunTimer, 80); + } else if (this->gekkoDrawEffect == GEKKO_DRAW_EFFECT_ELECTRIC_STUN) { + func_800AE434(globalCtx, &gekkoStunColor, this->stunTimer, 40); + } else { + func_800AE434(globalCtx, &gekkoStunColor, this->stunTimer, 40); + } + } + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Math_Vec3f_Sum(&this->actor.world.pos, &this->gekkoPosOffset, &gekkoPos); + Matrix_SetStateRotationAndTranslation(gekkoPos.x, gekkoPos.y, gekkoPos.z, &this->gekkoRot); + Matrix_Scale(this->gekkoScale, this->gekkoScale, this->gekkoScale, MTXMODE_APPLY); + SkinMatrix_Vec3fMtxFMultXYZ(&globalCtx->viewProjectionMtxF, &gekkoPos, &this->gekkoProjectedPos); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + NULL, EnBigslime_PostLimbDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + if ((this->actionFunc == EnBigslime_DamageGekko) || (this->actionFunc == EnBigslime_CutsceneDefeat) || + (this->actionFunc == EnBigslime_GekkoDespawn) || (this->actionFunc == EnBigslime_StunGekko)) { + func_800AE5A0(globalCtx); + } + + EnBigslime_SetSysMatrix(&gekkoPos, globalCtx, D_04076BC0, this->gekkoScale * (550.0f / 7.0f), + this->gekkoScale * (550.0f / 7.0f), 0.0f, 0, 255.0f); + + if (this->minislimeState != MINISLIME_INACTIVE_STATE) { + EnBigslime_DrawMinislime(this, globalCtx); + } + + EnBigslime_DrawShatteringEffects(this, globalCtx); + + // Draw actor damage effects + func_800BE680(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), + this->gekkoScale * (999.99991f / 7.0f) * this->unk_38C, this->unk_390, this->unk_388, + this->gekkoDrawEffect); +} + +void EnBigslime_DrawShatteringEffects(EnBigslime* this, GlobalContext* globalCtx) { + EnBigslimeIceShardEffect* iceShardEffect; + s32 i; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + // Draw Shockwave + if (this->shockwaveAlpha > 0) { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 225, 235, this->shockwaveAlpha); + gSPSegment(POLY_XLU_DISP++, 0x0D, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, globalCtx->gameplayFrames % 128, + (u8)(globalCtx->gameplayFrames * 8), 32, 64, 1, + (-globalCtx->gameplayFrames * 2) % 64, 0, 16, 16)); + Matrix_InsertTranslation(this->frozenPos.x, this->frozenPos.y, this->frozenPos.z, MTXMODE_NEW); + Matrix_Scale(this->shockwaveScale, this->shockwaveScale, this->shockwaveScale, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, &gBigslimeShockwaveDL); + } + + // Draw Ice Shards + AnimatedMat_Draw(globalCtx, this->iceShardTexAnim); + gSPDisplayList(POLY_XLU_DISP++, &gBigslimeIceShardDL); + + for (i = 0; i < BIGSLIME_NUM_ICE_SHARD; i++) { + iceShardEffect = &this->iceShardEffect[i]; + if (iceShardEffect->isActive > false) { + Matrix_SetStateRotationAndTranslation(iceShardEffect->pos.x, iceShardEffect->pos.y, iceShardEffect->pos.z, + &iceShardEffect->rotation); + Matrix_Scale(iceShardEffect->scale, iceShardEffect->scale, iceShardEffect->scale, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, &gBigslimeIceShardVtxDL); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.h b/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.h index 419b6c1f6..3f57f1666 100644 --- a/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.h +++ b/src/overlays/actors/ovl_En_Bigslime/z_en_bigslime.h @@ -63,7 +63,7 @@ typedef struct EnBigslime { u8 minislimeCounter; u8 numGekkoMeleeAttacks; // The Gekko will melee-attack link at 1-3 times at each position while engulfed in bigslime }; - /* 0x02B4 */ u8 iceShardAlpha; + /* 0x02B4 */ u8 shockwaveAlpha; /* 0x02B5 */ u8 gekkoDrawEffect; /* 0x02B6 */ s16 gekkoYaw; /* 0x02B8 */ s16 cutscene; @@ -95,16 +95,16 @@ typedef struct EnBigslime { }; /* 0x02C2 */ s16 ceilingDropTimer; // Bigslime is still during this timer and shakes before dropping /* 0x02C4 */ s16 numGekkoPosGrabPlayer; // The Gekko will melee-attack link at 6 positions while engulfed in bigslime - /* 0x02C6 */ s16 camId; - /* 0x02C8 */ s16 cameraYawGrabPlayer; + /* 0x02C6 */ s16 subCamId; + /* 0x02C8 */ s16 subCamYawGrabPlayer; /* 0x02CA */ s16 rotation; // is always 0, used in Matrix_RotateY /* 0x02CC */ s16 itemDropTimer; // items only drop when zero, Set to 40 then decrements, prevents itemDrop spam /* 0x02CE */ Vec3s gekkoRot; /* 0x02D4 */ Vec3f gekkoPosOffset; // Used when Bigslime grabs link /* 0x02E0 */ Vec3f gekkoProjectedPos; /* 0x02EC */ union { - Vec3f iceShardRefPos; - Vec3f eyeDistToFrog; // Used to zoom into frogs as Gekko despawns/Frog spawns + Vec3f frozenPos; + Vec3f subCamDistToFrog; // Used to zoom into frogs as Gekko despawns/Frog spawns }; /* 0x02F8 */ Vec3f limbPos[12]; /* 0x0388 */ f32 unk_388; // used as arg to func_800BE680 @@ -114,14 +114,14 @@ typedef struct EnBigslime { /* 0x0398 */ f32 vtxSurfacePerturbation[BIGSLIME_NUM_VTX]; /* 0x0620 */ f32 vtxScaleX; /* 0x0624 */ f32 vtxScaleZ; - /* 0x0628 */ f32 iceShardScale; + /* 0x0628 */ f32 shockwaveScale; /* 0x062C */ ColliderCylinder gekkoCollider; /* 0x0678 */ ColliderCylinder bigslimeCollider[BIGSLIME_NUM_RING_FACES]; /* 0x0A14 */ EnMinislime* minislime[MINISLIME_NUM_SPAWN]; /* 0x0A44 */ EnMinislime* minislimeToThrow; - /* 0x0A48 */ AnimatedMaterial* bigslimeFrozenTex; - /* 0x0A4C */ AnimatedMaterial* minislimeFrozenTex; - /* 0x0A50 */ AnimatedMaterial* iceShardTex; + /* 0x0A48 */ AnimatedMaterial* bigslimeFrozenTexAnim; + /* 0x0A4C */ AnimatedMaterial* minislimeFrozenTexAnim; + /* 0x0A50 */ AnimatedMaterial* iceShardTexAnim; /* 0x0A54 */ EnBigslimeIceShardEffect iceShardEffect[BIGSLIME_NUM_ICE_SHARD]; // 312 = 162 (bigslime) + 10 * 15 (minislime) } EnBigslime; // size = 0x3634 diff --git a/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.c b/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.c index fa8eb472f..3b7220221 100644 --- a/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.c +++ b/src/overlays/actors/ovl_En_Bji_01/z_en_bji_01.c @@ -116,8 +116,7 @@ void func_809CCEE8(EnBji01* this, GlobalContext* globalCtx) { return; } } else { - this->moonsTear = - (ObjMoonStone*)func_ActorCategoryIterateById(globalCtx, NULL, ACTORCAT_PROP, ACTOR_OBJ_MOON_STONE); + this->moonsTear = (ObjMoonStone*)SubS_FindActor(globalCtx, NULL, ACTORCAT_PROP, ACTOR_OBJ_MOON_STONE); } func_800B8500(&this->actor, globalCtx, 60.0f, 10.0f, 0); } @@ -144,7 +143,7 @@ void func_809CD028(EnBji01* this, GlobalContext* globalCtx) { } break; case PLAYER_FORM_HUMAN: - if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEI) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEIS_MASK) { this->textId = 0x236A; } else if (gSaveContext.weekEventReg[74] & 0x10) { this->textId = 0x5F6; @@ -350,8 +349,7 @@ void EnBji01_Init(Actor* thisx, GlobalContext* globalCtx) { Actor_SetScale(&this->actor, 0.01f); func_8013E3B8(&this->actor, this->cutscenes, ARRAY_COUNT(this->cutscenes)); /* initializes all elements of cutscenes to -1 */ - this->moonsTear = - (ObjMoonStone*)func_ActorCategoryIterateById(globalCtx, NULL, ACTORCAT_PROP, ACTOR_OBJ_MOON_STONE); + this->moonsTear = (ObjMoonStone*)SubS_FindActor(globalCtx, NULL, ACTORCAT_PROP, ACTOR_OBJ_MOON_STONE); switch (gSaveContext.entranceIndex) { case 0x4C00: /* Observatory from ECT */ diff --git a/src/overlays/actors/ovl_En_Bjt/z_en_bjt.c b/src/overlays/actors/ovl_En_Bjt/z_en_bjt.c index c09bb4cea..f4814fac2 100644 --- a/src/overlays/actors/ovl_En_Bjt/z_en_bjt.c +++ b/src/overlays/actors/ovl_En_Bjt/z_en_bjt.c @@ -1,7 +1,7 @@ /* - * File z_en_bjt.c + * File: z_en_bjt.c * Overlay: ovl_En_Bjt - * Description: Hand in Toilet + * Description: ??? (Hand in toilet) */ #include "z_en_bjt.h" diff --git a/src/overlays/actors/ovl_En_Boj_01/z_en_boj_01.c b/src/overlays/actors/ovl_En_Boj_01/z_en_boj_01.c index 9a3304b8a..e070bea5e 100644 --- a/src/overlays/actors/ovl_En_Boj_01/z_en_boj_01.c +++ b/src/overlays/actors/ovl_En_Boj_01/z_en_boj_01.c @@ -1,5 +1,5 @@ /* - * File z_en_boj_01.c + * File: z_en_boj_01.c * Overlay: ovl_En_Boj_01 * Description: [Empty] */ diff --git a/src/overlays/actors/ovl_En_Boj_02/z_en_boj_02.c b/src/overlays/actors/ovl_En_Boj_02/z_en_boj_02.c index 19b384d7f..9899a15e0 100644 --- a/src/overlays/actors/ovl_En_Boj_02/z_en_boj_02.c +++ b/src/overlays/actors/ovl_En_Boj_02/z_en_boj_02.c @@ -1,5 +1,5 @@ /* - * File z_en_boj_02.c + * File: z_en_boj_02.c * Overlay: ovl_En_Boj_02 * Description: [Empty] */ diff --git a/src/overlays/actors/ovl_En_Boj_03/z_en_boj_03.c b/src/overlays/actors/ovl_En_Boj_03/z_en_boj_03.c index 4391e59fb..019f80538 100644 --- a/src/overlays/actors/ovl_En_Boj_03/z_en_boj_03.c +++ b/src/overlays/actors/ovl_En_Boj_03/z_en_boj_03.c @@ -1,5 +1,5 @@ /* - * File z_en_boj_03.c + * File: z_en_boj_03.c * Overlay: ovl_En_Boj_03 * Description: [Empty] */ diff --git a/src/overlays/actors/ovl_En_Boj_04/z_en_boj_04.c b/src/overlays/actors/ovl_En_Boj_04/z_en_boj_04.c index 4fea47b30..9952f706d 100644 --- a/src/overlays/actors/ovl_En_Boj_04/z_en_boj_04.c +++ b/src/overlays/actors/ovl_En_Boj_04/z_en_boj_04.c @@ -1,5 +1,5 @@ /* - * File z_en_boj_04.c + * File: z_en_boj_04.c * Overlay: ovl_En_Boj_04 * Description: [Empty] */ diff --git a/src/overlays/actors/ovl_En_Boj_05/z_en_boj_05.c b/src/overlays/actors/ovl_En_Boj_05/z_en_boj_05.c index b327b381c..a3a9dcff8 100644 --- a/src/overlays/actors/ovl_En_Boj_05/z_en_boj_05.c +++ b/src/overlays/actors/ovl_En_Boj_05/z_en_boj_05.c @@ -1,5 +1,5 @@ /* - * File z_en_boj_05.c + * File: z_en_boj_05.c * Overlay: ovl_En_Boj_05 * Description: [Empty] */ diff --git a/src/overlays/actors/ovl_En_Bom/z_en_bom.c b/src/overlays/actors/ovl_En_Bom/z_en_bom.c index acb36d258..d135e2b35 100644 --- a/src/overlays/actors/ovl_En_Bom/z_en_bom.c +++ b/src/overlays/actors/ovl_En_Bom/z_en_bom.c @@ -1,5 +1,5 @@ /* - * File z_en_bom.c + * File: z_en_bom.c * Overlay: ovl_En_Bom * Description: Bomb / Powder Keg */ diff --git a/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c b/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c index 919fd5798..4ec8ae2b6 100644 --- a/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c +++ b/src/overlays/actors/ovl_En_Bom_Bowl_Man/z_en_bom_bowl_man.c @@ -1,7 +1,7 @@ /* - * File z_en_bom_bowl_man.c + * File: z_en_bom_bowl_man.c * Overlay: ovl_En_Bom_Bowl_Man - * Description: Line of Bombers? + * Description: Line of Bombers when they teach you the password */ #include "z_en_bom_bowl_man.h" diff --git a/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.c b/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.c index 3dabe557b..f02ab4ec6 100644 --- a/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.c +++ b/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.c @@ -1,5 +1,5 @@ /* - * File z_en_bom_chu.c + * File: z_en_bom_chu.c * Overlay: ovl_En_Bom_Chu * Description: Bombchus */ diff --git a/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h b/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h index 13172b180..910ad5174 100644 --- a/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h +++ b/src/overlays/actors/ovl_En_Bom_Chu/z_en_bom_chu.h @@ -10,7 +10,7 @@ typedef void (*EnBomChuActionFunc)(struct EnBomChu*, GlobalContext*); typedef struct EnBomChu { /* 0x0000 */ Actor actor; /* 0x0144 */ EnBomChuActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x98]; + /* 0x0148 */ char unk_148[0x98]; } EnBomChu; // size = 0x1E0 extern const ActorInit En_Bom_Chu_InitVars; diff --git a/src/overlays/actors/ovl_En_Bombal/z_en_bombal.c b/src/overlays/actors/ovl_En_Bombal/z_en_bombal.c index 134dc1042..09d0880c6 100644 --- a/src/overlays/actors/ovl_En_Bombal/z_en_bombal.c +++ b/src/overlays/actors/ovl_En_Bombal/z_en_bombal.c @@ -1,5 +1,5 @@ /* - * File z_en_bombal.c + * File: z_en_bombal.c * Overlay: ovl_En_Bombal * Description: Bombers - Majora Balloon */ diff --git a/src/overlays/actors/ovl_En_Bombal/z_en_bombal.h b/src/overlays/actors/ovl_En_Bombal/z_en_bombal.h index ea538d5ce..9ac9fafa0 100644 --- a/src/overlays/actors/ovl_En_Bombal/z_en_bombal.h +++ b/src/overlays/actors/ovl_En_Bombal/z_en_bombal.h @@ -10,7 +10,12 @@ typedef void (*EnBombalActionFunc)(struct EnBombal*, GlobalContext*); typedef struct EnBombal { /* 0x0000 */ Actor actor; /* 0x0144 */ EnBombalActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x28FC]; + /* 0x0148 */ char unk148[0x4]; + /* 0x014C */ s16 unk_14C; + /* 0x0150 */ f32 unk_150; + /* 0x0154 */ char unk154[0x150]; + /* 0x02A4 */ Vec3f unk_2A4; + /* 0x02B0 */ char unk2B0[0x2794]; } EnBombal; // size = 0x2A44 extern const ActorInit En_Bombal_InitVars; diff --git a/src/overlays/actors/ovl_En_Bombers/z_en_bombers.c b/src/overlays/actors/ovl_En_Bombers/z_en_bombers.c index 4bd648dea..2ef45e65d 100644 --- a/src/overlays/actors/ovl_En_Bombers/z_en_bombers.c +++ b/src/overlays/actors/ovl_En_Bombers/z_en_bombers.c @@ -1,5 +1,5 @@ /* - * File z_en_bombers.c + * File: z_en_bombers.c * Overlay: ovl_En_Bombers * Description: Bombers - Blue-Hatted Bomber */ diff --git a/src/overlays/actors/ovl_En_Bombers2/z_en_bombers2.c b/src/overlays/actors/ovl_En_Bombers2/z_en_bombers2.c index 478b117d7..18aa562e7 100644 --- a/src/overlays/actors/ovl_En_Bombers2/z_en_bombers2.c +++ b/src/overlays/actors/ovl_En_Bombers2/z_en_bombers2.c @@ -1,5 +1,5 @@ /* - * File z_en_bombers2.c + * File: z_en_bombers2.c * Overlay: ovl_En_Bombers2 * Description: Bombers - Hideout Guard */ diff --git a/src/overlays/actors/ovl_En_Bombf/z_en_bombf.c b/src/overlays/actors/ovl_En_Bombf/z_en_bombf.c index e40ff2efb..292469236 100644 --- a/src/overlays/actors/ovl_En_Bombf/z_en_bombf.c +++ b/src/overlays/actors/ovl_En_Bombf/z_en_bombf.c @@ -1,5 +1,5 @@ /* - * File z_en_bombf.c + * File: z_en_bombf.c * Overlay: ovl_En_Bombf * Description: Bomb flower */ diff --git a/src/overlays/actors/ovl_En_Bomjima/z_en_bomjima.c b/src/overlays/actors/ovl_En_Bomjima/z_en_bomjima.c index 0562e8dc4..d06c2a060 100644 --- a/src/overlays/actors/ovl_En_Bomjima/z_en_bomjima.c +++ b/src/overlays/actors/ovl_En_Bomjima/z_en_bomjima.c @@ -1,10 +1,12 @@ /* - * File z_en_bomjima.c + * File: z_en_bomjima.c * Overlay: ovl_En_Bomjima * Description: Bombers - Jim */ +#include "overlays/actors/ovl_En_Bombal/z_en_bombal.h" #include "z_en_bomjima.h" +#include "objects/object_cs/object_cs.h" #define FLAGS 0x00000019 @@ -16,8 +18,11 @@ void EnBomjima_Update(Actor* thisx, GlobalContext* globalCtx); void EnBomjima_Draw(Actor* thisx, GlobalContext* globalCtx); void func_80BFEA94(EnBomjima* this, GlobalContext* globalCtx); +void func_80BFEB1C(EnBomjima* this); void func_80BFEB64(EnBomjima* this, GlobalContext* globalCtx); +void func_80BFEFF0(EnBomjima* this); void func_80BFF03C(EnBomjima* this, GlobalContext* globalCtx); +void func_80BFF120(EnBomjima* this); void func_80BFF174(EnBomjima* this, GlobalContext* globalCtx); void func_80BFF430(EnBomjima* this, GlobalContext* globalCtx); void func_80BFF52C(EnBomjima* this, GlobalContext* globalCtx); @@ -26,13 +31,17 @@ void func_80BFF754(EnBomjima* this, GlobalContext* globalCtx); void func_80BFF9B0(EnBomjima* this, GlobalContext* globalCtx); void func_80BFFB40(EnBomjima* this, GlobalContext* globalCtx); void func_80BFFBC4(EnBomjima* this, GlobalContext* globalCtx); +void func_80BFFCFC(EnBomjima* this); void func_80BFFD48(EnBomjima* this, GlobalContext* globalCtx); void func_80BFFE48(EnBomjima* this, GlobalContext* globalCtx); void func_80BFFF54(EnBomjima* this, GlobalContext* globalCtx); void func_80C00168(EnBomjima* this, GlobalContext* globalCtx); +void func_80C00234(EnBomjima* this); void func_80C00284(EnBomjima* this, GlobalContext* globalCtx); -#if 0 +static s32 D_80C009F0 = 0; +static s32 D_80C009F4 = 0; + const ActorInit En_Bomjima_InitVars = { ACTOR_EN_BOMJIMA, ACTORCAT_NPC, @@ -45,83 +54,1075 @@ const ActorInit En_Bomjima_InitVars = { (ActorFunc)EnBomjima_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80C00A18 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 10, 30, 0, { 0, 0, 0 } }, }; +static u16 D_80C00A44[] = { + 0x0719, + 0x071A, + 0x071B, + 0x0708, +}; + +static u16 D_80C00A4C[] = { + 0x0739, + 0x073A, + 0x073B, + 0x0000, +}; + +static u16 D_80C00A54[] = { 0x0739, 0x073A, 0x073B, 0x0714, 0x0709, 0x070A, 0x070B, + 0x070C, 0x070D, 0x070E, 0x070F, 0x0712, 0x0713 }; + +static u16 D_80C00A70[] = { 0x0739, 0x073A, 0x073B, 0x0759, 0x0753, 0x0754, 0x0755, + 0x0756, 0x070D, 0x0757, 0x0758, 0x0712, 0x0713 }; + +static u16 D_80C00A8C[] = { + 0x0736, + 0x0737, + 0x0738, + 0x074E, +}; + +static AnimationHeader* sAnimations[] = { + &object_cs_Anim_0064B8, &object_cs_Anim_00FAF4, &object_cs_Anim_0057C8, &object_cs_Anim_0053F4, + &object_cs_Anim_002044, &object_cs_Anim_01007C, &object_cs_Anim_00349C, &object_cs_Anim_004960, + &object_cs_Anim_005128, &object_cs_Anim_004C1C, &object_cs_Anim_001A1C, &object_cs_Anim_003EE4, + &object_cs_Anim_00478C, &object_cs_Anim_00433C, &object_cs_Anim_0060E8, &object_cs_Anim_001708, + &object_cs_Anim_005DC4, &object_cs_Anim_0026B0, &object_cs_Anim_0036B0, &object_cs_Anim_0031C4, +}; + +static u8 D_80C00AE4[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, + 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, +}; + +void EnBomjima_Init(Actor* thisx, GlobalContext* globalCtx) { + EnBomjima* this = THIS; + s32 cs; + s32 i; + + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 19.0f); + this->actor.gravity = -3.0f; + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_cs_Skel_00F82C, &object_cs_Anim_0064B8, this->jointTable, + this->morphTable, 21); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + gSaveContext.weekEventReg[83] &= (u8)~0x4; + this->actor.targetMode = 0; + this->unk_2E6 = ENBOMJIMA_GET_F0(&this->actor); + this->unk_2E4 = ENBOMJIMA_GET_F(&this->actor); + Actor_SetScale(&this->actor, 0.01f); + + if (this->unk_2E6 == 0) { + cs = this->actor.cutscene; + i = 0; + + while (cs != -1) { + // clang-format off + this->unk_2D4[i] = cs; cs = ActorCutscene_GetAdditionalCutscene(cs); + // clang-format on + i++; + } + + this->actionFunc = func_80BFEA94; + } else if (this->unk_2E6 == 2) { + func_80BFFCFC(this); + } + + if ((gSaveContext.weekEventReg[75] & 0x40) || (gSaveContext.weekEventReg[73] & 0x10) || + (gSaveContext.weekEventReg[85] & 2)) { + Actor_MarkForDeath(&this->actor); + } +} + +void EnBomjima_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnBomjima* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void func_80BFE32C(EnBomjima* this, GlobalContext* globalCtx, s32 arg2) { + Player* player = GET_PLAYER(globalCtx); + + this->unk_2CA = arg2; + if (player->transformation == PLAYER_FORM_GORON) { + this->unk_2C8 = 1; + } + if (player->transformation == PLAYER_FORM_ZORA) { + this->unk_2C8 = 2; + } + + switch (this->unk_2CA) { + case 0: + if (player->transformation == PLAYER_FORM_DEKU) { + this->actor.textId = 0x759; + if (!(gSaveContext.weekEventReg[73] & 0x20)) { + this->actor.textId = 0x708; + } + } else if (player->transformation == PLAYER_FORM_HUMAN) { + this->actor.textId = 0x75A; + if (!(gSaveContext.weekEventReg[84] & 0x80)) { + this->actor.textId = 0x719; + } + } else if ((this->unk_2C8 == 1) || (this->unk_2C8 == 2)) { + this->actor.textId = D_80C00A44[this->unk_2C8]; + } + break; + + case 1: + this->actor.textId = D_80C00A4C[this->unk_2C8]; + break; + + case 2: + if (player->transformation == PLAYER_FORM_DEKU) { + this->actor.textId = D_80C00A54[this->unk_2C8]; + return; + } + this->actor.textId = D_80C00A70[this->unk_2C8]; + break; + + case 3: + this->actor.textId = D_80C00A8C[this->unk_2C8]; + break; + } +} + +void func_80BFE494(EnBomjima* this, s32 arg1, f32 arg2) { + this->unk_2EC = arg1; + this->unk_2CC = Animation_GetLastFrame(sAnimations[arg1]); + Animation_Change(&this->skelAnime, sAnimations[this->unk_2EC], arg2, 0.0f, this->unk_2CC, D_80C00AE4[this->unk_2EC], + -4.0f); +} + +void func_80BFE524(EnBomjima* this) { + if ((this->unk_2EC == 5) && + (Animation_OnFrame(&this->skelAnime, 9.0f) || Animation_OnFrame(&this->skelAnime, 10.0f) || + Animation_OnFrame(&this->skelAnime, 17.0f) || Animation_OnFrame(&this->skelAnime, 18.0f))) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_BOMBERS_WALK); + } + + if ((this->unk_2EC == 18) && + (Animation_OnFrame(&this->skelAnime, 0.0f) || Animation_OnFrame(&this->skelAnime, 2.0f) || + Animation_OnFrame(&this->skelAnime, 4.0f) || Animation_OnFrame(&this->skelAnime, 6.0f))) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_BOMBERS_WALK); + } + + if ((this->unk_2EC == 15) && Animation_OnFrame(&this->skelAnime, 15.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_BOMBERS_LAND); + } + + if ((this->unk_2EC == 6) && Animation_OnFrame(&this->skelAnime, 8.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_BOMBERS_LAND); + } +} + +void func_80BFE65C(EnBomjima* this) { + this->unk_2BC = 0; + this->unk_2C0 = 0; + this->unk_2BE = 0; + this->unk_2A2 = 0; + this->unk_290 = 0; + this->unk_29A = 0; +} + +void func_80BFE67C(EnBomjima* this, GlobalContext* globalCtx) { + f32 sp84 = this->skelAnime.curFrame; + f32 x; + f32 z; + s16 abs; + s16 abs2; + Vec3f sp6C; + Vec3f sp60; + Vec3f sp54; + CollisionPoly* sp50; + s32 sp4C; + + this->unk_2DC = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_2A4); + Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2DC, 1, 5000, 0); + + switch (this->unk_2A2) { + case 0: + if (this->unk_2C0 == 0) { + Math_Vec3f_Copy(&sp54, &this->actor.home.pos); + + sp54.x += randPlusMinusPoint5Scaled(150.0f); + sp54.z += randPlusMinusPoint5Scaled(150.0f); + + abs = ABS_ALT(BINANG_SUB(this->actor.world.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &sp54))); + if ((abs < 0x4000) && !BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.world.pos, &sp54, &sp6C, + &sp50, 1, 0, 0, 1, &sp4C)) { + func_80BFE494(this, 5, 1.0f); + Math_Vec3f_Copy(&this->unk_2A4, &sp54); + this->unk_2BE = Rand_S16Offset(30, 50); + this->unk_2A2++; + } + } + break; + + case 1: + if (sp84 >= 0.0f) { + this->unk_2DC = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_2A4); + Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2DC, 10, 2000, 20); + } + + abs2 = BINANG_SUB(this->actor.world.rot.y, this->unk_2DC); + if ((s16)ABS_ALT(abs2) < 0x100) { + Math_Vec3f_Copy(&sp60, &this->actor.world.pos); + + sp60.x += Math_SinS(this->actor.world.rot.y) * 60.0f; + sp60.z += Math_CosS(this->actor.world.rot.y) * 60.0f; + + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.world.pos, &sp60, &sp6C, &sp50, 1, 0, 0, 1, + &sp4C)) { + this->unk_2C0 = 0; + if (Rand_ZeroOne() < 0.5f) { + func_80BFE494(this, 19, 1.0f); + } else { + func_80BFE494(this, 0, 1.0f); + } + this->unk_2A2 = 0; + this->unk_2D0 = 0.0f; + break; + } + } + + x = this->unk_2A4.x - this->actor.world.pos.x; + z = this->unk_2A4.z - this->actor.world.pos.z; + + if ((this->unk_2BE == 0) || (sqrtf(SQ(x) + SQ(z)) < 4.0f)) { + this->unk_2C0 = Rand_S16Offset(20, 20); + if (!(this->unk_2C0 & 1)) { + func_80BFE494(this, 19, 1.0f); + } else { + func_80BFE494(this, 0, 1.0f); + } + this->unk_2A2 = 0; + this->unk_2D0 = 0.0f; + } else if (sp84 >= 0.0f) { + Math_ApproachF(&this->actor.world.pos.x, this->unk_2A4.x, 0.3f, this->unk_2D0); + Math_ApproachF(&this->actor.world.pos.z, this->unk_2A4.z, 0.3f, this->unk_2D0); + Math_ApproachF(&this->unk_2D0, 1.0f, 0.3f, 0.5f); + } + break; + } +} + +void func_80BFEA94(EnBomjima* this, GlobalContext* globalCtx) { + Actor* actor = globalCtx->actorCtx.actorList[ACTORCAT_PROP].first; + + while (actor != NULL) { + if (actor->id != ACTOR_EN_BOMBAL) { + actor = actor->next; + continue; + } + + this->unk_2F0 = (EnBombal*)actor; + Math_Vec3f_Copy(&this->unk_2B0, &actor->world.pos); + if (this->unk_2F4 == 0) { + this->unk_2F4 = this->unk_2F0->actor.cutscene; + } + func_80BFEB1C(this); + break; + } +} + +void func_80BFEB1C(EnBomjima* this) { + func_80BFE494(this, 1, 1.0f); + func_80BFE65C(this); + this->unk_2A0 = 0; + this->actionFunc = func_80BFEB64; +} + +void func_80BFEB64(EnBomjima* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 pad[2]; + Vec3f sp40; + + func_80BFE32C(this, globalCtx, 0); + if (player->transformation == PLAYER_FORM_DEKU) { + if (gSaveContext.weekEventReg[73] & 0x20) { + this->unk_2C8 = 3; + func_80BFE32C(this, globalCtx, 3); + } else if (gSaveContext.weekEventReg[77] & 2) { + this->unk_2C8 = 11; + func_80BFE32C(this, globalCtx, 2); + } + } else if (player->transformation == PLAYER_FORM_HUMAN) { + if (gSaveContext.weekEventReg[84] & 0x80) { + this->unk_2C8 = 0; + func_80BFE32C(this, globalCtx, 3); + } else if (gSaveContext.weekEventReg[85] & 1) { + this->unk_2C8 = 11; + func_80BFE32C(this, globalCtx, 2); + } + } + + if (Text_GetFaceReaction(globalCtx, 0x11) != 0) { + this->actor.textId = Text_GetFaceReaction(globalCtx, 0x11); + } + + if (func_800B84D0(&this->actor, globalCtx)) { + this->unk_2DC = this->actor.yawTowardsPlayer; + func_80C00234(this); + return; + } + + if (ActorCutscene_GetCurrentIndex() == -1) { + func_800B8614(&this->actor, globalCtx, 70.0f); + } + + if ((this->unk_2F0->actor.update == NULL) || (this->unk_2F0->actor.colChkInfo.health == 0)) { + func_80BFEFF0(this); + return; + } + + switch (this->unk_2A2) { + case 0: + func_80BFE494(this, 4, 1.0f); + this->unk_29A = -7000; + this->unk_2A2++; + break; + + case 1: + this->unk_2DC = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_2F0->actor.world.pos); + if (Animation_OnFrame(&this->skelAnime, 19.0f)) { + this->unk_2C0 = 5; + Audio_PlayActorSound2(&this->actor, NA_SE_EV_BOMBERS_SHOT_BREATH); + } + + if (this->unk_2C0 == 1) { + s16 sp3E = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_2F0->actor.world.pos); + + if (Rand_ZeroOne() < 0.5f) { + sp3E += 0x4000; + } else { + sp3E += 0xC000; + } + + sp40.x = (Math_SinS(sp3E) * (Rand_ZeroFloat(20.0f) + 40.0f)) + this->unk_2F0->actor.world.pos.x; + sp40.y = this->unk_2F0->actor.world.pos.y - randPlusMinusPoint5Scaled(40.0f); + sp40.z = (Math_CosS(sp3E) * (Rand_ZeroFloat(20.0f) + 40.0f)) + this->unk_2F0->actor.world.pos.z; + + Audio_PlaySoundAtPosition(globalCtx, &sp40, 50, NA_SE_EV_BOMBERS_SHOT_EXPLOSUIN); + EffectSsHitMark_SpawnFixedScale(globalCtx, 0, &sp40); + this->unk_2BC++; + + if (((s16)Rand_ZeroFloat(2.0f) + 3) < this->unk_2BC) { + func_80BFE494(this, 5, 1.0f); + this->unk_29A = 0; + Math_Vec3f_Copy(&this->unk_2A4, &this->actor.home.pos); + this->unk_2A4.x += randPlusMinusPoint5Scaled(150.0f); + this->unk_2A4.z += randPlusMinusPoint5Scaled(150.0f); + this->unk_2A2++; + } + } + break; + + case 2: + this->unk_2DC = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_2A4); + Math_ApproachF(&this->actor.world.pos.x, this->unk_2A4.x, 0.3f, 2.0f); + Math_ApproachF(&this->actor.world.pos.z, this->unk_2A4.z, 0.3f, 2.0f); + if (sqrtf(SQ(this->actor.world.pos.x - this->unk_2A4.x) + SQ(this->actor.world.pos.z - this->unk_2A4.z)) < + 4.0f) { + func_80BFE65C(this); + } + break; + } + + Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2DC, 1, 5000, 0); +} + +void func_80BFEFF0(EnBomjima* this) { + this->unk_2F0 = NULL; + func_80BFE494(this, 19, 1.0f); + func_80BFE65C(this); + this->unk_2A0 = 1; + this->actionFunc = func_80BFF03C; +} + +void func_80BFF03C(EnBomjima* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->unk_2D4[0]); + } else if (!ActorCutscene_GetCanPlayNext(this->unk_2D4[0])) { + ActorCutscene_SetIntentToPlay(this->unk_2D4[0]); + } else { + player->stateFlags1 &= ~0x20; + gSaveContext.weekEventReg[83] &= (u8)~4; + this->actor.world.rot.y = func_800DFCDC(GET_ACTIVE_CAM(globalCtx)); + this->unk_2DC = func_800DFCDC(GET_ACTIVE_CAM(globalCtx)); + ActorCutscene_StartAndSetUnkLinkFields(this->unk_2D4[0], &this->actor); + func_80BFF120(this); + } +} + +void func_80BFF120(EnBomjima* this) { + func_80BFE65C(this); + this->unk_2C4 = 30; + func_80BFE494(this, 6, 1.0f); + this->unk_2DE = 0; + this->unk_2A0 = 2; + this->actionFunc = func_80BFF174; +} + +void func_80BFF174(EnBomjima* this, GlobalContext* globalCtx) { + f32 sp2C = this->skelAnime.curFrame; + Player* player = GET_PLAYER(globalCtx); + + if (this->unk_2C4 == 1) { + ActorCutscene_Stop(this->unk_2D4[0]); + this->unk_2DE = 1; + } + + if (Text_GetFaceReaction(globalCtx, 0x11) != 0) { + this->actor.textId = Text_GetFaceReaction(globalCtx, 0x11); + } + + if (func_800B84D0(&this->actor, globalCtx)) { + this->unk_2DC = this->actor.yawTowardsPlayer; + func_80C00234(this); + return; + } + + Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2DC, 1, 5000, 0); + + if ((this->unk_2CC <= sp2C) && (this->unk_2BC < 5)) { + this->unk_2BC++; + if (this->unk_2EC != 19) { + func_80BFE494(this, 19, 1.0f); + } + } + + if (player->transformation == PLAYER_FORM_DEKU) { + if (gSaveContext.weekEventReg[73] & 0x20) { + this->unk_2C8 = 3; + func_80BFE32C(this, globalCtx, 3); + } else { + if (!(gSaveContext.weekEventReg[77] & 2)) { + if (this->unk_2E8 == 0) { + this->unk_2C8 = 4; + } else { + this->unk_2C8 = 3; + } + } else { + this->unk_2C8 = 11; + } + func_80BFE32C(this, globalCtx, 2); + } + } else if (player->transformation == PLAYER_FORM_HUMAN) { + if (gSaveContext.weekEventReg[84] & 0x80) { + this->unk_2C8 = 0; + func_80BFE32C(this, globalCtx, 3); + } else { + if (!(gSaveContext.weekEventReg[85] & 1)) { + if (this->unk_2EA == 0) { + this->unk_2C8 = 4; + } else { + this->unk_2C8 = 3; + } + } else { + this->unk_2C8 = 11; + } + func_80BFE32C(this, globalCtx, 2); + } + } else if (this->unk_2CA != 1) { + func_80BFE32C(this, globalCtx, 1); + } + + if (this->unk_2DE != 0) { + if (this->unk_2BC >= 5) { + func_80BFE67C(this, globalCtx); + } + func_800B8614(&this->actor, globalCtx, 70.0f); + } +} + +void func_80BFF3F0(EnBomjima* this) { + func_80BFE494(this, 15, 1.0f); + this->unk_2A0 = 3; + this->actionFunc = func_80BFF430; +} + +void func_80BFF430(EnBomjima* this, GlobalContext* globalCtx) { + f32 curFrame = this->skelAnime.curFrame; + + if (this->unk_2CC <= curFrame) { + EnBombal* bombal = (EnBombal*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_BOMBAL, this->unk_2B0.x, + this->unk_2B0.y, this->unk_2B0.z, 0, 0, 0, 0); + + if (bombal != NULL) { + bombal->unk_150 = 0.0f; + bombal->unk_14C = this->unk_2F4; + func_800B86C8(&this->actor, globalCtx, &bombal->actor); + gSaveContext.weekEventReg[83] &= (u8)~4; + func_80BFE65C(this); + func_801477B4(globalCtx); + this->actionFunc = func_80BFEA94; + } + } +} + +void func_80BFF4F4(EnBomjima* this) { + func_80BFE65C(this); + this->unk_2A0 = 4; + this->actionFunc = func_80BFF52C; +} + +void func_80BFF52C(EnBomjima* this, GlobalContext* globalCtx) { + if ((func_80152498(&globalCtx->msgCtx) == 4) && func_80147624(globalCtx)) { + func_801477B4(globalCtx); + if (globalCtx->msgCtx.choiceIndex == 0) { + Player* player = GET_PLAYER(globalCtx); + + func_8019F208(); + func_80BFE65C(this); + this->unk_28E = 0; + this->unk_29A = 0; + this->unk_2C8 = 8; + if (player->transformation == PLAYER_FORM_DEKU) { + this->actor.textId = D_80C00A54[this->unk_2C8]; + } else { + this->actor.textId = D_80C00A70[this->unk_2C8]; + } + func_80151938(globalCtx, this->actor.textId); + play_sound(NA_SE_SY_FOUND); + func_80BFE494(this, 15, 1.0f); + this->unk_2A0 = 5; + this->actionFunc = func_80BFF6CC; + } else { + Player* player = GET_PLAYER(globalCtx); + + func_8019F230(); + func_80BFE65C(this); + this->unk_2C8 = 10; + if (player->transformation == PLAYER_FORM_DEKU) { + this->actor.textId = D_80C00A54[this->unk_2C8]; + this->unk_2E8 = 1; + } else { + this->actor.textId = D_80C00A70[this->unk_2C8]; + this->unk_2EA = 1; + } + func_80151938(globalCtx, this->actor.textId); + func_80C00234(this); + } + } +} + +void func_80BFF6CC(EnBomjima* this, GlobalContext* globalCtx) { + f32 curFrame = this->skelAnime.curFrame; + + if (this->unk_2CC <= curFrame) { + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + func_801477B4(globalCtx); + func_80BFE494(this, 1, 1.0f); + this->actionFunc = func_80BFF754; + } + } +} + +#ifdef NON_EQUIVALENT +// Data indexing is wrong + +typedef struct { + /* 0x00 */ s16 unk_00; + /* 0x02 */ s16 unk_02; +} EnBombjimaStruct; + +void func_80BFF754(EnBomjima* this, GlobalContext* globalCtx) { + static EnBombjimaStruct D_80C00AF8[] = { + { 0x4000, 0x003C }, + { 0x4000, 0x001E }, + { 0xC000, 0x001E }, + { 0xC000, 0x003C }, + }; + Player* player = GET_PLAYER(globalCtx); + Vec3f spA0; + EnBombal* temp_s3; + s32 i; + f32 x; + f32 y; + f32 z; + + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->unk_2D4[1]); + return; + } + + if (!ActorCutscene_GetCanPlayNext(this->unk_2D4[1])) { + ActorCutscene_SetIntentToPlay(this->unk_2D4[1]); + return; + } + + for (i = 1; i < 5; i++) { + Math_Vec3f_Copy(&spA0, &player->actor.world.pos); + + x = spA0.x - this->actor.world.pos.x; + y = spA0.y - this->actor.world.pos.y; + z = spA0.z - this->actor.world.pos.z; + + spA0.x += x * (2.0f + (i * 0.2f)); + spA0.y += y * (2.0f + (i * 0.2f)); + spA0.z += z * (2.0f + (i * 0.2f)); + + temp_s3 = (EnBombal*)Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_BOMJIMA, spA0.x, + spA0.y, spA0.z, 0, 0, 0, i + 32); + if (temp_s3 != NULL) { + s32 idx1 = (i * 2) - 1; + s32 idx2 = i * 2; + + Math_Vec3f_Copy(&spA0, &this->actor.world.pos); + + spA0.x += Math_SinS(D_80C00AF8[idx1 - 1].unk_00 + this->actor.world.rot.y) * D_80C00AF8[idx2].unk_02; + spA0.z += Math_CosS(D_80C00AF8[idx2].unk_00 + this->actor.world.rot.y) * D_80C00AF8[idx2].unk_02; + + Math_Vec3f_Copy(&temp_s3->unk_2A4, &spA0); + } + } + + D_80C009F0 = 0; + ActorCutscene_StartAndSetUnkLinkFields(this->unk_2D4[1], &this->actor); + this->actionFunc = func_80BFF9B0; +} +#else +static s16 D_80C00AF8[][2] = { + { 0x4000, 0x003C }, + { 0x4000, 0x001E }, + { 0xC000, 0x001E }, + { 0xC000, 0x003C }, +}; +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF754.s") #endif -extern ColliderCylinderInit D_80C00A18; +void func_80BFF9B0(EnBomjima* this, GlobalContext* globalCtx) { + if (D_80C009F0 >= 4) { + Player* player = GET_PLAYER(globalCtx); -extern UNK_TYPE D_060064B8; + D_80C009F0 = 0; + this->unk_2C8 = 9; + if (player->transformation == PLAYER_FORM_DEKU) { + gSaveContext.weekEventReg[73] |= 0x10; + gSaveContext.weekEventReg[77] |= 2; + } else { + gSaveContext.weekEventReg[85] |= 2; + gSaveContext.weekEventReg[85] |= 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/EnBomjima_Init.s") + gSaveContext.weekEventReg[11] &= (u8)~1; + gSaveContext.weekEventReg[11] &= (u8)~2; + gSaveContext.weekEventReg[11] &= (u8)~4; + gSaveContext.weekEventReg[11] &= (u8)~8; + gSaveContext.weekEventReg[11] &= (u8)~0x10; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/EnBomjima_Destroy.s") + gSaveContext.weekEventReg[76] &= (u8)~1; + gSaveContext.weekEventReg[76] &= (u8)~2; + gSaveContext.weekEventReg[76] &= (u8)~4; + gSaveContext.weekEventReg[76] &= (u8)~8; + gSaveContext.weekEventReg[76] &= (u8)~0x10; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFE32C.s") + gSaveContext.unk_FE6 = 0; + gSaveContext.unk_FE7[0] = 0; + gSaveContext.unk_FE7[1] = 0; + gSaveContext.unk_FE7[2] = 0; + gSaveContext.unk_FE7[3] = 0; + gSaveContext.unk_FE7[4] = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFE494.s") + func_80BFE494(this, 3, 1.0f); + this->unk_2C8 = 9; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFE524.s") + if (player->transformation == PLAYER_FORM_DEKU) { + this->actor.textId = D_80C00A54[this->unk_2C8]; + } else { + this->actor.textId = D_80C00A70[this->unk_2C8]; + } + func_80151938(globalCtx, this->actor.textId); + this->actionFunc = func_80BFFB40; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFE65C.s") +void func_80BFFB40(EnBomjima* this, GlobalContext* globalCtx) { + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + func_801477B4(globalCtx); + func_80BFE494(this, 15, 1.0f); + D_80C009F0 = 100; + this->unk_2DC = 0; + this->actionFunc = func_80BFFBC4; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFE67C.s") +void func_80BFFBC4(EnBomjima* this, GlobalContext* globalCtx) { + f32 curFrame = this->skelAnime.curFrame; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFEA94.s") + if ((this->unk_2EC != 1) && (this->unk_2CC <= curFrame)) { + func_80BFE494(this, 1, 1.0f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFEB1C.s") + if ((D_80C009F4 != 0) && (this->unk_2C2 == 0)) { + this->unk_2C2 = Rand_S16Offset(5, 5); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFEB64.s") + if (this->unk_2C2 == 1) { + this->unk_2DC = -10000; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFEFF0.s") + Math_SmoothStepToS(&this->unk_290, this->unk_2DC, 1, 5000, 0); + if (D_80C009F0 >= 104) { + D_80C009F0 = 0; + func_801477B4(globalCtx); + globalCtx->nextEntranceIndex = Entrance_CreateIndexFromSpawn(6); + gSaveContext.nextCutsceneIndex = 0; + globalCtx->sceneLoadFlag = 20; + globalCtx->unk_1887F = 0x56; + gSaveContext.nextTransition = 3; + ActorCutscene_Stop(this->unk_2D4[1]); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF03C.s") +void func_80BFFCFC(EnBomjima* this) { + func_80BFE65C(this); + func_80BFE494(this, 18, 1.0f); + this->unk_2A0 = 6; + this->actionFunc = func_80BFFD48; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF120.s") +void func_80BFFD48(EnBomjima* this, GlobalContext* globalCtx) { + s32 pad[2]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF174.s") + this->unk_2DC = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_2A4); + Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2DC, 1, 5000, 0); + Math_ApproachF(&this->actor.world.pos.x, this->unk_2A4.x, 0.3f, 4.0f); + Math_ApproachF(&this->actor.world.pos.z, this->unk_2A4.z, 0.3f, 4.0f); + if (sqrtf(SQ(this->actor.world.pos.x - this->unk_2A4.x) + SQ(this->actor.world.pos.z - this->unk_2A4.z)) < 4.0f) { + D_80C009F0++; + this->unk_2DC = this->actor.parent->world.rot.y; + func_80BFE494(this, 0, 1.0f); + this->actionFunc = func_80BFFE48; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF3F0.s") +void func_80BFFE48(EnBomjima* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2DC, 1, 5000, 0); + Math_ApproachF(&this->actor.world.pos.x, this->unk_2A4.x, 0.3f, 4.0f); + Math_ApproachF(&this->actor.world.pos.z, this->unk_2A4.z, 0.3f, 4.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF430.s") + if (D_80C009F0 >= 100) { + if (this->unk_2E4 != 4) { + func_80BFE494(this, 15, 1.0f); + this->unk_2DC = 0; + func_80BFE65C(this); + this->actionFunc = func_80BFFF54; + } else { + Math_SmoothStepToS(&this->unk_290, 10000, 1, 5000, 0); + if (D_80C009F0 >= 103) { + this->unk_2DC = 0; + func_80BFE494(this, 15, 1.0f); + func_80BFE65C(this); + this->actionFunc = func_80BFFF54; + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF4F4.s") +void func_80BFFF54(EnBomjima* this, GlobalContext* globalCtx) { + f32 curFrame = this->skelAnime.curFrame; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF52C.s") + Math_SmoothStepToS(&this->unk_290, this->unk_2DC, 1, 5000, 0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF6CC.s") + if ((D_80C009F4 != 0) && (this->unk_2C2 == 0)) { + this->unk_2C2 = Rand_S16Offset(5, 5); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF754.s") + if (this->unk_2C2 == 1) { + this->unk_2DC = -10000; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFF9B0.s") + if (this->unk_2E4 != 4) { + if ((this->unk_2EC != 0) && (this->unk_2CC <= curFrame)) { + D_80C009F0++; + func_80BFE494(this, 0, 1.0f); + } + } else if ((this->unk_2EC != 8) && (this->unk_2CC <= curFrame)) { + func_80BFE494(this, 8, 1.0f); + D_80C009F4 = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFFB40.s") + if (this->unk_2EC == 8) { + if ((D_80C009F4 == 1) && Animation_OnFrame(&this->skelAnime, 7.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_HUMAN_BOUND); + D_80C009F4 = 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFFBC4.s") + if ((this->unk_2CC <= curFrame) && (this->unk_2C0 == 0)) { + this->unk_2C0 = 10; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFFCFC.s") + if (this->unk_2C0 == 1) { + D_80C009F0++; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFFD48.s") +void func_80C0011C(EnBomjima* this) { + func_80BFE65C(this); + func_80BFE494(this, 0, 1.0f); + this->unk_2A0 = 7; + this->actionFunc = func_80C00168; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFFE48.s") +void func_80C00168(EnBomjima* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80BFFF54.s") + if (player->transformation == PLAYER_FORM_HUMAN) { + this->unk_2C8 = 4; + } else if (player->transformation == PLAYER_FORM_DEKU) { + this->unk_2C8 = 7; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80C0011C.s") + func_80BFE32C(this, globalCtx, 0); + func_80BFE67C(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80C00168.s") + if (Text_GetFaceReaction(globalCtx, 0x11) != 0) { + this->actor.textId = Text_GetFaceReaction(globalCtx, 0x11); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80C00234.s") + if (func_800B84D0(&this->actor, globalCtx)) { + this->unk_2DC = this->actor.yawTowardsPlayer; + func_80C00234(this); + } else { + func_800B8614(&this->actor, globalCtx, 70.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80C00284.s") +void func_80C00234(EnBomjima* this) { + func_80BFE494(this, 3, 1.0f); + this->collider.dim.radius = 15; + this->collider.dim.height = 40; + func_80BFE65C(this); + this->actionFunc = func_80C00284; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/EnBomjima_Update.s") +void func_80C00284(EnBomjima* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 sp28 = this->skelAnime.curFrame; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/func_80C007F4.s") + Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2DC, 1, 5000, 0); + if (((this->unk_2A0 == 0) || (this->unk_2C8 == 10) || (this->unk_2C8 == 11) || (this->unk_2CA == 1)) && + (this->unk_2CC <= sp28)) { + if (!(this->unk_2BC & 1)) { + func_80BFE494(this, 3, 1.0f); + } else { + func_80BFE494(this, 16, 1.0f); + } + this->unk_2BC++; + this->unk_2BC &= 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjima/EnBomjima_Draw.s") + if ((player->transformation != PLAYER_FORM_GORON) && (player->transformation != PLAYER_FORM_ZORA)) { + if (player->transformation == PLAYER_FORM_HUMAN) { + this->unk_28E = -4000; + } + } else { + this->unk_28E = -6000; + } + + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + this->collider.dim.radius = 10; + this->collider.dim.height = 30; + if ((this->unk_2A0 == 4) || (this->unk_2CA == 1) || ((this->unk_2CA == 3) && (this->unk_2C8 >= 2))) { + this->unk_28E = 0; + if (player->stateFlags1 & 0x20) { + player->stateFlags1 &= ~0x20; + } + + if ((this->unk_2F0 == 0) || (this->unk_2F0->actor.update == NULL) || + (this->unk_2F0->actor.colChkInfo.health <= 0)) { + func_80BFF3F0(this); + } else { + func_80BFE65C(this); + func_801477B4(globalCtx); + this->actionFunc = func_80BFEA94; + } + return; + } + + func_801477B4(globalCtx); + + switch (this->unk_2CA) { + case 0: + this->unk_28E = 0; + if (this->unk_2A0 == 7) { + func_80C0011C(this); + } else { + func_80BFEB1C(this); + } + break; + + case 2: + if (this->unk_2C8 == 10) { + func_80BFE65C(this); + this->unk_28E = 0; + func_80BFE494(this, 1, 1.0f); + this->unk_2A0 = 2; + this->actionFunc = func_80BFF174; + return; + } + + this->unk_2C8++; + if (player->transformation == PLAYER_FORM_DEKU) { + if ((this->unk_2E8 != 0) && (this->unk_2C8 == 4)) { + this->unk_2C8 = 6; + } + this->actor.textId = D_80C00A54[this->unk_2C8]; + } else { + if ((this->unk_2EA != 0) && (this->unk_2C8 == 4)) { + this->unk_2C8 = 6; + } + this->actor.textId = D_80C00A70[this->unk_2C8]; + } + func_80151938(globalCtx, this->actor.textId); + if ((this->unk_2C8 == 7) || (this->unk_2C8 == 12)) { + func_80BFF4F4(this); + } + break; + + case 3: + this->unk_2C8++; + this->actor.textId = D_80C00A8C[this->unk_2C8]; + func_80151938(globalCtx, this->actor.textId); + if (this->unk_2C8 >= 2) { + func_80BFE494(this, 17, 1.0f); + } + break; + } + } +} + +void EnBomjima_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnBomjima* this = THIS; + + if (this->unk_2BE != 0) { + this->unk_2BE--; + } + + if (this->unk_2C2 != 0) { + this->unk_2C2--; + } + + if (this->unk_2C0 != 0) { + this->unk_2C0--; + } + + if (this->unk_2C6 != 0) { + this->unk_2C6--; + } + + if (this->unk_2C4 != 0) { + this->unk_2C4--; + } + + SkelAnime_Update(&this->skelAnime); + this->actor.shape.rot.y = this->actor.world.rot.y; + func_80BFE524(this); + Actor_SetHeight(&this->actor, 20.0f); + this->actionFunc(this, globalCtx); + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Math_SmoothStepToS(&this->unk_28A, this->unk_290, 1, 5000, 0); + Math_SmoothStepToS(&this->unk_288, this->unk_28E, 1, 1000, 0); + Math_SmoothStepToS(&this->unk_294, this->unk_29A, 1, 1000, 0); + + if (this->unk_2E2 == 0) { + this->unk_2E0++; + if (this->unk_2E0 >= 3) { + this->unk_2E0 = 0; + this->unk_2E2 = (s16)Rand_ZeroFloat(60.0f) + 20; + } + } + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 50.0f, 0x1D); + this->actor.uncullZoneForward = 500.0f; + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +s32 EnBomjima_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnBomjima* this = THIS; + + if (limbIndex == 8) { + rot->z += this->unk_294; + } + + if ((limbIndex == 15) && (this->unk_2E6 == 2)) { + *dList = NULL; + } + + if (limbIndex == 17) { + rot->x += this->unk_28A; + rot->z += this->unk_288; + } + + if ((limbIndex == 19) && (this->unk_2E6 == 2)) { + *dList = NULL; + } + + if ((limbIndex == 20) && (this->unk_2E6 == 0)) { + *dList = NULL; + } + + return false; +} + +#include "overlays/ovl_En_Bomjima/ovl_En_Bomjima.c" + +void EnBomjima_Draw(Actor* thisx, GlobalContext* globalCtx) { + static Gfx* D_80C00B28[] = { + gEnBomjima_D_80C00B08, gEnBomjima_D_80C00B18, gEnBomjima_D_80C00B18, + gEnBomjima_D_80C00B18, gEnBomjima_D_80C00B18, + }; + static TexturePtr D_80C00B3C[] = { + &object_cs_Tex_00C520, + &object_cs_Tex_00CD20, + &object_cs_Tex_00D520, + }; + static TexturePtr D_80C00B48[] = { + &object_cs_Tex_00E620, &object_cs_Tex_00EA20, &object_cs_Tex_00EE20, + &object_cs_Tex_00DD20, &object_cs_Tex_00F220, + }; + EnBomjima* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80C00B3C[this->unk_2E0])); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80C00B48[this->unk_2E4])); + gSPSegment(POLY_OPA_DISP++, 0x0A, Lib_SegmentedToVirtual(D_80C00B28[this->unk_2E4])); + + Scene_SetRenderModeXlu(globalCtx, 0, 1); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnBomjima_OverrideLimbDraw, NULL, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Bomjima/z_en_bomjima.h b/src/overlays/actors/ovl_En_Bomjima/z_en_bomjima.h index b24725d21..c01e70bd5 100644 --- a/src/overlays/actors/ovl_En_Bomjima/z_en_bomjima.h +++ b/src/overlays/actors/ovl_En_Bomjima/z_en_bomjima.h @@ -7,11 +7,53 @@ struct EnBomjima; typedef void (*EnBomjimaActionFunc)(struct EnBomjima*, GlobalContext*); +#define ENBOMJIMA_GET_F0(thisx) (((thisx)->params >> 4) & 0xF) +#define ENBOMJIMA_GET_F(thisx) ((thisx)->params & 0xF) + typedef struct EnBomjima { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x140]; - /* 0x0284 */ EnBomjimaActionFunc actionFunc; - /* 0x0288 */ char unk_288[0xBC]; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[21]; + /* 0x206 */ Vec3s morphTable[21]; + /* 0x284 */ EnBomjimaActionFunc actionFunc; + /* 0x288 */ s16 unk_288; + /* 0x28A */ s16 unk_28A; + /* 0x28C */ UNK_TYPE1 unk28C[2]; + /* 0x28E */ s16 unk_28E; + /* 0x290 */ s16 unk_290; + /* 0x292 */ UNK_TYPE1 unk292[2]; + /* 0x294 */ s16 unk_294; + /* 0x296 */ UNK_TYPE1 unk296[4]; + /* 0x29A */ s16 unk_29A; + /* 0x29C */ UNK_TYPE1 unk29C[4]; + /* 0x2A0 */ s16 unk_2A0; + /* 0x2A2 */ s16 unk_2A2; + /* 0x2A4 */ Vec3f unk_2A4; + /* 0x2B0 */ Vec3f unk_2B0; + /* 0x2BC */ s16 unk_2BC; + /* 0x2BE */ s16 unk_2BE; + /* 0x2C0 */ s16 unk_2C0; + /* 0x2C2 */ s16 unk_2C2; + /* 0x2C4 */ s16 unk_2C4; + /* 0x2C6 */ s16 unk_2C6; + /* 0x2C8 */ s16 unk_2C8; + /* 0x2CA */ s16 unk_2CA; + /* 0x2CC */ f32 unk_2CC; + /* 0x2D0 */ f32 unk_2D0; + /* 0x2D4 */ s16 unk_2D4[2]; + /* 0x2D8 */ UNK_TYPE1 unk2D8[4]; // maybe a part of the above? + /* 0x2DC */ s16 unk_2DC; + /* 0x2DE */ s16 unk_2DE; + /* 0x2E0 */ s16 unk_2E0; + /* 0x2E2 */ s16 unk_2E2; + /* 0x2E4 */ s16 unk_2E4; + /* 0x2E6 */ s16 unk_2E6; + /* 0x2E8 */ s16 unk_2E8; + /* 0x2EA */ s16 unk_2EA; + /* 0x2EC */ s32 unk_2EC; + /* 0x2F0 */ EnBombal* unk_2F0; + /* 0x2F4 */ s16 unk_2F4; + /* 0x2F8 */ ColliderCylinder collider; } EnBomjima; // size = 0x344 extern const ActorInit En_Bomjima_InitVars; diff --git a/src/overlays/actors/ovl_En_Bomjimb/z_en_bomjimb.c b/src/overlays/actors/ovl_En_Bomjimb/z_en_bomjimb.c index f8c22c44f..229803174 100644 --- a/src/overlays/actors/ovl_En_Bomjimb/z_en_bomjimb.c +++ b/src/overlays/actors/ovl_En_Bomjimb/z_en_bomjimb.c @@ -1,10 +1,12 @@ /* - * File z_en_bomjimb.c + * File: z_en_bomjimb.c * Overlay: ovl_En_Bomjimb - * Description: Bomber Jim B + * Description: Bombers when chasing them */ #include "z_en_bomjimb.h" +#include "overlays/actors/ovl_En_Niw/z_en_niw.h" +#include "objects/object_cs/object_cs.h" #define FLAGS 0x00000009 @@ -15,19 +17,29 @@ void EnBomjimb_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnBomjimb_Update(Actor* thisx, GlobalContext* globalCtx); void EnBomjimb_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80C01494(EnBomjimb* this); void func_80C014E4(EnBomjimb* this, GlobalContext* globalCtx); +void func_80C01984(EnBomjimb* this, GlobalContext* globalCtx); void func_80C01A24(EnBomjimb* this, GlobalContext* globalCtx); +void func_80C01B40(EnBomjimb* this); void func_80C01B74(EnBomjimb* this, GlobalContext* globalCtx); +void func_80C01C18(EnBomjimb* this, GlobalContext* globalCtx); void func_80C01CD0(EnBomjimb* this, GlobalContext* globalCtx); void func_80C0201C(EnBomjimb* this, GlobalContext* globalCtx); +void func_80C02108(EnBomjimb* this); void func_80C0217C(EnBomjimb* this, GlobalContext* globalCtx); +void func_80C0250C(EnBomjimb* this); void func_80C02570(EnBomjimb* this, GlobalContext* globalCtx); +void func_80C0267C(EnBomjimb* this); void func_80C02704(EnBomjimb* this, GlobalContext* globalCtx); +void func_80C02740(EnBomjimb* this, GlobalContext* globalCtx); void func_80C02A14(EnBomjimb* this, GlobalContext* globalCtx); void func_80C02BCC(EnBomjimb* this, GlobalContext* globalCtx); +void func_80C02CA4(EnBomjimb* this, GlobalContext* globalCtx); void func_80C02DAC(EnBomjimb* this, GlobalContext* globalCtx); -#if 0 +static Actor* D_80C03170 = NULL; + const ActorInit En_Bomjimb_InitVars = { ACTOR_EN_BOMJIMB, ACTORCAT_NPC, @@ -40,79 +52,873 @@ const ActorInit En_Bomjimb_InitVars = { (ActorFunc)EnBomjimb_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80C03194 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 20, 30, 0, { 0, 0, 0 } }, }; -#endif +void EnBomjimb_Init(Actor* thisx, GlobalContext* globalCtx) { + EnBomjimb* this = THIS; -extern ColliderCylinderInit D_80C03194; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 19.0f); + this->actor.gravity = -2.0f; + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_cs_Skel_00F82C, &object_cs_Anim_0064B8, this->jointTable, + this->morphTable, 21); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + this->actor.targetMode = 6; + Actor_SetScale(&this->actor, 0.01f); -extern UNK_TYPE D_060064B8; + this->unk_2C6 = ENBOMJIMB_GET_F0(&this->actor); + this->unk_2B2 = ENBOMJIMB_GET_FF00(&this->actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/EnBomjimb_Init.s") + if (this->unk_2C6 != ENBOMJIMB_F0_0) { + this->unk_2C8 = ENBOMJIMB_GET_F(&this->actor) + 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/EnBomjimb_Destroy.s") + if (this->unk_2C8 < ENBOMJIMB_F_0) { + this->unk_2C8 = ENBOMJIMB_F_0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C0113C.s") + if (this->unk_2C6 < ENBOMJIMB_F0_0) { + this->unk_2C6 = ENBOMJIMB_F0_0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C011CC.s") + if ((gSaveContext.weekEventReg[73] & 0x10) || (gSaveContext.weekEventReg[85] & 2)) { + switch (this->unk_2C8) { + case ENBOMJIMB_F_0: + if (gSaveContext.weekEventReg[11] & 1) { + Actor_MarkForDeath(&this->actor); + return; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C012E0.s") + case ENBOMJIMB_F_1: + if (gSaveContext.weekEventReg[11] & 2) { + Actor_MarkForDeath(&this->actor); + return; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C012FC.s") + case ENBOMJIMB_F_2: + if (gSaveContext.weekEventReg[11] & 4) { + Actor_MarkForDeath(&this->actor); + return; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C013B4.s") + case ENBOMJIMB_F_3: + if (gSaveContext.weekEventReg[11] & 8) { + Actor_MarkForDeath(&this->actor); + return; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C013F0.s") + case ENBOMJIMB_F_4: + if (gSaveContext.weekEventReg[11] & 0x10) { + Actor_MarkForDeath(&this->actor); + return; + } + break; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C01494.s") + if ((!(gSaveContext.weekEventReg[73] & 0x10) && !(gSaveContext.weekEventReg[85] & 2)) || + (gSaveContext.weekEventReg[75] & 0x40)) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C014E4.s") + Math_Vec3f_Copy(&this->unk_2A0, &this->actor.home.pos); + if ((this->unk_2C6 == ENBOMJIMB_F0_0) || (this->unk_2C6 == ENBOMJIMB_F0_1) || (this->unk_2C6 != ENBOMJIMB_F0_2)) { + func_80C01494(this); + } else { + func_80C01984(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C01984.s") +void EnBomjimb_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnBomjimb* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C01A24.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C01B40.s") +void func_80C0113C(EnBomjimb* this, s32 arg1, f32 arg2) { + static AnimationHeader* sAnimations[] = { + &object_cs_Anim_0064B8, &object_cs_Anim_00FAF4, &object_cs_Anim_0057C8, &object_cs_Anim_0053F4, + &object_cs_Anim_002044, &object_cs_Anim_01007C, &object_cs_Anim_00349C, &object_cs_Anim_004960, + &object_cs_Anim_005128, &object_cs_Anim_004C1C, &object_cs_Anim_002930, &object_cs_Anim_001A1C, + &object_cs_Anim_003EE4, &object_cs_Anim_00478C, &object_cs_Anim_00433C, &object_cs_Anim_0060E8, + &object_cs_Anim_001708, &object_cs_Anim_005DC4, &object_cs_Anim_0026B0, &object_cs_Anim_0036B0, + &object_cs_Anim_0031C4, &object_cs_Anim_010B68, + }; + static u8 D_80C03218[] = { + 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 2, 0, 0, 0, 2, 0, 2, 0, 0, 2, 0, 0, + }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C01B74.s") + this->unk_2DC = arg1; + this->unk_2B8 = Animation_GetLastFrame(sAnimations[arg1]); + Animation_Change(&this->skelAnime, sAnimations[this->unk_2DC], arg2, 0.0f, this->unk_2B8, D_80C03218[this->unk_2DC], + -4.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C01C18.s") +void func_80C011CC(EnBomjimb* this) { + if ((this->unk_2DC == 5) && + (Animation_OnFrame(&this->skelAnime, 9.0f) || Animation_OnFrame(&this->skelAnime, 10.0f) || + Animation_OnFrame(&this->skelAnime, 17.0f) || Animation_OnFrame(&this->skelAnime, 18.0f))) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_BOMBERS_WALK); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C01CD0.s") + if ((this->unk_2DC == 19) && + (Animation_OnFrame(&this->skelAnime, 2.0f) || Animation_OnFrame(&this->skelAnime, 6.0f))) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_BOMBERS_WALK); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C01FD4.s") + if ((this->unk_2DC == 18) && Animation_OnFrame(&this->skelAnime, 15.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_BOMBERS_LAND); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C0201C.s") + if ((this->unk_2DC == 7) && Animation_OnFrame(&this->skelAnime, 8.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_BOMBERS_LAND); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C02108.s") +void func_80C012E0(EnBomjimb* this) { + this->unk_2C0 = 0; + this->unk_2AE = 0; + this->unk_2B0 = 0; + this->unk_2CC = 0; + this->unk_290 = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C0217C.s") +s32 func_80C012FC(EnBomjimb* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C0250C.s") + if (!func_801690CC(globalCtx) && (this->actor.xzDistToPlayer < 40.0f) && + (fabsf(player->actor.world.pos.y - this->actor.world.pos.y) < 50.0f) && (globalCtx->msgCtx.unk11F10 == 0)) { + this->actor.speedXZ = 0.0f; + func_80C02740(this, globalCtx); + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C02570.s") +s32 func_80C013B4(EnBomjimb* this) { + if (this->collider.base.acFlags & AC_HIT) { + func_80C0267C(this); + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C0267C.s") +s32 func_80C013F0(EnBomjimb* this, GlobalContext* globalCtx) { + Actor* sp1C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C02704.s") + if (this->collider.base.ocFlags1 & OC1_HIT) { + sp1C = this->collider.base.oc; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C02740.s") + if ((sp1C->id == ACTOR_OBJ_KIBAKO) && (D_80C03170 == NULL) && (sp1C->update != NULL) && + !Actor_HasParent(sp1C, globalCtx)) { + D_80C03170 = sp1C; + this->unk_2E4 = sp1C; + func_80C01C18(this, globalCtx); + return true; + } + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C02A14.s") +void func_80C01494(EnBomjimb* this) { + func_80C012E0(this); + Math_Vec3f_Copy(&this->unk_2A0, &this->actor.world.pos); + this->unk_2CA = 3; + this->actionFunc = func_80C014E4; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C02BCC.s") +void func_80C014E4(EnBomjimb* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 curFrame = this->skelAnime.curFrame; + CollisionPoly* colPoly; + s16 abs; + f32 x; + f32 z; + f32 phi_f0; + Vec3f sp60; + Vec3f sp54; + Vec3f sp48; + s32 sp44; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C02CA4.s") + if (func_80C012FC(this, globalCtx) || func_80C013B4(this) || func_80C013F0(this, globalCtx)) { + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C02DAC.s") + switch (this->unk_2CC) { + case 0: + if (this->unk_2AE == 0) { + Math_Vec3f_Copy(&sp48, &this->actor.home.pos); + sp48.x += randPlusMinusPoint5Scaled(150.0f); + sp48.z += randPlusMinusPoint5Scaled(150.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/EnBomjimb_Update.s") + abs = ABS_ALT(BINANG_SUB(this->actor.world.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &sp48))); + if ((abs < 0x4000) && !BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.world.pos, &sp48, &sp60, + &colPoly, 1, 0, 0, 1, &sp44)) { + func_80C0113C(this, 5, 1.0f); + Math_Vec3f_Copy(&this->unk_294, &sp48); + this->unk_2B0 = Rand_S16Offset(30, 50); + this->unk_2CC++; + } + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/func_80C02FA8.s") + case 1: + if (curFrame >= 0.0f) { + this->unk_2D6 = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_294); + Math_SmoothStepToS(&this->actor.world.rot.y, this->unk_2D6, 10, 2000, 20); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Bomjimb/EnBomjimb_Draw.s") + if ((s16)ABS_ALT(BINANG_SUB(this->actor.world.rot.y, this->unk_2D6)) < 0x100) { + Math_Vec3f_Copy(&sp54, &this->actor.world.pos); + sp54.x += Math_SinS(this->actor.world.rot.y) * 60.0f; + sp54.z += Math_CosS(this->actor.world.rot.y) * 60.0f; + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.world.pos, &sp54, &sp60, &colPoly, 1, 0, 0, + 1, &sp44)) { + this->unk_2AE = 0; + if (Rand_ZeroOne() < 0.5f) { + func_80C0113C(this, 20, 1.0f); + } else { + func_80C0113C(this, 0, 1.0f); + } + this->unk_2CC = 0; + this->unk_2B4 = 0.0f; + break; + } + } + + x = this->unk_294.x - this->actor.world.pos.x; + z = this->unk_294.z - this->actor.world.pos.z; + + if ((this->unk_2B0 == 0) || (sqrtf(SQ(x) + SQ(z)) < 4.0f)) { + this->unk_2AE = Rand_S16Offset(20, 20); + if (!(this->unk_2AE & 1)) { + func_80C0113C(this, 20, 1.0f); + } else { + func_80C0113C(this, 0, 1.0f); + } + this->unk_2CC = 0; + this->unk_2B4 = 0.0f; + } else if (curFrame >= 0.0f) { + Math_ApproachF(&this->actor.world.pos.x, this->unk_294.x, 0.3f, this->unk_2B4); + Math_ApproachF(&this->actor.world.pos.z, this->unk_294.z, 0.3f, this->unk_2B4); + Math_ApproachF(&this->unk_2B4, 1.0f, 0.3f, 0.5f); + } + break; + } + + if (player->stateFlags3 != 0x1000000) { + phi_f0 = 200.0f; + + abs = ABS_ALT(BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.world.rot.y)); + if (abs > 0x2890) { + phi_f0 = 150.0f; + } + + if (this->actor.xzDistToPlayer < phi_f0) { + func_80C02108(this); + } + } +} + +void func_80C01984(EnBomjimb* this, GlobalContext* globalCtx) { + func_80C012E0(this); + this->unk_2E4 = + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_NIW, this->actor.world.pos.x, + this->actor.world.pos.y + 30.0f, this->actor.world.pos.z, 0, this->actor.world.rot.y, 0, 2); + if (this->unk_2E4 != NULL) { + func_80C0113C(this, 11, 1.0f); + } + this->unk_2CA = 0; + this->actionFunc = func_80C01A24; +} + +void func_80C01A24(EnBomjimb* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + this->actor.gravity = -0.1f; + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + if ((this->unk_2E4 != NULL) && (this->unk_2E4->update != NULL)) { + ((EnNiw*)this->unk_2E4)->unk2BC.z = 90000.0f; + } + this->actor.speedXZ = 0.0f; + this->unk_2E4 = NULL; + this->actor.gravity = -2.0f; + func_80C02108(this); + return; + } + + if ((this->actor.xzDistToPlayer < 200.0f) && (fabsf(player->actor.world.pos.y - this->actor.world.pos.y) < 40.0f)) { + this->unk_2C0 = 1; + } + + if (this->unk_2C0 != 0) { + Math_ApproachF(&this->actor.speedXZ, 6.0f, 0.5f, 2.0f); + } + + if ((this->unk_2C0 != 0) && !(this->actor.bgCheckFlags & 1)) { + func_80C01B40(this); + } +} + +void func_80C01B40(EnBomjimb* this) { + func_80C012E0(this); + this->unk_2CA = 0; + this->actionFunc = func_80C01B74; +} + +void func_80C01B74(EnBomjimb* this, GlobalContext* globalCtx) { + Math_ApproachF(&this->actor.speedXZ, 6.0f, 0.5f, 2.0f); + if ((this->collider.base.acFlags & AC_HIT) || (this->actor.bgCheckFlags & 1)) { + this->collider.base.acFlags &= ~AC_HIT; + if ((this->unk_2E4 != NULL) && (this->unk_2E4->update != NULL)) { + ((EnNiw*)this->unk_2E4)->unk2BC.z = 90000.0f; + } + this->actor.speedXZ = 0.0f; + this->unk_2E4 = NULL; + this->actor.gravity = -2.0f; + func_80C02108(this); + } +} + +void func_80C01C18(EnBomjimb* this, GlobalContext* globalCtx) { + func_80C012E0(this); + if (this->unk_2E4 != NULL) { + if (this->unk_2E4->update != NULL) { + this->unk_2E4->velocity.y = 8.0f; + this->unk_2E4->shape.rot.z = BINANG_SUB(4000, ((s16)(globalCtx->gameplayFrames & 2) * 4000)); + this->unk_294.x = this->unk_2E4->world.pos.x; + this->unk_294.y = this->actor.world.pos.y; + this->unk_294.z = this->unk_2E4->world.pos.z; + } + } + this->actor.speedXZ = 0.0f; + this->unk_2CA = 2; + this->actionFunc = func_80C01CD0; +} + +void func_80C01CD0(EnBomjimb* this, GlobalContext* globalCtx) { + f32 sp3C = this->skelAnime.curFrame; + s32 pad[2]; + + if ((this->unk_2E4 != NULL) && ((this->unk_2E4->update == NULL) || Actor_HasParent(this->unk_2E4, globalCtx))) { + this->actor.draw = EnBomjimb_Draw; + D_80C03170 = NULL; + this->unk_2E4 = NULL; + func_80C02108(this); + return; + } + + if (this->unk_2DC != 7) { + Math_SmoothStepToS(&this->actor.world.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_294), 1, 3000, + 0); + Math_ApproachF(&this->actor.world.pos.x, this->unk_294.x, 0.3f, 2.0f); + Math_ApproachF(&this->actor.world.pos.z, this->unk_294.z, 0.3f, 2.0f); + if (sqrtf(SQ(this->actor.world.pos.x - this->unk_294.x) + SQ(this->actor.world.pos.z - this->unk_294.z)) < + 3.0f) { + func_80C0113C(this, 7, 1.0f); + Math_Vec3f_Copy(&this->actor.world.pos, &this->unk_294); + } + } else if (this->unk_2B8 <= sp3C) { + this->actor.draw = NULL; + } + + if ((this->unk_2C0 == 0) && (this->unk_2E4->bgCheckFlags & 1)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_PUT_DOWN_WOODBOX); + this->unk_2C0 = 1; + } + + if (this->unk_2AE == 0) { + if (this->actor.draw == NULL) { + this->unk_2AE = Rand_S16Offset(20, 30); + this->unk_2E4->shape.rot.z = 1000; + return; + } + + this->unk_2AE = 10; + if ((this->unk_2E4 != NULL) && (this->unk_2E4->update != NULL)) { + if ((globalCtx->gameplayFrames % 16) == 0) { + this->unk_2E4->shape.rot.z = -this->unk_2E4->shape.rot.z; + this->unk_2E4->shape.rot.z *= 0.1f; + } + + if (fabsf(this->unk_2E4->shape.rot.z) < 100.0f) { + this->unk_2E4->shape.rot.z = 0; + } + } + return; + } + + if (this->actor.draw == 0) { + this->unk_2E4->shape.rot.z = -this->unk_2E4->shape.rot.z; + this->unk_2E4->shape.rot.z *= 0.1f; + if (fabsf(this->unk_2E4->shape.rot.z) < 100.0f) { + this->unk_2E4->shape.rot.z = 0; + } + } +} + +void func_80C01FD4(EnBomjimb* this) { + this->actor.textId = 0x72D; + func_80C0113C(this, 9, 1.0f); + this->unk_2CA = 4; + this->actionFunc = func_80C0201C; +} + +void func_80C0201C(EnBomjimb* this, GlobalContext* globalCtx) { + s16 abs = ABS_ALT(BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.world.rot.y)); + + this->unk_290 = 0; + if ((this->actor.xzDistToPlayer < 200.0f) && (abs < 0x61A8)) { + this->unk_290 = this->actor.yawTowardsPlayer - this->actor.world.rot.y; + if (this->unk_290 > 10000) { + this->unk_290 = 10000; + } else if (this->unk_290 < -10000) { + this->unk_290 = -10000; + } + } + + if (func_800B84D0(&this->actor, globalCtx)) { + this->unk_2CA = 10; + this->actionFunc = func_80C02A14; + } else { + func_800B8614(&this->actor, globalCtx, 40.0f); + } +} + +void func_80C02108(EnBomjimb* this) { + func_80C0113C(this, 6, 1.0f); + this->unk_2D6 = BINANG_ROT180(this->actor.yawTowardsPlayer); + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + func_80C012E0(this); + Math_Vec3f_Copy(&this->unk_2A0, &this->actor.world.pos); + this->unk_2D4 = 0; + this->unk_2CA = 5; + this->actionFunc = func_80C0217C; +} + +void func_80C0217C(EnBomjimb* this, GlobalContext* globalCtx) { + Vec3f sp74; + CollisionPoly* sp70; + Vec3f sp64; + s32 sp60; + s32 sp5C = this->actor.floorBgId; + CollisionPoly* sp58 = this->actor.floorPoly; + Player* player = GET_PLAYER(globalCtx); + s32 sp50 = false; + + if (func_80C012FC(this, globalCtx) || func_80C013B4(this) || func_80C013F0(this, globalCtx)) { + return; + } + + if (player->stateFlags3 == 0x1000000) { + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 1, 3000, 0); + func_80C01494(this); + return; + } + + if (this->unk_2DC == 6) { + f32 curFrame = this->skelAnime.curFrame; + + if (this->unk_2B8 <= curFrame) { + func_80C0113C(this, 19, 2.0f); + } + return; + } + + Math_ApproachF(&this->actor.speedXZ, 8.0f, 0.5f, 2.0f); + Math_Vec3f_Copy(&sp74, &this->actor.world.pos); + + sp74.x += Math_SinS(this->actor.world.rot.y) * 50.0f; + sp74.y += 20.0f; + sp74.z += Math_CosS(this->actor.world.rot.y) * 50.0f; + + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.world.pos, &sp74, &sp64, &sp70, 1, 0, 0, 1, &sp60)) { + s16 temp = BINANG_SUB((this->actor.world.rot.y - this->actor.yawTowardsPlayer), 0x8000); + this->unk_2D6 = temp; + + if (temp < 0) { + this->unk_2D6 += BINANG_ADD((s32)Rand_ZeroFloat(0x200), 0x4000); + if (this->unk_2D0 != 0) { + this->unk_2D6 += BINANG_ADD((s32)Rand_ZeroFloat(0x200), 0x4000); + } + this->unk_2D0 = 1; + } else { + this->unk_2D6 -= BINANG_ADD((s32)Rand_ZeroFloat(0x200), 0x4000); + if (this->unk_2D0 != 0) { + this->unk_2D6 -= BINANG_ADD((s32)Rand_ZeroFloat(0x200), 0x4000); + } + this->unk_2D0 = 1; + } + sp50 = true; + } + + if (!sp50) { + this->unk_2D0 = 0; + if (this->actor.xzDistToPlayer < 60.0f) { + this->unk_2D6 = BINANG_ROT180(this->actor.yawTowardsPlayer); + } + } + + this->actor.world.rot.y = this->unk_2D6 + this->unk_2D4; + + if (SurfaceType_GetSceneExitIndex(&globalCtx->colCtx, sp58, sp5C)) { + s16 temp = BINANG_SUB(this->actor.world.rot.y, this->actor.yawTowardsPlayer - 0x8000); + + if (temp < 0) { + this->unk_2D4 -= 0x1000; + } else { + this->unk_2D4 += 0x1000; + } + this->actor.world.rot.y = this->unk_2D6 + this->unk_2D4; + return; + } + + this->unk_2D4 = 0; + if (!sp50 && (this->actor.xzDistToPlayer > 200.0f)) { + func_80C0250C(this); + } +} + +void func_80C0250C(EnBomjimb* this) { + func_80C0113C(this, 15, 1.0f); + this->unk_2D4 = 0; + this->actor.speedXZ = 0.0f; + this->unk_2D6 = BINANG_ROT180(this->actor.yawTowardsPlayer); + func_80C012E0(this); + this->unk_2CA = 6; + this->actionFunc = func_80C02570; +} + +void func_80C02570(EnBomjimb* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (func_80C012FC(this, globalCtx) || func_80C013B4(this) || func_80C013F0(this, globalCtx)) { + return; + } + + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 1, 5000, 0); + + if (this->actor.xzDistToPlayer < 200.0f) { + this->unk_2D6 = BINANG_ROT180(this->actor.yawTowardsPlayer); + func_80C0113C(this, 19, 2.0f); + this->actionFunc = func_80C0217C; + } else if ((player->stateFlags3 == 0x1000000) || (this->actor.xzDistToPlayer > 410.0f)) { + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 1, 3000, 0); + func_80C01494(this); + } +} + +void func_80C0267C(EnBomjimb* this) { + func_80C012E0(this); + func_80C0113C(this, 8, 1.0f); + this->actor.speedXZ = 0.0f; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + this->unk_2AE = 40; + this->unk_2C2 = 0; + this->unk_2C4 = (s32)Rand_ZeroFloat(60.0f) + 20; + this->unk_2CA = 7; + this->actionFunc = func_80C02704; +} + +void func_80C02704(EnBomjimb* this, GlobalContext* globalCtx) { + if (!func_80C012FC(this, globalCtx) && (this->unk_2AE == 0)) { + func_80C0250C(this); + } +} + +void func_80C02740(EnBomjimb* this, GlobalContext* globalCtx) { + static u16 D_80C03230[] = { + 0x0721, 0x0722, 0x0723, 0x0724, 0x072C, + }; + Player* player = GET_PLAYER(globalCtx); + s16 idx; + + func_80C012E0(this); + func_80C0113C(this, 21, 1.0f); + if ((player->transformation != PLAYER_FORM_DEKU) && (player->transformation != PLAYER_FORM_HUMAN)) { + func_80C0113C(this, 17, 1.0f); + func_801518B0(globalCtx, 0x72E, &this->actor); + player->stateFlags1 |= 0x10000000; + player->actor.freezeTimer = 3; + func_80C012E0(this); + this->unk_2CA = 9; + this->actionFunc = func_80C02BCC; + return; + } + + if (((player->transformation == PLAYER_FORM_DEKU) && !(gSaveContext.weekEventReg[73] & 0x10)) || + ((player->transformation == PLAYER_FORM_HUMAN) && !(gSaveContext.weekEventReg[85] & 2))) { + func_80C0113C(this, 17, 1.0f); + func_801518B0(globalCtx, 0x72E, &this->actor); + player->stateFlags1 |= 0x10000000; + player->actor.freezeTimer = 3; + func_80C012E0(this); + this->unk_2CA = 9; + this->actionFunc = func_80C02BCC; + return; + } + + idx = gSaveContext.unk_FE6; + func_801518B0(globalCtx, D_80C03230[idx], &this->actor); + idx = gSaveContext.unk_FE6; + gSaveContext.unk_FE7[idx] = this->unk_2C8 + 1; + gSaveContext.unk_FE6++; + + if (gSaveContext.unk_FE6 > 4) { + func_801A3098(0x922); + } else { + Audio_PlayActorSound2(&this->actor, NA_SE_SY_PIECE_OF_HEART); + } + + switch (this->unk_2C8) { + case ENBOMJIMB_F_0: + gSaveContext.weekEventReg[76] |= 1; + gSaveContext.weekEventReg[11] |= 1; + break; + + case ENBOMJIMB_F_1: + gSaveContext.weekEventReg[76] |= 2; + gSaveContext.weekEventReg[11] |= 2; + break; + + case ENBOMJIMB_F_2: + gSaveContext.weekEventReg[76] |= 4; + gSaveContext.weekEventReg[11] |= 4; + break; + + case ENBOMJIMB_F_3: + gSaveContext.weekEventReg[76] |= 8; + gSaveContext.weekEventReg[11] |= 8; + break; + + case ENBOMJIMB_F_4: + gSaveContext.weekEventReg[76] |= 0x10; + gSaveContext.weekEventReg[11] |= 0x10; + break; + } + + if (!func_801690CC(globalCtx)) { + Player* player = GET_PLAYER(globalCtx); + + player->stateFlags1 |= 0x10000000; + player->actor.freezeTimer = 3; + } + this->unk_2CA = 8; + this->actionFunc = func_80C02A14; +} + +void func_80C02A14(EnBomjimb* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 curFrame = this->skelAnime.curFrame; + + if (this->unk_2DC == 21) { + player->actor.freezeTimer = 3; + if (this->unk_2B8 <= curFrame) { + func_80C0113C(this, 9, 1.0f); + } + return; + } + + if ((this->unk_2CA == 8) && (this->unk_2DC == 9)) { + player->actor.freezeTimer = 3; + if (this->unk_2E0 == 0) { + if (Animation_OnFrame(&this->skelAnime, 7.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_HUMAN_BOUND); + this->unk_2E0 = 1; + } + } + } + + if ((this->unk_2DC == 15) && (this->unk_2CA == 8)) { + player->actor.freezeTimer = 3; + } + + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + func_801477B4(globalCtx); + if ((this->unk_2CA == 8) && (gSaveContext.unk_FE6 >= 5)) { + func_80C02CA4(this, globalCtx); + } else { + if (this->unk_2CA == 8) { + player->stateFlags1 &= ~0x10000000; + } + func_80C01FD4(this); + } + } +} + +void func_80C02BCC(EnBomjimb* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 1, 5000, 0); + if (this->unk_2C0 == 0) { + player->actor.freezeTimer = 3; + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + func_801477B4(globalCtx); + this->unk_2C0 = 1; + player->stateFlags1 &= ~0x10000000; + } + } else if (this->actor.xzDistToPlayer > 200.0f) { + func_80C01494(this); + } +} + +void func_80C02CA4(EnBomjimb* this, GlobalContext* globalCtx) { + if (BREG(13) == 0) { + globalCtx->nextEntranceIndex = globalCtx->setupExitList[this->unk_2B2]; + gSaveContext.nextCutsceneIndex = 0; + Scene_SetExitFade(globalCtx); + globalCtx->sceneLoadFlag = 0x14; + } else { + globalCtx->nextEntranceIndex = Entrance_CreateIndexFromSpawn(5); + gSaveContext.nextCutsceneIndex = 0; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 0x56; + gSaveContext.nextTransition = 3; + } + gSaveContext.weekEventReg[75] |= 0x40; + gSaveContext.weekEventReg[83] |= 4; + this->actionFunc = func_80C02DAC; +} + +void func_80C02DAC(EnBomjimb* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + player->actor.freezeTimer = 3; +} + +void EnBomjimb_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnBomjimb* this = THIS; + + if (this->unk_2B0 != 0) { + this->unk_2B0--; + } + + if (this->unk_2AE != 0) { + this->unk_2AE--; + } + + if (this->unk_2AC != 0) { + this->unk_2AC--; + } + + SkelAnime_Update(&this->skelAnime); + this->actor.shape.rot.y = this->actor.world.rot.y; + func_80C011CC(this); + Actor_SetHeight(&this->actor, 20.0f); + + this->actionFunc(this, globalCtx); + + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + + if (this->unk_2CA == 0) { + if ((this->unk_2E4 != NULL) && (this->unk_2E4->update != NULL)) { + Math_Vec3f_Copy(&this->unk_2E4->world.pos, &this->actor.world.pos); + if (this->actor.bgCheckFlags & 1) { + this->unk_2E4->world.pos.y = this->actor.world.pos.y + 35.0f; + } else { + this->unk_2E4->world.pos.y = this->actor.world.pos.y + 25.0f; + } + } + } + + Math_SmoothStepToS(&this->unk_28A, this->unk_290, 1, 5000, 0); + + if (this->unk_2C4 == 0) { + this->unk_2C2++; + if (this->unk_2C2 > 2) { + this->unk_2C2 = 0; + this->unk_2C4 = (s16)Rand_ZeroFloat(60.0f) + 20; + } + } + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 50.0f, 0x1D); + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + + if (this->unk_2CA != 2) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +s32 EnBomjimb_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnBomjimb* this = THIS; + + if (limbIndex == 15) { + *dList = NULL; + } + + if (limbIndex == 17) { + rot->x += this->unk_28A; + rot->z += this->unk_288; + } + + if ((limbIndex == 19) && (this->unk_2C8 != ENBOMJIMB_F_0)) { + *dList = NULL; + } + + if ((limbIndex == 20) && (this->unk_2C8 == ENBOMJIMB_F_0)) { + *dList = NULL; + } + + return false; +} + +#include "overlays/ovl_En_Bomjimb/ovl_En_Bomjimb.c" + +void EnBomjimb_Draw(Actor* thisx, GlobalContext* globalCtx) { + static Gfx* D_80C03260[] = { + gEnBomjimb_D_80C03240, gEnBomjimb_D_80C03250, gEnBomjimb_D_80C03250, + gEnBomjimb_D_80C03250, gEnBomjimb_D_80C03250, + }; + static TexturePtr D_80C03274[] = { + &object_cs_Tex_00C520, + &object_cs_Tex_00CD20, + &object_cs_Tex_00D520, + }; + static TexturePtr D_80C03280[] = { + &object_cs_Tex_00E620, &object_cs_Tex_00EA20, &object_cs_Tex_00EE20, + &object_cs_Tex_00DD20, &object_cs_Tex_00F220, + }; + EnBomjimb* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80C03274[this->unk_2C2])); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80C03280[this->unk_2C8])); + gSPSegment(POLY_OPA_DISP++, 0x0A, Lib_SegmentedToVirtual(D_80C03260[this->unk_2C8])); + + Scene_SetRenderModeXlu(globalCtx, 0, 1); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnBomjimb_OverrideLimbDraw, NULL, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Bomjimb/z_en_bomjimb.h b/src/overlays/actors/ovl_En_Bomjimb/z_en_bomjimb.h index 664b34224..7a961461c 100644 --- a/src/overlays/actors/ovl_En_Bomjimb/z_en_bomjimb.h +++ b/src/overlays/actors/ovl_En_Bomjimb/z_en_bomjimb.h @@ -7,11 +7,58 @@ struct EnBomjimb; typedef void (*EnBomjimbActionFunc)(struct EnBomjimb*, GlobalContext*); +#define ENBOMJIMB_GET_F(thisx) ((thisx)->params & 0xF) +#define ENBOMJIMB_GET_F0(thisx) (((thisx)->params >> 4) & 0xF) +#define ENBOMJIMB_GET_FF00(thisx) (((thisx)->params >> 8) & 0xFF) + +enum { + /* 0 */ ENBOMJIMB_F_0, + /* 1 */ ENBOMJIMB_F_1, + /* 2 */ ENBOMJIMB_F_2, + /* 3 */ ENBOMJIMB_F_3, + /* 4 */ ENBOMJIMB_F_4, +}; + +enum { + /* 0 */ ENBOMJIMB_F0_0, + /* 1 */ ENBOMJIMB_F0_1, + /* 2 */ ENBOMJIMB_F0_2, +}; + typedef struct EnBomjimb { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x140]; - /* 0x0284 */ EnBomjimbActionFunc actionFunc; - /* 0x0288 */ char unk_288[0xAC]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[21]; + /* 0x206 */ Vec3s morphTable[21]; + /* 0x284 */ EnBomjimbActionFunc actionFunc; + /* 0x288 */ s16 unk_288; + /* 0x28A */ s16 unk_28A; + /* 0x28C */ UNK_TYPE1 unk28C[4]; + /* 0x290 */ s16 unk_290; + /* 0x294 */ Vec3f unk_294; + /* 0x2A0 */ Vec3f unk_2A0; + /* 0x2AC */ s16 unk_2AC; + /* 0x2AE */ s16 unk_2AE; + /* 0x2B0 */ s16 unk_2B0; + /* 0x2B2 */ s16 unk_2B2; + /* 0x2B4 */ f32 unk_2B4; + /* 0x2B8 */ f32 unk_2B8; + /* 0x2BC */ UNK_TYPE1 unk2BC[4]; + /* 0x2C0 */ s16 unk_2C0; + /* 0x2C2 */ s16 unk_2C2; + /* 0x2C4 */ s16 unk_2C4; + /* 0x2C6 */ s16 unk_2C6; + /* 0x2C8 */ s16 unk_2C8; + /* 0x2CA */ s16 unk_2CA; + /* 0x2CC */ s16 unk_2CC; + /* 0x2D0 */ s32 unk_2D0; + /* 0x2D4 */ s16 unk_2D4; + /* 0x2D6 */ s16 unk_2D6; + /* 0x2D8 */ UNK_TYPE1 unk2D8[4]; + /* 0x2DC */ s32 unk_2DC; + /* 0x2E0 */ u8 unk_2E0; + /* 0x2E4 */ Actor* unk_2E4; + /* 0x2E8 */ ColliderCylinder collider; } EnBomjimb; // size = 0x334 extern const ActorInit En_Bomjimb_InitVars; diff --git a/src/overlays/actors/ovl_En_Boom/z_en_boom.c b/src/overlays/actors/ovl_En_Boom/z_en_boom.c index 99efd7f3d..b6115a897 100644 --- a/src/overlays/actors/ovl_En_Boom/z_en_boom.c +++ b/src/overlays/actors/ovl_En_Boom/z_en_boom.c @@ -1,5 +1,5 @@ /* - * File z_en_boom.c + * File: z_en_boom.c * Overlay: ovl_En_Boom * Description: Zora boomerangs */ diff --git a/src/overlays/actors/ovl_En_Box/z_en_box.c b/src/overlays/actors/ovl_En_Box/z_en_box.c index f3a2d835c..7367f49bc 100644 --- a/src/overlays/actors/ovl_En_Box/z_en_box.c +++ b/src/overlays/actors/ovl_En_Box/z_en_box.c @@ -1,5 +1,5 @@ /* - * File z_en_box.c + * File: z_en_box.c * Overlay: ovl_En_Box * Description: Chest */ diff --git a/src/overlays/actors/ovl_En_Bsb/z_en_bsb.c b/src/overlays/actors/ovl_En_Bsb/z_en_bsb.c index 0bb1f7e29..2e6b31a35 100644 --- a/src/overlays/actors/ovl_En_Bsb/z_en_bsb.c +++ b/src/overlays/actors/ovl_En_Bsb/z_en_bsb.c @@ -1,5 +1,5 @@ /* - * File z_en_bsb.c + * File: z_en_bsb.c * Overlay: ovl_En_Bsb * Description: Captain Keeta */ diff --git a/src/overlays/actors/ovl_En_Bu/z_en_bu.c b/src/overlays/actors/ovl_En_Bu/z_en_bu.c index 4bd1e310f..3c5653525 100644 --- a/src/overlays/actors/ovl_En_Bu/z_en_bu.c +++ b/src/overlays/actors/ovl_En_Bu/z_en_bu.c @@ -1,5 +1,5 @@ /* - * File z_en_bu.c + * File: z_en_bu.c * Overlay: ovl_En_Bu * Description: Unused dummied-out enemy */ @@ -54,9 +54,9 @@ void EnBu_Draw(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); - Matrix_InsertZRotation_s(this->actor.shape.rot.z, 1); - Matrix_RotateY(this->actor.shape.rot.y, 1); - Matrix_InsertXRotation_s(this->actor.shape.rot.x, 1); + Matrix_InsertZRotation_s(this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->actor.shape.rot.x, MTXMODE_APPLY); Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, this->displayListPtr); diff --git a/src/overlays/actors/ovl_En_Bubble/z_en_bubble.c b/src/overlays/actors/ovl_En_Bubble/z_en_bubble.c index 4cddd0d54..e6ff6864a 100644 --- a/src/overlays/actors/ovl_En_Bubble/z_en_bubble.c +++ b/src/overlays/actors/ovl_En_Bubble/z_en_bubble.c @@ -1,7 +1,7 @@ /* - * File z_en_bubble.c + * File: z_en_bubble.c * Overlay: ovl_En_Bubble - * Description: Bubble (flying skull enemy) + * Description: Shabom (unused) */ #include "z_en_bubble.h" diff --git a/src/overlays/actors/ovl_En_Bubble/z_en_bubble.h b/src/overlays/actors/ovl_En_Bubble/z_en_bubble.h index c78b9df69..f2901b324 100644 --- a/src/overlays/actors/ovl_En_Bubble/z_en_bubble.h +++ b/src/overlays/actors/ovl_En_Bubble/z_en_bubble.h @@ -10,7 +10,7 @@ typedef void (*EnBubbleActionFunc)(struct EnBubble*, GlobalContext*); typedef struct EnBubble { /* 0x0000 */ Actor actor; /* 0x0144 */ EnBubbleActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x110]; + /* 0x0148 */ char unk_148[0x110]; } EnBubble; // size = 0x258 extern const ActorInit En_Bubble_InitVars; diff --git a/src/overlays/actors/ovl_En_Butte/z_en_butte.c b/src/overlays/actors/ovl_En_Butte/z_en_butte.c index e8b2dceb4..54dd34dbc 100644 --- a/src/overlays/actors/ovl_En_Butte/z_en_butte.c +++ b/src/overlays/actors/ovl_En_Butte/z_en_butte.c @@ -1,5 +1,5 @@ /* - * File z_en_butte.c + * File: z_en_butte.c * Overlay: ovl_En_Butte * Description: Butterflies */ diff --git a/src/overlays/actors/ovl_En_Cha/z_en_cha.c b/src/overlays/actors/ovl_En_Cha/z_en_cha.c index 9a1280c29..d8f32613f 100644 --- a/src/overlays/actors/ovl_En_Cha/z_en_cha.c +++ b/src/overlays/actors/ovl_En_Cha/z_en_cha.c @@ -119,6 +119,6 @@ void EnCha_Draw(Actor* thisx, GlobalContext* globalCtx) { func_800BDFC0(globalCtx, D_06000710); Matrix_InsertTranslation(-1094.0f, 4950.0f, 9.0f, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->actor.home.rot.x, 1); + Matrix_InsertXRotation_s(this->actor.home.rot.x, MTXMODE_APPLY); func_800BDFC0(globalCtx, D_06000958); } diff --git a/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c b/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c index 6ee8f0055..04180ab47 100644 --- a/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c +++ b/src/overlays/actors/ovl_En_Clear_Tag/z_en_clear_tag.c @@ -1,5 +1,5 @@ /* - * File z_en_clear_tag.c + * File: z_en_clear_tag.c * Overlay: ovl_En_Clear_Tag * Description: Various effects: explosions and pops, splashes, light rays */ @@ -416,7 +416,7 @@ void EnClearTag_Init(Actor* thisx, GlobalContext* globalCtx) { for (i = 0; i < 54; i++) { lightRayMaxScale = sLightRayMaxScale[thisx->params] + Rand_ZeroFloat(sLightRayMaxScale[thisx->params]); - Matrix_InsertYRotation_f(Rand_ZeroFloat(M_PI * 2), 0); + Matrix_InsertYRotation_f(Rand_ZeroFloat(M_PI * 2), MTXMODE_NEW); Matrix_RotateStateAroundXAxis(Rand_ZeroFloat(M_PI * 2)); Matrix_GetStateTranslationAndScaledZ(lightRayMaxScale, &vel); accel.x = vel.x * -0.03f; @@ -489,7 +489,7 @@ void EnClearTag_Init(Actor* thisx, GlobalContext* globalCtx) { pos = this->actor.world.pos; for (i = 0; i < 44; i++) { lightRayMaxScale = sLightRayMaxScale[thisx->params] + Rand_ZeroFloat(sLightRayMaxScale[thisx->params]); - Matrix_InsertYRotation_f(Rand_ZeroFloat(2 * M_PI), 0); + Matrix_InsertYRotation_f(Rand_ZeroFloat(2 * M_PI), MTXMODE_NEW); Matrix_RotateStateAroundXAxis(Rand_ZeroFloat(2 * M_PI)); Matrix_GetStateTranslationAndScaledZ(lightRayMaxScale, &vel); accel.x = vel.x * -0.03f; @@ -538,7 +538,7 @@ void EnClearTag_UpdateCamera(EnClearTag* this, GlobalContext* globalCtx) { func_80169590(globalCtx, 0, 1); func_80169590(globalCtx, this->camId, 7); func_800B7298(globalCtx, &this->actor, 4); - camera = Play_GetCamera(globalCtx, 0); + camera = Play_GetCamera(globalCtx, MAIN_CAM); this->eye.x = camera->eye.x; this->eye.y = camera->eye.y; this->eye.z = camera->eye.z; @@ -557,7 +557,7 @@ void EnClearTag_UpdateCamera(EnClearTag* this, GlobalContext* globalCtx) { player->actor.speedXZ = 0.0f; if (func_80152498(&globalCtx->msgCtx) == 0) { - camera = Play_GetCamera(globalCtx, 0); + camera = Play_GetCamera(globalCtx, MAIN_CAM); camera->eye = this->eye; camera->eyeNext = this->eye; camera->at = this->at; @@ -871,7 +871,7 @@ void EnClearTag_DrawEffects(Actor* thisx, GlobalContext* globalCtx) { POLY_XLU_DISP++, 0x08, Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, -effect->actionTimer * 5, 32, 64, 1, 0, 0, 32, 32)); Matrix_InsertTranslation(effect->position.x, effect->position.y, effect->position.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(effect->smokeScaleX * effect->scale, effect->smokeScaleY * effect->scale, 1.0f, MTXMODE_APPLY); Matrix_InsertTranslation(0.0f, 20.0f, 0.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); @@ -897,7 +897,7 @@ void EnClearTag_DrawEffects(Actor* thisx, GlobalContext* globalCtx) { POLY_XLU_DISP++, 0x08, Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, -effect->actionTimer * 15, 32, 64, 1, 0, 0, 32, 32)); Matrix_InsertTranslation(effect->position.x, effect->position.y, effect->position.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(effect->scale, effect->scale, 1.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, gClearTagFireEffectDL); @@ -919,7 +919,7 @@ void EnClearTag_DrawEffects(Actor* thisx, GlobalContext* globalCtx) { // Draw the flash billboard effect. gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 200, (s8)effect->primColor.a); Matrix_InsertTranslation(effect->position.x, effect->position.y, effect->position.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(2.0f * effect->scale, 2.0f * effect->scale, 1.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, gClearTagFlashEffectDL); diff --git a/src/overlays/actors/ovl_En_Cne_01/z_en_cne_01.c b/src/overlays/actors/ovl_En_Cne_01/z_en_cne_01.c index fcb693e71..698878d71 100644 --- a/src/overlays/actors/ovl_En_Cne_01/z_en_cne_01.c +++ b/src/overlays/actors/ovl_En_Cne_01/z_en_cne_01.c @@ -1,7 +1,7 @@ /* - * File z_en_cne_01.c + * File: z_en_cne_01.c * Overlay: ovl_En_Cne_01 - * Description: + * Description: Unused Market NPC */ #include "z_en_cne_01.h" diff --git a/src/overlays/actors/ovl_En_Cne_01/z_en_cne_01.h b/src/overlays/actors/ovl_En_Cne_01/z_en_cne_01.h index 4211550ec..db0e797e9 100644 --- a/src/overlays/actors/ovl_En_Cne_01/z_en_cne_01.h +++ b/src/overlays/actors/ovl_En_Cne_01/z_en_cne_01.h @@ -10,7 +10,7 @@ typedef void (*EnCne01ActionFunc)(struct EnCne01*, GlobalContext*); typedef struct EnCne01 { /* 0x0000 */ Actor actor; /* 0x0144 */ EnCne01ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x4D4]; + /* 0x0148 */ char unk_148[0x4D4]; } EnCne01; // size = 0x61C extern const ActorInit En_Cne_01_InitVars; diff --git a/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.c b/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.c index d6d7f4100..9a70e1c7d 100644 --- a/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.c +++ b/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.c @@ -1,10 +1,12 @@ /* - * File z_en_col_man.c + * File: z_en_col_man.c * Overlay: ovl_En_Col_Man - * Description: Gives you a Piece of Heart when you touch it? + * Description: Lab HP, Garo Master falling rocks, Garo Master bomb */ #include "z_en_col_man.h" +#include "overlays/actors/ovl_En_Bom/z_en_bom.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x00100000 @@ -13,17 +15,35 @@ void EnColMan_Init(Actor* thisx, GlobalContext* globalCtx); void EnColMan_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnColMan_Update(Actor* thisx, GlobalContext* globalCtx); - +void func_80AFDD60(EnColMan* this); void func_80AFDE00(EnColMan* this, GlobalContext* globalCtx); -void func_80AFDF00(EnColMan* this, GlobalContext* globalCtx); +void EnColMan_SetHeartPieceCollectedAndKill(EnColMan* this, GlobalContext* globalCtx); +void func_80AFDF60(EnColMan* this); void func_80AFDFB4(EnColMan* this, GlobalContext* globalCtx); +void func_80AFE234(EnColMan* this); void func_80AFE25C(EnColMan* this, GlobalContext* globalCtx); +void func_80AFE414(Actor* thisx, GlobalContext* globalCtx); +void func_80AFE4AC(Actor* thisx, GlobalContext* globalCtx); +void func_80AFE584(Actor* thisx, GlobalContext* globalCtx); +void func_80AFE650(Actor* thisx, GlobalContext* globalCtx); -#if 0 -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80AFE730 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 10, 11, 1, { 0, 0, 0 } }, }; @@ -39,34 +59,217 @@ const ActorInit En_Col_Man_InitVars = { (ActorFunc)NULL, }; -#endif +static Color_RGBA8 primColor = { 60, 50, 20, 255 }; +static Color_RGBA8 envColor = { 40, 30, 30, 255 }; -extern ColliderCylinderInit D_80AFE730; +void EnColMan_Init(Actor* thisx, GlobalContext* globalCtx) { + EnColMan* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/EnColMan_Init.s") + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + this->actor.targetMode = 1; + this->scale = (BREG(55) / 1000.0f) + 0.01f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/EnColMan_Destroy.s") + switch (this->actor.params) { + case EN_COL_MAN_HEART_PIECE: + case EN_COL_MAN_RECOVERY_HEART: + default: + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 10.0f); + func_80AFDD60(this); + break; + case EN_COL_MAN_FALLING_ROCK: + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 10.0f); + func_80AFDF60(this); + break; + case EN_COL_MAN_CUTSCENE_BOMB: + case EN_COL_MAN_GAMEPLAY_BOMB: + func_80AFE234(this); + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFDD60.s") +void EnColMan_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnColMan* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFDE00.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFDF00.s") +void func_80AFDD60(EnColMan* this) { + if (!(gSaveContext.weekEventReg[56] & 2)) { + this->actor.draw = func_80AFE414; + this->actor.shape.yOffset = 700.0f; + if (this->actor.params == EN_COL_MAN_HEART_PIECE) { + this->actor.gravity = -2.0f; + } + this->type = EN_COL_MAN_HEART_PIECE; + } else { + this->actor.draw = func_80AFE4AC; + this->actor.shape.yOffset = 300.0f; + this->actor.shape.shadowScale = 5.0f; + if (this->actor.params == EN_COL_MAN_HEART_PIECE) { + this->actor.gravity = -2.0f; + } + this->type = EN_COL_MAN_RECOVERY_HEART; + } + this->actionFunc = func_80AFDE00; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFDF60.s") +void func_80AFDE00(EnColMan* this, GlobalContext* globalCtx) { + if (this->actor.bgCheckFlags & 1) { + if (this->actor.params == EN_COL_MAN_HEART_PIECE) { + this->actor.params = EN_COL_MAN_RECOVERY_HEART; + this->actor.speedXZ = 2.0f; + this->actor.velocity.y = 8.0f; + } else { + this->actor.speedXZ = 0.0f; + } + } + if (!(gSaveContext.weekEventReg[56] & 2)) { + this->actor.shape.rot.y += 0x3E8; + } + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + this->actor.draw = NULL; + this->actionFunc = EnColMan_SetHeartPieceCollectedAndKill; + } else if (!(gSaveContext.weekEventReg[56] & 2)) { + func_800B8A1C(&this->actor, globalCtx, GI_HEART_PIECE, 40.0f, 40.0f); + } else { + func_800B8A1C(&this->actor, globalCtx, GI_RECOVERY_HEART, 40.0f, 40.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFDFB4.s") +void EnColMan_SetHeartPieceCollectedAndKill(EnColMan* this, GlobalContext* globalCtx) { + if (func_80152498(&globalCtx->msgCtx) == 6 && func_80147624(globalCtx)) { + gSaveContext.weekEventReg[56] |= 2; + Actor_MarkForDeath(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFE234.s") +void func_80AFDF60(EnColMan* this) { + this->actor.draw = func_80AFE584; + this->actor.flags |= 0x10; + this->actor.flags |= 0x20; + this->type = EN_COL_MAN_FALLING_ROCK; + this->actionFunc = func_80AFDFB4; + this->actor.shape.shadowScale = 5.0f; + this->actor.gravity = -3.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFE25C.s") +void func_80AFDFB4(EnColMan* this, GlobalContext* globalCtx) { + s32 i; + Vec3f velocity; + Vec3f accel; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/EnColMan_Update.s") + this->scale = (BREG(55) / 10000.0f) + 0.0015f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFE414.s") + if ((this->actor.bgCheckFlags & 1) && (this->actor.velocity.y < 0.0f)) { + if (!this->hasSetRandomValues) { + this->actor.world.rot.y = randPlusMinusPoint5Scaled(30000.0f); + this->actor.speedXZ = 2.0f + BREG(56) + Rand_ZeroFloat(2.0f); + this->actor.velocity.y = 12.0f + BREG(57) + Rand_ZeroFloat(5.0f); + this->hasSetRandomValues = true; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_ANSATSUSYA_ROCK); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFE4AC.s") + for (i = 0; i < 2; i++) { + velocity.x = randPlusMinusPoint5Scaled(2.0f); + velocity.y = Rand_ZeroFloat(2.0f) + 1.0f; + velocity.z = randPlusMinusPoint5Scaled(2.0f); + accel.y = -0.1f; + accel.z = 0.0f; + accel.x = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFE584.s") + func_800B0EB0(globalCtx, &this->actor.world.pos, &velocity, &accel, &primColor, &envColor, + Rand_ZeroFloat(50.0f) + 60.0f, 30, Rand_ZeroFloat(5.0f) + 20.0f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Col_Man/func_80AFE650.s") + Actor_MarkForDeath(&this->actor); + } +} + +void func_80AFE234(EnColMan* this) { + this->actor.draw = func_80AFE650; + this->type = EN_COL_MAN_CUTSCENE_BOMB; + this->actionFunc = func_80AFE25C; +} + +void func_80AFE25C(EnColMan* this, GlobalContext* globalCtx) { + this->scale = BREG(55) * 0.01f + 0.05f; + + if (BREG(60) || (this->actor.world.rot.z != 0)) { + if (this->actor.params == EN_COL_MAN_CUTSCENE_BOMB) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->actor.parent->world.pos.x, + this->actor.parent->world.pos.y, this->actor.parent->world.pos.z, 0, 0, 0, + CLEAR_TAG_SMALL_EXPLOSION); + } else { + EnBom* bomb = (EnBom*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_BOM, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0); + + if (bomb != NULL) { + bomb->timer = 0; + } + } + + Audio_PlayActorSound2(&this->actor, NA_SE_IT_BOMB_EXPLOSION); + Actor_MarkForDeath(&this->actor); + } +} + +void EnColMan_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnColMan* this = THIS; + + Actor_SetScale(&this->actor, this->scale); + this->actionFunc(this, globalCtx); + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 30.0f, 30.0f, 0x1F); + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void func_80AFE414(Actor* thisx, GlobalContext* globalCtx) { + EnColMan* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + func_800B8118(&this->actor, globalCtx, 0); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_05AAB0); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80AFE4AC(Actor* thisx, GlobalContext* globalCtx) { + EnColMan* this = THIS; + + func_8012C2DC(globalCtx->state.gfxCtx); + func_8012C28C(globalCtx->state.gfxCtx); + OPEN_DISPS(globalCtx->state.gfxCtx); + POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP); + POLY_OPA_DISP = func_8012C724(POLY_OPA_DISP); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(&gameplay_keep_Tex_05E6F0)); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_05F6F0); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80AFE584(Actor* thisx, GlobalContext* globalCtx) { + func_8012C2DC(globalCtx->state.gfxCtx); + func_8012C28C(globalCtx->state.gfxCtx); + OPEN_DISPS(globalCtx->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x80, 255, 255, 255, 255); + gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 255); + gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_06AB30); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80AFE650(Actor* thisx, GlobalContext* globalCtx) { + func_8012C28C(globalCtx->state.gfxCtx); + OPEN_DISPS(globalCtx->state.gfxCtx); + POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP); + POLY_OPA_DISP = func_8012C724(POLY_OPA_DISP); + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(&gameplay_keep_Tex_05CEF0)); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_05F6F0); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.h b/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.h index 31d1b980e..ab1ac285d 100644 --- a/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.h +++ b/src/overlays/actors/ovl_En_Col_Man/z_en_col_man.h @@ -8,10 +8,21 @@ struct EnColMan; typedef void (*EnColManActionFunc)(struct EnColMan*, GlobalContext*); typedef struct EnColMan { - /* 0x0000 */ Actor actor; - /* 0x0144 */ EnColManActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x58]; -} EnColMan; // size = 0x1A0 + /* 0x000 */ Actor actor; + /* 0x144 */ EnColManActionFunc actionFunc; + /* 0x148 */ s16 type; // never used, only set + /* 0x14C */ s32 hasSetRandomValues; + /* 0x150 */ f32 scale; + /* 0x154 */ ColliderCylinder collider; +} EnColMan; /* size = 0x1A0 */ + +typedef enum { + /* 0 */ EN_COL_MAN_HEART_PIECE, + /* 1 */ EN_COL_MAN_RECOVERY_HEART, + /* 2 */ EN_COL_MAN_FALLING_ROCK, + /* 3 */ EN_COL_MAN_CUTSCENE_BOMB, + /* 4 */ EN_COL_MAN_GAMEPLAY_BOMB, +} EnColManType; extern const ActorInit En_Col_Man_InitVars; diff --git a/src/overlays/actors/ovl_En_Cow/z_en_cow.c b/src/overlays/actors/ovl_En_Cow/z_en_cow.c index 84f6928a7..54eb091b7 100644 --- a/src/overlays/actors/ovl_En_Cow/z_en_cow.c +++ b/src/overlays/actors/ovl_En_Cow/z_en_cow.c @@ -1,5 +1,5 @@ /* - * File z_en_cow.c + * File: z_en_cow.c * Overlay: ovl_En_Cow * Description: Cow */ @@ -15,16 +15,18 @@ void EnCow_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnCow_Update(Actor* thisx, GlobalContext* globalCtx); void EnCow_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_8099CAA8(EnCow* this, GlobalContext* globalCtx); -void func_8099CB20(EnCow* this, GlobalContext* globalCtx); -void func_8099CB68(EnCow* this, GlobalContext* globalCtx); -void func_8099CBCC(EnCow* this, GlobalContext* globalCtx); -void func_8099CC68(EnCow* this, GlobalContext* globalCtx); -void func_8099CCF8(EnCow* this, GlobalContext* globalCtx); -void func_8099CDA0(EnCow* this, GlobalContext* globalCtx); -void func_8099CFAC(EnCow* this, GlobalContext* globalCtx); +void EnCow_TalkEnd(EnCow* this, GlobalContext* globalCtx); +void EnCow_GiveMilkEnd(EnCow* this, GlobalContext* globalCtx); +void EnCow_GiveMilkWait(EnCow* this, GlobalContext* globalCtx); +void EnCow_GiveMilk(EnCow* this, GlobalContext* globalCtx); +void EnCow_CheckForEmptyBottle(EnCow* this, GlobalContext* globalCtx); +void EnCow_Talk(EnCow* this, GlobalContext* globalCtx); +void EnCow_Idle(EnCow* this, GlobalContext* globalCtx); + +void EnCow_DoTail(EnCow* this, GlobalContext* globalCtx); +void EnCow_UpdateTail(Actor* this, GlobalContext* globalCtx); +void EnCow_DrawTail(Actor* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Cow_InitVars = { ACTOR_EN_COW, ACTORCAT_NPC, @@ -37,57 +39,404 @@ const ActorInit En_Cow_InitVars = { (ActorFunc)EnCow_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_8099D610 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_ENEMY, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_ENEMY, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 30, 40, 0, { 0, 0, 0 } }, }; -#endif +Vec3f D_8099D63C = { 0.0f, -1300.0f, 1100.0f }; -extern ColliderCylinderInit D_8099D610; +extern AnimationHeader D_060001CC; // gCowBodyChewAnim +extern FlexSkeletonHeader D_06004010; // gCowBodySkel +extern AnimationHeader D_06004264; // gCowBodyMoveHeadAnim +extern AnimationHeader D_06004348; // gCowTailIdleAnim +extern FlexSkeletonHeader D_06004C30; // gCowTailSkel +extern AnimationHeader D_06004E98; // gCowTailSwishAnim -extern UNK_TYPE D_060001CC; -extern UNK_TYPE D_06004010; -extern UNK_TYPE D_06004348; +void EnCow_RotatePoint(Vec3f* vec, s16 angle) { + f32 x = (Math_CosS(angle) * vec->x) + (Math_SinS(angle) * vec->z); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099C290.s") + vec->z = (-Math_SinS(angle) * vec->x) + (Math_CosS(angle) * vec->z); + vec->x = x; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099C328.s") +void EnCow_SetColliderPos(EnCow* this) { + Vec3f vec; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099C41C.s") + vec.x = vec.y = 0.0f; + vec.z = 30.0f; + EnCow_RotatePoint(&vec, this->actor.shape.rot.y); + this->colliders[0].dim.pos.x = this->actor.world.pos.x + vec.x; + this->colliders[0].dim.pos.y = this->actor.world.pos.y; + this->colliders[0].dim.pos.z = this->actor.world.pos.z + vec.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/EnCow_Init.s") + vec.x = vec.y = 0.0f; + vec.z = -20.0f; + EnCow_RotatePoint(&vec, this->actor.shape.rot.y); + this->colliders[1].dim.pos.x = this->actor.world.pos.x + vec.x; + this->colliders[1].dim.pos.y = this->actor.world.pos.y; + this->colliders[1].dim.pos.z = this->actor.world.pos.z + vec.z; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/EnCow_Destroy.s") +void EnCow_SetTailPos(EnCow* this) { + Vec3f vec; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099C880.s") + VEC_SET(vec, 0.0f, 57.0f, -36.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099CAA8.s") + EnCow_RotatePoint(&vec, this->actor.shape.rot.y); + this->actor.world.pos.x += vec.x; + this->actor.world.pos.y += vec.y; + this->actor.world.pos.z += vec.z; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099CB20.s") +void EnCow_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnCow* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099CB68.s") + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 72.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099CBCC.s") + switch (EN_COW_TYPE(thisx)) { + case EN_COW_TYPE_DEFAULT: + case EN_COW_TYPE_ABDUCTED: + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06004010, NULL, this->jointTable, this->morphTable, + COW_LIMB_MAX); + Animation_PlayLoop(&this->skelAnime, &D_060001CC); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099CC68.s") + Collider_InitAndSetCylinder(globalCtx, &this->colliders[0], &this->actor, &sCylinderInit); + Collider_InitAndSetCylinder(globalCtx, &this->colliders[1], &this->actor, &sCylinderInit); + EnCow_SetColliderPos(this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099CCF8.s") + this->actionFunc = EnCow_Idle; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099CDA0.s") + if (!(gSaveContext.weekEventReg[22] & 1) && (CURRENT_DAY != 1) && + (EN_COW_TYPE(thisx) == EN_COW_TYPE_ABDUCTED)) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099CFAC.s") + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_COW, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, this->actor.shape.rot.y, 0, + EN_COW_TYPE_TAIL); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/EnCow_Update.s") + this->animationTimer = Rand_ZeroFloat(1000.0f) + 40.0f; + this->animationCycle = 0; + this->actor.targetMode = 6; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099D3C0.s") + D_801BDAA4 = 0; + func_801A5080(4); + break; + case EN_COW_TYPE_TAIL: + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06004C30, NULL, this->jointTable, this->morphTable, + COW_LIMB_MAX); + Animation_PlayLoop(&this->skelAnime, &D_06004348); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099D4AC.s") + this->actor.update = EnCow_UpdateTail; + this->actor.draw = EnCow_DrawTail; + this->actionFunc = EnCow_DoTail; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099D4FC.s") + EnCow_SetTailPos(this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/EnCow_Draw.s") + this->actor.flags &= ~EN_COW_FLAG_IS_TAIL; + this->animationTimer = Rand_ZeroFloat(1000.0f) + 40.0f; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Cow/func_8099D59C.s") + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + Actor_SetScale(&this->actor, 0.01f); + this->flags = 0; + + gSaveContext.weekEventReg[87] &= (u8)~1; +} + +void EnCow_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnCow* this = THIS; + + if (this->actor.params == EN_COW_TYPE_DEFAULT) { //! @bug EN_COW_TYPE_ABDUCTED do not destroy their cylinders + Collider_DestroyCylinder(globalCtx, &this->colliders[0]); + Collider_DestroyCylinder(globalCtx, &this->colliders[1]); + } +} + +void EnCow_UpdateAnimation(EnCow* this, GlobalContext* globalCtx) { + if (this->animationTimer > 0) { + this->animationTimer--; + } else { + this->animationTimer = Rand_ZeroFloat(500.0f) + 40.0f; + Animation_Change(&this->skelAnime, &D_060001CC, 1.0f, this->skelAnime.curFrame, + Animation_GetLastFrame(&D_060001CC), ANIMMODE_ONCE, 1.0f); + } + if (this->actor.xzDistToPlayer < 150.0f) { + if (!(this->flags & EN_COW_FLAG_PLAYER_HAS_APPROACHED)) { + this->flags |= EN_COW_FLAG_PLAYER_HAS_APPROACHED; + if (this->skelAnime.animation == &D_060001CC) { + this->animationTimer = 0; + } + } + } + this->animationCycle++; + if (this->animationCycle > 0x30) { + this->animationCycle = 0; + } + + if (this->animationCycle < 0x20) { + this->actor.scale.x = ((Math_SinS(this->animationCycle * 0x400) * (1.0f / 100.0f)) + 1.0f) * 0.01f; + } else { + this->actor.scale.x = 0.01f; + } + + if (this->animationCycle > 0x10) { + this->actor.scale.y = ((Math_SinS((this->animationCycle * 0x400) - 0x4000) * (1.0f / 100.0f)) + 1.0f) * 0.01f; + } else { + this->actor.scale.y = 0.01f; + } +} + +void EnCow_TalkEnd(EnCow* this, GlobalContext* globalCtx) { + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + this->actor.flags &= ~0x10000; + func_801477B4(globalCtx); + this->actionFunc = EnCow_Idle; + } +} + +void EnCow_GiveMilkEnd(EnCow* this, GlobalContext* globalCtx) { + if (func_800B867C(&this->actor, globalCtx)) { + this->actor.flags &= ~0x10000; + this->actionFunc = EnCow_Idle; + } +} + +void EnCow_GiveMilkWait(EnCow* this, GlobalContext* globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + this->actionFunc = EnCow_GiveMilkEnd; + } else { + func_800B8A1C(&this->actor, globalCtx, GI_MILK, 10000.0f, 100.0f); + } +} + +void EnCow_GiveMilk(EnCow* this, GlobalContext* globalCtx) { + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + this->actor.flags &= ~0x10000; + func_801477B4(globalCtx); + this->actionFunc = EnCow_GiveMilkWait; + func_800B8A1C(&this->actor, globalCtx, GI_MILK, 10000.0f, 100.0f); + } +} + +void EnCow_CheckForEmptyBottle(EnCow* this, GlobalContext* globalCtx) { + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + if (func_80114E90()) { + func_80151938(globalCtx, 0x32C9); // Text to give milk. + this->actionFunc = EnCow_GiveMilk; + } else { + func_80151938(globalCtx, 0x32CA); // Text if you don't have an empty bottle. + this->actionFunc = EnCow_TalkEnd; + } + } +} + +void EnCow_Talk(EnCow* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + if (this->actor.textId == 0x32C8) { // Text to give milk after playing Epona's Song. + this->actionFunc = EnCow_CheckForEmptyBottle; + } else if (this->actor.textId == 0x32C9) { // Text to give milk. + this->actionFunc = EnCow_GiveMilk; + } else { + this->actionFunc = EnCow_TalkEnd; + } + } else { + this->actor.flags |= 0x10000; + func_800B8614(&this->actor, globalCtx, 170.0f); + this->actor.textId = 0x32C8; //! @bug textId is reset to this no matter the intial value + } + + EnCow_UpdateAnimation(this, globalCtx); +} + +void EnCow_Idle(EnCow* this, GlobalContext* globalCtx) { + if ((globalCtx->msgCtx.unk1202A == 0) || (globalCtx->msgCtx.unk1202A == 4)) { + if (D_801BDAA4 != 0) { + if (this->flags & EN_COW_FLAG_WONT_GIVE_MILK) { + this->flags &= ~EN_COW_FLAG_WONT_GIVE_MILK; + D_801BDAA4 = 0; + } else if ((this->actor.xzDistToPlayer < 150.0f) && + ABS_ALT((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)) < 25000) { + D_801BDAA4 = 0; + this->actionFunc = EnCow_Talk; + this->actor.flags |= 0x10000; + func_800B8614(&this->actor, globalCtx, 170.0f); + this->actor.textId = 0x32C8; // Text to give milk after playing Epona's Song. + + EnCow_UpdateAnimation(this, globalCtx); + return; + } else { + this->flags |= EN_COW_FLAG_WONT_GIVE_MILK; + } + } else { + this->flags &= ~EN_COW_FLAG_WONT_GIVE_MILK; + } + } + + if (this->actor.xzDistToPlayer < 150.0f && + ABS_ALT((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)) < 25000) { + if (func_801A5100() == 4) { + if (!(gSaveContext.weekEventReg[87] & 1)) { + gSaveContext.weekEventReg[87] |= 1; + if (func_80114E90()) { + this->actor.textId = 0x32C9; // Text to give milk. + } else { + this->actor.textId = 0x32CA; // Text if you don't have an empty bottle. + } + this->actor.flags |= 0x10000; + func_800B8614(&this->actor, globalCtx, 170.0f); + this->actionFunc = EnCow_Talk; + } + } else { + gSaveContext.weekEventReg[87] &= (u8)~1; + } + } + + EnCow_UpdateAnimation(this, globalCtx); +} + +void EnCow_DoTail(EnCow* this, GlobalContext* globalCtx) { + if (this->animationTimer > 0) { + this->animationTimer--; + } else { + this->animationTimer = Rand_ZeroFloat(200.0f) + 40.0f; + Animation_Change(&this->skelAnime, &D_06004348, 1.0f, this->skelAnime.curFrame, + Animation_GetLastFrame(&D_06004348), ANIMMODE_ONCE, 1.0f); + } + + if (this->actor.xzDistToPlayer < 150.0f && + ABS_ALT((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)) > 25000) { + if (!(this->flags & EN_COW_FLAG_PLAYER_HAS_APPROACHED)) { + this->flags |= EN_COW_FLAG_PLAYER_HAS_APPROACHED; + if (this->skelAnime.animation == &D_06004348) { + this->animationTimer = 0; + } + } + } +} + +void EnCow_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnCow* this = THIS; + s16 targetX; + s16 targetY; + Player* player = GET_PLAYER(globalCtx); + + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliders[0].base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliders[1].base); + + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); + + if (SkelAnime_Update(&this->skelAnime)) { + if (this->skelAnime.animation == &D_060001CC) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_COW_CRY); + Animation_Change(&this->skelAnime, &D_06004264, 1.0f, 0.0f, Animation_GetLastFrame(&D_06004264), + ANIMMODE_ONCE, 1.0f); + } else { + Animation_Change(&this->skelAnime, &D_060001CC, 1.0f, 0.0f, Animation_GetLastFrame(&D_060001CC), + ANIMMODE_LOOP, 1.0f); + } + } + + this->actionFunc(this, globalCtx); + + if (this->actor.xzDistToPlayer < 150.0f && + ABS_ALT(Math_Vec3f_Yaw(&thisx->world.pos, &player->actor.world.pos)) < 0xC000) { + targetX = Math_Vec3f_Pitch(&thisx->focus.pos, &player->actor.focus.pos); + targetY = Math_Vec3f_Yaw(&thisx->focus.pos, &player->actor.focus.pos) - this->actor.shape.rot.y; + + if (targetX > 0x1000) { + targetX = 0x1000; + } else if (targetX < -0x1000) { + targetX = -0x1000; + } + + if (targetY > 0x2500) { + targetY = 0x2500; + } else if (targetY < -0x2500) { + targetY = -0x2500; + } + } else { + targetX = targetY = 0; + } + + Math_SmoothStepToS(&this->headTilt.x, targetX, 10, 200, 10); + Math_SmoothStepToS(&this->headTilt.y, targetY, 10, 200, 10); +} + +void EnCow_UpdateTail(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnCow* this = THIS; + + if (SkelAnime_Update(&this->skelAnime)) { + if (this->skelAnime.animation == &D_06004348) { + Animation_Change(&this->skelAnime, &D_06004E98, 1.0f, 0.0f, Animation_GetLastFrame(&D_06004E98), + ANIMMODE_ONCE, 1.0f); + } else { + Animation_Change(&this->skelAnime, &D_06004348, 1.0f, 0.0f, Animation_GetLastFrame(&D_06004348), + ANIMMODE_LOOP, 1.0f); + } + } + + this->actionFunc(this, globalCtx); +} + +s32 EnCow_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnCow* this = THIS; + + if (limbIndex == COW_LIMB_HEAD) { + rot->y += this->headTilt.y; + rot->x += this->headTilt.x; + } + if (limbIndex == COW_LIMB_NOSE_RING) { + *dList = NULL; + } + + return false; +} + +void EnCow_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnCow* this = THIS; + + if (limbIndex == COW_LIMB_HEAD) { + Matrix_MultiplyVector3fByState(&D_8099D63C, &this->actor.focus.pos); + } +} + +void EnCow_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnCow* this = THIS; + + func_8012C5B0(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnCow_OverrideLimbDraw, EnCow_PostLimbDraw, &this->actor); +} + +void EnCow_DrawTail(Actor* thisx, GlobalContext* globalCtx) { + EnCow* this = THIS; + + func_8012C5B0(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + NULL, NULL, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Cow/z_en_cow.h b/src/overlays/actors/ovl_En_Cow/z_en_cow.h index ecbd3a9e1..fd865cecb 100644 --- a/src/overlays/actors/ovl_En_Cow/z_en_cow.h +++ b/src/overlays/actors/ovl_En_Cow/z_en_cow.h @@ -3,13 +3,42 @@ #include "global.h" +#define EN_COW_TYPE(thisx) ((thisx)->params & 0xF) + +#define EN_COW_FLAG_IS_TAIL (1 << 0) // This is never set but it is cleared for tail types +#define EN_COW_FLAG_PLAYER_HAS_APPROACHED (1 << 1) +#define EN_COW_FLAG_WONT_GIVE_MILK (1 << 2) + +typedef enum { + /* 0 */ EN_COW_TYPE_DEFAULT, + /* 1 */ EN_COW_TYPE_TAIL, + /* 2 */ EN_COW_TYPE_ABDUCTED, +} EnCowType; + struct EnCow; typedef void (*EnCowActionFunc)(struct EnCow*, GlobalContext*); +typedef enum { + /* 0 */ COW_LIMB_NONE, + /* 1 */ COW_LIMB_ROOT, + /* 2 */ COW_LIMB_HEAD, + /* 3 */ COW_LIMB_JAW, + /* 4 */ COW_LIMB_NOSE, + /* 5 */ COW_LIMB_NOSE_RING, + /* 6 */ COW_LIMB_MAX, +} ObjectCowLimbs; + typedef struct EnCow { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x130]; + /* 0x0144 */ ColliderCylinder colliders[2]; + /* 0x01DC */ SkelAnime skelAnime; + /* 0x0220 */ Vec3s jointTable[COW_LIMB_MAX]; + /* 0x0244 */ Vec3s morphTable[COW_LIMB_MAX]; + /* 0x0268 */ Vec3s headTilt; + /* 0x026E */ u16 flags; + /* 0x0270 */ u16 animationTimer; + /* 0x0272 */ u16 animationCycle; /* 0x0274 */ EnCowActionFunc actionFunc; } EnCow; // size = 0x278 diff --git a/src/overlays/actors/ovl_En_Crow/z_en_crow.c b/src/overlays/actors/ovl_En_Crow/z_en_crow.c index b4dead243..be24037bf 100644 --- a/src/overlays/actors/ovl_En_Crow/z_en_crow.c +++ b/src/overlays/actors/ovl_En_Crow/z_en_crow.c @@ -1,5 +1,5 @@ /* - * File z_en_crow.c + * File: z_en_crow.c * Overlay: ovl_En_Crow * Description: Guay */ diff --git a/src/overlays/actors/ovl_En_Dai/z_en_dai.c b/src/overlays/actors/ovl_En_Dai/z_en_dai.c index fb917742c..b84feb51a 100644 --- a/src/overlays/actors/ovl_En_Dai/z_en_dai.c +++ b/src/overlays/actors/ovl_En_Dai/z_en_dai.c @@ -103,7 +103,7 @@ void func_80B3E168(EnDaiParticle* particle, GlobalContext* globalCtx2) { (particle->unk_02 + (i * 3)) * 15, 0x20, 0x40, 1, 0, 0, 0x20, 0x20)); Matrix_InsertTranslation(particle->unk_10.x, particle->unk_10.y, particle->unk_10.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(particle->unk_34, particle->unk_34, 1.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), @@ -591,7 +591,7 @@ s32 func_80B3F598(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p } if (limbIndex == 11) { - Matrix_MultiplyVector3fByState(&D_801D15B0, &this->unk_1E4); + Matrix_MultiplyVector3fByState(&gZeroVec3f, &this->unk_1E4); } if (limbIndex == 10) { diff --git a/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c b/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c index 413dbdac6..40eac8099 100644 --- a/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c +++ b/src/overlays/actors/ovl_En_Daiku/z_en_daiku.c @@ -184,7 +184,7 @@ void func_809438F8(EnDaiku* this, GlobalContext* globalCtx) { s32 day = gSaveContext.day - 1; s32 pad2; - if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEI) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEIS_MASK) { if (this->unk_278 == ENDAIKU_PARAMS_FF_1) { this->actor.textId = 0x2365; } else { diff --git a/src/overlays/actors/ovl_En_Death/z_en_death.c b/src/overlays/actors/ovl_En_Death/z_en_death.c index e47822ed8..ec6d57bbf 100644 --- a/src/overlays/actors/ovl_En_Death/z_en_death.c +++ b/src/overlays/actors/ovl_En_Death/z_en_death.c @@ -1,5 +1,5 @@ /* - * File z_en_death.c + * File: z_en_death.c * Overlay: ovl_En_Death * Description: Gomess */ diff --git a/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c b/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c index 421495be7..288ce89a3 100644 --- a/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c +++ b/src/overlays/actors/ovl_En_Dekubaba/z_en_dekubaba.c @@ -1,5 +1,5 @@ /* - * File z_en_dekubaba.c + * File: z_en_dekubaba.c * Overlay: ovl_En_Dekubaba * Description: Deku Baba */ diff --git a/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c b/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c index 1ab2c9654..69d2fc9d6 100644 --- a/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c +++ b/src/overlays/actors/ovl_En_Dekunuts/z_en_dekunuts.c @@ -547,7 +547,7 @@ void func_808BE4D4(EnDekunuts* this, GlobalContext* globalCtx) { sp40.x = this->actor.world.pos.x; sp40.y = this->actor.world.pos.y + 18.0f; sp40.z = this->actor.world.pos.z; - EffectSsDeadDb_Spawn(globalCtx, &sp40, &D_801D15B0, &D_801D15B0, &D_808BEF90, &D_808BEF94, 200, 0, 13); + EffectSsDeadDb_Spawn(globalCtx, &sp40, &gZeroVec3f, &gZeroVec3f, &D_808BEF90, &D_808BEF94, 200, 0, 13); Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 11, NA_SE_EN_EXTINCT); sp40.y = this->actor.world.pos.y + 10.0f; EffectSsHahen_SpawnBurst(globalCtx, &sp40, 3.0f, 0, 12, 3, 15, HAHEN_OBJECT_DEFAULT, 10, NULL); diff --git a/src/overlays/actors/ovl_En_Demo_heishi/z_en_demo_heishi.c b/src/overlays/actors/ovl_En_Demo_heishi/z_en_demo_heishi.c index a1cda6362..b7e160990 100644 --- a/src/overlays/actors/ovl_En_Demo_heishi/z_en_demo_heishi.c +++ b/src/overlays/actors/ovl_En_Demo_heishi/z_en_demo_heishi.c @@ -1,5 +1,5 @@ /* - * File z_en_demo_heishi.c + * File: z_en_demo_heishi.c * Overlay: ovl_En_Demo_heishi * Description: Unused(?) version of Shiro */ diff --git a/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.c b/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.c index bf0f977b7..f82295874 100644 --- a/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.c +++ b/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.c @@ -278,7 +278,7 @@ static InitChainEntry sInitChain[] = { void EnDinofos_Init(Actor* thisx, GlobalContext* globalCtx) { static s32 D_8089E364 = 0; - static EffBlureInit2 D_8089E368 = { + static EffectBlureInit2 D_8089E368 = { 0, 8, 0, { 255, 255, 255, 255 }, { 255, 255, 255, 64 }, { 255, 255, 255, 0 }, { 255, 255, 255, 0 }, 8, 0, 2, 0, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, }; @@ -288,7 +288,7 @@ void EnDinofos_Init(Actor* thisx, GlobalContext* globalCtx) { Actor_ProcessInitChain(&this->actor, sInitChain); ActorShape_Init(&this->actor.shape, 0.0f, func_800B42F8, 90.0f); - Effect_Add(globalCtx, &this->unk_2A0, 2, 0, 0, &D_8089E368); + Effect_Add(globalCtx, &this->unk_2A0, EFFECT_BLURE2, 0, 0, &D_8089E368); Collider_InitAndSetJntSph(globalCtx, &this->colliderJntSph, &this->actor, &sJntSphInit, this->colliderJntSphElement); Collider_InitAndSetQuad(globalCtx, &this->colliderQuad, &this->actor, &sQuadInit); @@ -936,7 +936,7 @@ void func_8089C56C(EnDinofos* this, GlobalContext* globalCtx) { Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0x800); this->actor.world.rot.y = this->actor.shape.rot.y; if (SkelAnime_Update(&this->skelAnime)) { - func_800A8514(Effect_GetParams(this->unk_2A0)); + EffectBlure_AddSpace(Effect_GetByIndex(this->unk_2A0)); this->colliderQuad.base.atFlags &= ~AT_ON; func_8089A9B0(this, globalCtx); } else if (Animation_OnFrame(&this->skelAnime, 7.0f)) { @@ -1454,7 +1454,7 @@ void func_8089DC84(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* Matrix_MultiplyVector3fByState(&D_8089E398, &sp5C); Collider_SetQuadVertices(&this->colliderQuad, &sp5C, &sp68, &sp74, &sp80); if (this->colliderQuad.base.atFlags & AT_ON) { - func_800A81F0(Effect_GetParams(this->unk_2A0), &sp68, &sp5C); + EffectBlure_AddVertex(Effect_GetByIndex(this->unk_2A0), &sp68, &sp5C); } this->unk_292 = this->unk_290; } @@ -1475,7 +1475,7 @@ void func_8089DC84(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* sp4C.x -= sp48->mf[3][0]; sp4C.y -= sp48->mf[3][1]; sp4C.z -= sp48->mf[3][2]; - EffectSsDFire_Spawn(globalCtx, &this->unk_34C, &sp4C, &D_801D15B0, 30, 22, 255 - (sp58 * 20), 20, 3, 8); + EffectSsDFire_Spawn(globalCtx, &this->unk_34C, &sp4C, &gZeroVec3f, 30, 22, 255 - (sp58 * 20), 20, 3, 8); this->unk_292 = this->unk_290; } } diff --git a/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.h b/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.h index 4ed2a76ab..e6a00853e 100644 --- a/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.h +++ b/src/overlays/actors/ovl_En_Dinofos/z_en_dinofos.h @@ -20,7 +20,7 @@ typedef struct EnDinofos { /* 0x28C */ s16 unk_28C; /* 0x28E */ s16 unk_28E; /* 0x290 */ s16 unk_290; - /* 0x290 */ s16 unk_292; + /* 0x292 */ s16 unk_292; /* 0x294 */ UNK_TYPE1 unk_294[4]; /* 0x298 */ s16 camId; /* 0x29A */ Vec3s unk_29A; diff --git a/src/overlays/actors/ovl_En_Dnb/z_en_dnb.c b/src/overlays/actors/ovl_En_Dnb/z_en_dnb.c index a2804c0a8..7e4b67b7c 100644 --- a/src/overlays/actors/ovl_En_Dnb/z_en_dnb.c +++ b/src/overlays/actors/ovl_En_Dnb/z_en_dnb.c @@ -1,7 +1,7 @@ /* * File: z_en_dnb.c * Overlay: ovl_En_Dnb - * Description: + * Description: Unused invisible snowy mountain that explodes? */ #include "z_en_dnb.h" @@ -47,7 +47,7 @@ void func_80A4FDD0(EnDnbParticle* particle, EnDnb* this, s16* alloc, s32 idx) { particle->unk_00 = sp1C; particle->unk_0C = sp1C; particle->unk_24 = Math_Vec3f_Yaw(&this->dyna.actor.world.pos, &sp1C); - particle->unk_18 = D_801D15BC; + particle->unk_18 = gZeroVec3s; } s32 func_80A4FEBC(EnDnbParticle* particle, f32 arg1) { @@ -76,7 +76,7 @@ void func_80A4FFE8(EnDnbParticle* particle, s16 arg1) { particle->unk_1E.x = (Rand_ZeroOne() - 0.5f) * 400.0f; particle->unk_1E.y = (Rand_ZeroOne() - 0.5f) * 400.0f; particle->unk_1E.z = (Rand_ZeroOne() - 0.5f) * 400.0f; - particle->unk_18 = D_801D15BC; + particle->unk_18 = gZeroVec3s; particle->unk_30 = 40.0f; particle->unk_2C = 0.0f; particle->unk_26 = arg1; @@ -86,7 +86,7 @@ void func_80A4FFE8(EnDnbParticle* particle, s16 arg1) { s32 func_80A500F8(EnDnb* this) { static Vec3f D_80A50CB0 = { 0.0f, 0.0f, 1000.0f }; Actor* actor = &this->dyna.actor; - Vec3f spA8 = D_801D15B0; + Vec3f spA8 = gZeroVec3f; Vec3f sp9C; s32 i; f32 temp_f20; @@ -288,7 +288,7 @@ s32 func_80A50950(EnDnbUnkStruct* arg0, GlobalContext* globalCtx2) { Matrix_InsertTranslation(arg0->unk_0C.x, arg0->unk_0C.y, arg0->unk_0C.z, MTXMODE_NEW); Matrix_Scale(arg0->unk_04, arg0->unk_04, 1.0f, MTXMODE_APPLY); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); diff --git a/src/overlays/actors/ovl_En_Dnh/z_en_dnh.h b/src/overlays/actors/ovl_En_Dnh/z_en_dnh.h index 9edb339d4..21336aa91 100644 --- a/src/overlays/actors/ovl_En_Dnh/z_en_dnh.h +++ b/src/overlays/actors/ovl_En_Dnh/z_en_dnh.h @@ -10,7 +10,7 @@ typedef void (*EnDnhActionFunc)(struct EnDnh*, GlobalContext*); typedef struct EnDnh { /* 0x0000 */ Actor actor; /* 0x0144 */ EnDnhActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x74]; + /* 0x0148 */ char unk_148[0x74]; } EnDnh; // size = 0x1BC extern const ActorInit En_Dnh_InitVars; diff --git a/src/overlays/actors/ovl_En_Dnk/z_en_dnk.c b/src/overlays/actors/ovl_En_Dnk/z_en_dnk.c index 7fd5c84b8..8a6c3a583 100644 --- a/src/overlays/actors/ovl_En_Dnk/z_en_dnk.c +++ b/src/overlays/actors/ovl_En_Dnk/z_en_dnk.c @@ -283,7 +283,7 @@ s32 func_80A51A78(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p void func_80A51AA4(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { EnDnk* this = THIS; MtxF sp5C; - Vec3f sp50 = D_801D15B0; + Vec3f sp50 = gZeroVec3f; Vec3f sp44; Vec3s sp3C; @@ -359,7 +359,7 @@ s32 func_80A51D78(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* p void func_80A51DA4(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { EnDnk* this = THIS; MtxF sp5C; - Vec3f sp50 = D_801D15B0; + Vec3f sp50 = gZeroVec3f; Vec3f sp44; Vec3s sp3C; diff --git a/src/overlays/actors/ovl_En_Dno/z_en_dno.c b/src/overlays/actors/ovl_En_Dno/z_en_dno.c index 3fe0b0299..6b03849ae 100644 --- a/src/overlays/actors/ovl_En_Dno/z_en_dno.c +++ b/src/overlays/actors/ovl_En_Dno/z_en_dno.c @@ -6,6 +6,7 @@ #include "z_en_dno.h" #include "overlays/actors/ovl_Bg_Crace_Movebg/z_bg_crace_movebg.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x00000039 @@ -134,9 +135,9 @@ void func_80A714B4(EnDno* this, GlobalContext* globalCtx) { Actor* actor = NULL; do { - actor = func_ActorCategoryIterateById(globalCtx, actor, ACTORCAT_BG, ACTOR_BG_CRACE_MOVEBG); + actor = SubS_FindActor(globalCtx, actor, ACTORCAT_BG, ACTOR_BG_CRACE_MOVEBG); if (actor != NULL) { - if (ENDNO_GET_F(actor) == ENDNO_GET_F_1) { + if ((s32)ENDNO_GET_F(actor) == ENDNO_GET_F_1) { Actor_SetSwitchFlag(globalCtx, ENDNO_GET_7F0(actor)); } actor = actor->next; @@ -164,14 +165,13 @@ void func_80A715DC(EnDno* this, GlobalContext* globalCtx) { Vec3f sp70; do { - crace = - (BgCraceMovebg*)func_ActorCategoryIterateById(globalCtx, &crace->actor, ACTORCAT_BG, ACTOR_BG_CRACE_MOVEBG); + crace = (BgCraceMovebg*)SubS_FindActor(globalCtx, &crace->actor, ACTORCAT_BG, ACTOR_BG_CRACE_MOVEBG); if (crace != NULL) { if (ENDNO_GET_F(&crace->actor) == ENDNO_GET_F_0 && !(crace->unk_170 & 1)) { if (func_8013E5CC(&crace->actor.home.pos, &crace->actor.home.rot, &D_80A73B2C, &this->actor.prevPos, &this->actor.world.pos, &sp88)) { Math_Vec3f_Diff(&this->actor.world.pos, &crace->actor.home.pos, &sp7C); - Matrix_RotateY(-crace->actor.home.rot.y, 0); + Matrix_RotateY(-crace->actor.home.rot.y, MTXMODE_NEW); Matrix_MultiplyVector3fByState(&sp7C, &sp70); if ((fabsf(sp70.x) < 100.0f) && (sp70.y >= -10.0f) && (sp70.y <= 180.0f) && (sp70.z < 0.0f)) { crace->unk_170 |= 1; @@ -187,7 +187,7 @@ void func_80A71788(EnDno* this, GlobalContext* globalCtx) { Actor* actor = NULL; do { - actor = func_ActorCategoryIterateById(globalCtx, actor, ACTORCAT_BG, ACTOR_BG_CRACE_MOVEBG); + actor = SubS_FindActor(globalCtx, actor, ACTORCAT_BG, ACTOR_BG_CRACE_MOVEBG); if (actor != NULL) { Actor_UnsetSwitchFlag(globalCtx, ENDNO_GET_7F0(actor)); actor = actor->next; @@ -201,7 +201,7 @@ void EnDno_Init(Actor* thisx, GlobalContext* globalCtx) { Actor* actor = NULL; while (true) { - actor = func_ActorCategoryIterateById(globalCtx, actor, ACTORCAT_NPC, ACTOR_EN_DNO); + actor = SubS_FindActor(globalCtx, actor, ACTORCAT_NPC, ACTOR_EN_DNO); if (actor != NULL) { if (actor != thisx) { Actor_MarkForDeath(thisx); @@ -248,7 +248,7 @@ void EnDno_Init(Actor* thisx, GlobalContext* globalCtx) { Actor_MarkForDeath(thisx); } else { func_8013E1C8(&this->skelAnime, sAnimations, 13, &this->unk_32C); - this->unk_460 = func_ActorCategoryIterateById(globalCtx, NULL, ACTORCAT_NPC, ACTOR_EN_DNQ); + this->unk_460 = SubS_FindActor(globalCtx, NULL, ACTORCAT_NPC, ACTOR_EN_DNQ); if (this->unk_460 == NULL) { Actor_MarkForDeath(thisx); } else { @@ -985,7 +985,7 @@ void EnDno_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve func_8012C28C(globalCtx->state.gfxCtx); if (limbIndex == 13) { Matrix_Scale(this->unk_454, this->unk_454, this->unk_454, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->unk_45C, 1); + Matrix_InsertXRotation_s(this->unk_45C, MTXMODE_APPLY); } gfxOpa = POLY_OPA_DISP; @@ -1005,7 +1005,7 @@ void EnDno_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve frames = globalCtx->gameplayFrames; Matrix_MultiplyVector3fByState(&D_80A73B40, &sp84); func_80A711D0(this, globalCtx, &sp84); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(0.15f, 0.15f, 1.0f, MTXMODE_APPLY); Matrix_InsertTranslation(0.0f, -3200.0f, 0.0f, MTXMODE_APPLY); gfxXlu = func_8012C2B4(POLY_XLU_DISP); @@ -1015,7 +1015,7 @@ void EnDno_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, -frames * 20, 0x20, 0x80)); gDPSetPrimColor(&gfxXlu[2], 0x80, 0x80, 255, 255, 0, 255); gDPSetEnvColor(&gfxXlu[3], 255, 0, 0, 0); - gSPDisplayList(&gfxXlu[4], D_0407D590); + gSPDisplayList(&gfxXlu[4], gGameplayKeepDrawFlameDL); POLY_XLU_DISP = gfxXlu + 5; diff --git a/src/overlays/actors/ovl_En_Dnp/z_en_dnp.c b/src/overlays/actors/ovl_En_Dnp/z_en_dnp.c index 8e0bbbaab..f3753c978 100644 --- a/src/overlays/actors/ovl_En_Dnp/z_en_dnp.c +++ b/src/overlays/actors/ovl_En_Dnp/z_en_dnp.c @@ -435,7 +435,7 @@ s32 func_80B3D974(s16 arg0, s16 arg1, Vec3f* arg2, Vec3s* arg3, s32 arg4, s32 ar Vec3s sp6C; MtxF sp2C; - Matrix_MultiplyVector3fByState(&D_801D15B0, &sp74); + Matrix_MultiplyVector3fByState(&gZeroVec3f, &sp74); Matrix_CopyCurrentState(&sp2C); func_8018219C(&sp2C, &sp6C, 0); *arg2 = sp74; diff --git a/src/overlays/actors/ovl_En_Dns/z_en_dns.c b/src/overlays/actors/ovl_En_Dns/z_en_dns.c index e75f1aa46..97db5bcb6 100644 --- a/src/overlays/actors/ovl_En_Dns/z_en_dns.c +++ b/src/overlays/actors/ovl_En_Dns/z_en_dns.c @@ -284,11 +284,11 @@ s32 func_8092CCEC(EnDns* this, GlobalContext* globalCtx) { Math_Vec3f_Copy(&sp30, &this->actor.world.pos); Math_Vec3f_Copy(&sp3C, &player->actor.world.pos); - this->unk_2D6 = Math_Vec3f_Yaw(&D_801D15B0, &sp3C); - this->unk_2D4 = Math_Vec3f_Yaw(&D_801D15B0, &sp30); - this->unk_2EC = Math_Vec3f_DistXZ(&sp30, &D_801D15B0); - sp2E = Math_Vec3f_Yaw(&D_801D15B0, &sp3C); - sp2E -= Math_Vec3f_Yaw(&D_801D15B0, &sp30); + this->unk_2D6 = Math_Vec3f_Yaw(&gZeroVec3f, &sp3C); + this->unk_2D4 = Math_Vec3f_Yaw(&gZeroVec3f, &sp30); + this->unk_2EC = Math_Vec3f_DistXZ(&sp30, &gZeroVec3f); + sp2E = Math_Vec3f_Yaw(&gZeroVec3f, &sp3C); + sp2E -= Math_Vec3f_Yaw(&gZeroVec3f, &sp30); this->unk_2D8 = (Rand_ZeroOne() * 182.0f) + 182.0f; this->unk_2D8 = (sp2E > 0) ? this->unk_2D8 : -this->unk_2D8; this->unk_2D0 = 0x28; @@ -413,7 +413,7 @@ void EnDns_DoNothing(EnDns* this, GlobalContext* globalCtx) { void func_8092D330(EnDns* this, GlobalContext* globalCtx) { s32 pad; - Vec3f sp30 = D_801D15B0; + Vec3f sp30 = gZeroVec3f; s16 temp = this->unk_2D6 - this->unk_2D4; if (ABS_ALT(temp) < 0xC16) { @@ -549,7 +549,7 @@ s32 func_8092D954(s16 arg0, s16 arg1, Vec3f* arg2, Vec3s* arg3, s32 arg4, s32 ar Vec3s sp6C; MtxF sp2C; - Matrix_MultiplyVector3fByState(&D_801D15B0, &sp74); + Matrix_MultiplyVector3fByState(&gZeroVec3f, &sp74); Matrix_CopyCurrentState(&sp2C); func_8018219C(&sp2C, &sp6C, 0); *arg2 = sp74; diff --git a/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c b/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c index 693ea4ec4..fe92a5b1f 100644 --- a/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c +++ b/src/overlays/actors/ovl_En_Dodongo/z_en_dodongo.c @@ -288,7 +288,7 @@ static InitChainEntry sInitChain[] = { }; void EnDodongo_Init(Actor* thisx, GlobalContext* globalCtx) { - static EffBlureInit2 D_80879308 = { + static EffectBlureInit2 D_80879308 = { 2, 8, 0, { 255, 255, 255, 255 }, { 255, 255, 255, 64 }, { 255, 255, 255, 0 }, { 255, 255, 255, 0 }, 8, 0, 0, 0, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, }; @@ -315,7 +315,7 @@ void EnDodongo_Init(Actor* thisx, GlobalContext* globalCtx) { this->collider2.elements[i].info.bumper.dmgFlags = 0x77C34FE6; } - Effect_Add(globalCtx, &this->unk_338, 2, 0, 0, &D_80879308); + Effect_Add(globalCtx, &this->unk_338, EFFECT_BLURE2, 0, 0, &D_80879308); if (this->actor.params == 0) { Actor_SetScale(&this->actor, 3.0f / 160.0f); this->unk_334 = 1.0f; @@ -384,7 +384,7 @@ void func_80876930(EnDodongo* this, GlobalContext* globalCtx, Vec3f* arg2) { sp88.z = randPlusMinusPoint5Scaled(temp3) + arg2->z; D_8087933C.x = randPlusMinusPoint5Scaled(2.0f); D_8087933C.z = randPlusMinusPoint5Scaled(2.0f); - func_800B0DE0(globalCtx, &sp88, &D_801D15B0, &D_8087933C, sp80, sp7C, temp1, temp2); + func_800B0DE0(globalCtx, &sp88, &gZeroVec3f, &D_8087933C, sp80, sp7C, temp1, temp2); } } @@ -780,13 +780,13 @@ void func_80877E60(EnDodongo* this, GlobalContext* globalCtx) { sp5E = this->unk_334 * 50.0f; sp5C = this->unk_334 * 5.0f; Math_Vec3f_Copy(&sp64, &this->unk_348[0]); - func_800B0DE0(globalCtx, &sp64, &D_801D15B0, &D_80879360, &D_8087936C, &D_8087936C, sp5E, sp5C); + func_800B0DE0(globalCtx, &sp64, &gZeroVec3f, &D_80879360, &D_8087936C, &D_8087936C, sp5E, sp5C); sp64.x -= Math_CosS(this->actor.shape.rot.y) * 6.0f * this->unk_334; sp64.z += Math_SinS(this->actor.shape.rot.y) * 6.0f * this->unk_334; - func_800B0DE0(globalCtx, &sp64, &D_801D15B0, &D_80879360, &D_8087936C, &D_8087936C, sp5E, sp5C); + func_800B0DE0(globalCtx, &sp64, &gZeroVec3f, &D_80879360, &D_8087936C, &D_8087936C, sp5E, sp5C); sp64.x = (2.0f * this->unk_348[0].x) - sp64.x; sp64.z = (2.0f * this->unk_348[0].z) - sp64.z; - func_800B0DE0(globalCtx, &sp64, &D_801D15B0, &D_80879360, &D_8087936C, &D_8087936C, sp5E, sp5C); + func_800B0DE0(globalCtx, &sp64, &gZeroVec3f, &D_80879360, &D_8087936C, &D_8087936C, sp5E, sp5C); } } @@ -1099,7 +1099,7 @@ void EnDodongo_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList } if ((limbIndex == 30) && (this->actionFunc == func_80878424) && (this->timer != this->unk_304)) { - func_800A81F0(Effect_GetParams(this->unk_338), &this->unk_320, &this->unk_348[4]); + EffectBlure_AddVertex(Effect_GetByIndex(this->unk_338), &this->unk_320, &this->unk_348[4]); this->unk_304 = this->timer; } } diff --git a/src/overlays/actors/ovl_En_Door/z_en_door.h b/src/overlays/actors/ovl_En_Door/z_en_door.h index 1dbc470dc..6ed5aac15 100644 --- a/src/overlays/actors/ovl_En_Door/z_en_door.h +++ b/src/overlays/actors/ovl_En_Door/z_en_door.h @@ -8,11 +8,17 @@ struct EnDoor; typedef void (*EnDoorActionFunc)(struct EnDoor*, GlobalContext*); typedef struct EnDoor { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x63]; - /* 0x01A7 */ s8 unk_1A7; - /* 0x01A8 */ char unk_1A8[0x20]; - /* 0x01C8 */ EnDoorActionFunc actionFunc; + /* 0x000 */ Actor actor; + /* 0x144 */ char unk_144[0x5C]; + /* 0x1A0 */ s8 unk_1A0; + /* 0x1A1 */ s8 unk_1A1; + /* 0x1A2 */ char unk_1A2[0x2]; + /* 0x1A4 */ u8 unk_1A4; + /* 0x1A5 */ u8 unk_1A5; + /* 0x1A6 */ s8 unk_1A6; + /* 0x1A7 */ s8 unk_1A7; + /* 0x1A8 */ char unk_1A8[0x20]; + /* 0x1C8 */ EnDoorActionFunc actionFunc; } EnDoor; // size = 0x1CC extern const ActorInit En_Door_InitVars; diff --git a/src/overlays/actors/ovl_En_Ds2n/z_en_ds2n.c b/src/overlays/actors/ovl_En_Ds2n/z_en_ds2n.c index ab0c54888..1ca8d69fc 100644 --- a/src/overlays/actors/ovl_En_Ds2n/z_en_ds2n.c +++ b/src/overlays/actors/ovl_En_Ds2n/z_en_ds2n.c @@ -1,7 +1,7 @@ /* * File: z_en_ds2n.c * Overlay: ovl_En_Ds2n - * Description: + * Description: Potion Shop Owner from OoT (unused) */ #include "z_en_ds2n.h" diff --git a/src/overlays/actors/ovl_En_Elf/z_en_elf.c b/src/overlays/actors/ovl_En_Elf/z_en_elf.c index 1af159e0b..112892a38 100644 --- a/src/overlays/actors/ovl_En_Elf/z_en_elf.c +++ b/src/overlays/actors/ovl_En_Elf/z_en_elf.c @@ -15,16 +15,25 @@ void EnElf_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnElf_Update(Actor* thisx, GlobalContext* globalCtx); void EnElf_Draw(Actor* thisx, GlobalContext* globalCtx); +void EnElf_SetupAction(EnElf* this, EnElfActionFunc actionFunc); +void func_8088C9CC(EnElf* this, GlobalContext* globalCtx); +void func_8088D3EC(EnElf* this, GlobalContext* globalCtx); +void func_8088D470(EnElf* this, GlobalContext* globalCtx); +void func_8088D504(EnElf* this, GlobalContext* globalCtx); void func_8088DD34(EnElf* this, GlobalContext* globalCtx); void func_8088E018(EnElf* this, GlobalContext* globalCtx); void func_8088E0E0(EnElf* this, GlobalContext* globalCtx); void func_8088E0F0(EnElf* this, GlobalContext* globalCtx); void func_8088E484(EnElf* this, GlobalContext* globalCtx); void func_8088E850(EnElf* this, GlobalContext* globalCtx); +void func_8088EFA4(EnElf* this, GlobalContext* globalCtx); +void func_8088F214(EnElf* this, GlobalContext* globalCtx); +void func_8088F5F4(EnElf* this, GlobalContext* globalCtx, s32 arg2); +void func_8089010C(Actor* thisx, GlobalContext* globalCtx); +void func_808908D0(Vec3f* arg0, GlobalContext* globalCtx, u32 arg2); -void EnElf_SetupAction(EnElf* this, EnElfActionFunc actionFunc); +extern SkeletonHeader D_0402AF58; -#if 0 const ActorInit En_Elf_InitVars = { ACTOR_EN_ELF, ACTORCAT_ITEMACTION, @@ -37,96 +46,1592 @@ const ActorInit En_Elf_InitVars = { (ActorFunc)EnElf_Draw, }; -#endif +static InitChainEntry sInitChain[] = { + ICHAIN_VEC3F_DIV1000(scale, 8, ICHAIN_STOP), +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/EnElf_SetupAction.s") +static Color_RGBAf sInnerColors[] = { + { 255.0f, 255.0f, 230.0f, 255.0f }, + { 255.0f, 220.0f, 220.0f, 255.0f }, + { 255.0f, 235.0f, 220.0f, 255.0f }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088C51C.s") +static Color_RGBAf sOuterColors[] = { + { 220.0f, 160.0f, 80.0f, 255.0f }, + { 255.0f, 50.0f, 100.0f, 255.0f }, + { 255.0f, 150.0f, 0.0f, 255.0f }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088C804.s") +typedef struct { + u8 r, g, b; +} FairyColorFlags; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088C858.s") +static FairyColorFlags sColorFlags[] = { + { 0, 0, 0 }, { 1, 0, 0 }, { 1, 2, 0 }, { 1, 0, 2 }, { 0, 1, 0 }, { 2, 1, 0 }, { 0, 1, 2 }, + { 0, 0, 1 }, { 2, 0, 1 }, { 0, 2, 1 }, { 1, 1, 0 }, { 1, 0, 1 }, { 0, 1, 1 }, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088C920.s") +void EnElf_SetupAction(EnElf* this, EnElfActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088C9CC.s") +void func_8088C51C(EnElf* this, s32 arg1) { + this->unk_244 = arg1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088CBAC.s") + switch (this->unk_244) { + case 0: + this->unk_24A = 0x400; + this->unk_24C = 0x200; + this->unk_26C = func_8088D3EC; + this->unk_25C = 0x64; + this->skelAnime.playSpeed = 1.0f; + this->unk_250 = 5.0f; + this->unk_254 = 20.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088CC48.s") + case 10: + this->unk_24A = 0x400; + this->unk_24C = 0x200; + this->unk_26C = func_8088D3EC; + this->unk_25C = 0x64; + this->unk_250 = 1.0f; + this->skelAnime.playSpeed = 1.0f; + this->unk_254 = 5.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088CD3C.s") + case 8: + this->unk_24A = 0x400; + this->unk_24C = 0; + this->unk_26C = func_8088D3EC; + this->skelAnime.playSpeed = 1.0f; + this->unk_254 = 0.0f; + this->unk_250 = 5.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/EnElf_Init.s") + case 7: + this->unk_24A = 0x1000; + this->unk_24C = 0x200; + this->unk_26C = func_8088D3EC; + this->skelAnime.playSpeed = 1.0f; + this->unk_250 = 3.0f; + this->unk_254 = 10.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/EnElf_Destroy.s") + case 5: + this->unk_26C = func_8088D3EC; + this->unk_24A = 0x1E; + this->unk_25C = 1; + this->unk_250 = 0.0f; + this->unk_254 = 0.0f; + this->skelAnime.playSpeed = 1.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088D3EC.s") + case 6: + this->unk_24A = 0x1000; + this->unk_24C = 0x200; + this->unk_26C = func_8088D3EC; + this->unk_250 = 0.0f; + this->unk_254 = 0.0f; + this->skelAnime.playSpeed = 1.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088D470.s") + case 1: + this->unk_24A = 0x1000; + this->unk_24C = 0x800; + this->unk_26C = func_8088D3EC; + this->unk_250 = 5.0f; + this->unk_254 = 7.5f; + this->skelAnime.playSpeed = 2.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088D504.s") + case 2: + this->unk_24A = 0x400; + this->unk_24C = 0x1000; + this->unk_26C = func_8088D470; + this->skelAnime.playSpeed = 1.0f; + this->unk_250 = 10.0f; + this->unk_254 = 20.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088D5A0.s") + case 3: + this->unk_24C = 0x600; + this->unk_26C = func_8088D504; + this->unk_254 = 1.0f; + this->unk_250 = 1.0f; + this->skelAnime.playSpeed = 1.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088D660.s") + case 4: + this->unk_24A = 0x1000; + this->unk_24C = 0x800; + this->unk_26C = func_8088D3EC; + this->unk_250 = 60.0f; + this->unk_254 = 20.0f; + this->skelAnime.playSpeed = 2.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088D7F8.s") + case 9: + this->unk_24A = 0x400; + this->unk_24C = 0x2000; + this->unk_26C = func_8088D3EC; + this->unk_25C = 0x2A; + this->unk_254 = 1.0f; + this->skelAnime.playSpeed = 1.0f; + this->unk_250 = 5.0f; + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088D864.s") +s32 func_8088C804(Vec3f* arg0, Vec3f* arg1, f32 arg2) { + return SQ(arg2) < SQ(arg1->x - arg0->x) + SQ(arg1->z - arg0->z); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088D8D0.s") +void func_8088C858(EnElf* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088D9BC.s") + if (!func_8088C804(&this->actor.world.pos, &player->actor.world.pos, 30.0f)) { + this->unk_254 = 0.5f; + } else { + this->unk_254 = 2.0f; + } + if (this->unk_25C > 0) { + this->unk_25C--; + } else { + this->unk_244 = 1; + this->unk_248 = 128; + this->unk_254 = Rand_ZeroFloat(1.0f) + 0.5f; + this->unk_24C = randPlusMinusPoint5Scaled(0x7FFF); + this->unk_26C = func_8088C9CC; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088DB4C.s") +void func_8088C920(EnElf* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088DCA4.s") + if (func_8088C804(&this->actor.world.pos, &player->actor.world.pos, 50.0f)) { + if (this->unk_25C > 0) { + this->unk_25C--; + } else { + this->unk_244 = 1; + this->unk_248 = 128; + this->unk_254 = Rand_ZeroFloat(1.0f) + 0.5f; + this->unk_24C = randPlusMinusPoint5Scaled(0x7FFF); + this->unk_26C = func_8088C9CC; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088DD34.s") +void func_8088C9CC(EnElf* this, GlobalContext* globalCtx) { + f32 xzDistToPlayer; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088E018.s") + if (this->unk_25C > 0) { + this->unk_25C--; + } else { + xzDistToPlayer = this->actor.xzDistToPlayer; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088E0E0.s") + if (xzDistToPlayer < 50.0f) { + if (Rand_ZeroOne() < 0.2f) { + this->unk_244 = 2; + this->unk_248 = 0x400; + this->unk_254 = 2.0f; + this->actor.speedXZ = 1.5f; + this->unk_26C = func_8088C920; + this->unk_25C = (s32)Rand_ZeroFloat(8.0f) + 4; + } else { + this->unk_25C = 10; + } + } else { + if (xzDistToPlayer > 150.0f) { + xzDistToPlayer = 150.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088E0F0.s") + xzDistToPlayer = ((xzDistToPlayer - 50.0f) * 0.95f) + 0.05f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088E304.s") + if (Rand_ZeroOne() < xzDistToPlayer) { + this->unk_244 = 3; + this->unk_248 = 0x200; + this->unk_254 = (2.0f * xzDistToPlayer) + 1.0f; + this->unk_26C = func_8088C858; + this->unk_25C = (s32)Rand_ZeroFloat(16.0f) + 16; + } else { + this->unk_25C = 10; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088E484.s") + if (Rand_ZeroOne() < 0.1f) { + this->unk_244 = 1; + this->unk_248 = 128; + this->unk_254 = Rand_ZeroFloat(0.5f) + 0.5f; + this->unk_24C = randPlusMinusPoint5Scaled(0x7FFF); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088E5A8.s") +void func_8088CBAC(EnElf* this, GlobalContext* globalCtx) { + f32 phi_f0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088E60C.s") + if (this->fairyFlags & 0x4000) { + phi_f0 = 0.0f; + } else { + phi_f0 = 100.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088E850.s") + if (func_8088C804(&this->unk_224, &this->actor.world.pos, phi_f0)) { + this->unk_244 = 0; + this->unk_248 = 0x200; + this->unk_254 = 1.5f; + this->unk_26C = func_8088C9CC; + } else { + this->unk_26C(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088EF18.s") +void func_8088CC48(EnElf* this, GlobalContext* globalCtx) { + EnElf_SetupAction(this, func_8088DD34); + this->unk_250 = Rand_ZeroFloat(10.0f) + 10.0f; + this->unk_246 = 0; + this->unk_24A = (s32)Rand_ZeroFloat(1048.0f) + 0x200; + this->unk_224 = this->actor.world.pos; + this->unk_258 = randPlusMinusPoint5Scaled(0x7FFF); + this->unk_26C = func_8088C9CC; + func_8088CBAC(this, globalCtx); + this->unk_25C = 0; + this->disappearTimer = 240; + if ((this->fairyFlags & 0x400) && Actor_GetCollectibleFlag(globalCtx, this->unk_260)) { + Actor_MarkForDeath(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088EFA4.s") +f32 func_8088CD3C(s32 colorFlag) { + switch (colorFlag) { + case 1: + return Rand_ZeroFloat(55.0f) + 200.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088F214.s") + case 2: + return Rand_ZeroFloat(255.0f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088F5F4.s") + return 0.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088F9E4.s") +void EnElf_Init(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnElf* this = THIS; + Player* player = GET_PLAYER(globalCtx); + s32 colorConfig; + s32 params; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088FA38.s") + Actor_ProcessInitChain(thisx, sInitChain); + SkelAnime_Init(globalCtx, &this->skelAnime, &D_0402AF58, &D_04029140, this->jointTable, this->morphTable, 7); + ActorShape_Init(&thisx->shape, 0.0f, NULL, 15.0f); + thisx->shape.shadowAlpha = 255; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088FC34.s") + Lights_PointGlowSetInfo(&this->lightInfoGlow, thisx->world.pos.x, thisx->world.pos.y, thisx->world.pos.z, 255, 255, + 255, 0); + this->lightNodeGlow = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfoGlow); + Lights_PointNoGlowSetInfo(&this->lightInfoNoGlow, thisx->world.pos.x, thisx->world.pos.y, thisx->world.pos.z, 255, + 255, 255, 0); + this->lightNodeNoGlow = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfoNoGlow); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088FD04.s") + this->fairyFlags = 0; + this->disappearTimer = 600; + this->unk_240 = 0.0f; + colorConfig = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088FDCC.s") + this->unk_260 = ENELF_GET_FE00(&this->actor); + params = ENELF_GET_F(&this->actor); + if (thisx->params & 0x100) { + this->fairyFlags |= 0x400; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8088FE64.s") + this->actor.params = params; + switch (params) { + case 0: + thisx->room = -1; + EnElf_SetupAction(this, func_8088E850); + func_8088C51C(this, 0); + this->fairyFlags |= 4; + thisx->update = func_8089010C; + this->elfMsg = NULL; + this->unk_234 = NULL; + this->unk_269 = 20; + if ((gSaveContext.tatlTimer >= 25800) || (gSaveContext.tatlTimer < 3000)) { + gSaveContext.tatlTimer = 0; + } + this->unk_266 = ElfMessage_GetFirstCycleHint(globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_8089010C.s") + case 1: + colorConfig = -1; + gSaveContext.unk_1016 = 0; + EnElf_SetupAction(this, func_8088E0F0); + this->unk_254 = Math_Vec3f_DistXZ(&thisx->world.pos, &player->actor.world.pos); + this->unk_248 = player->actor.shape.rot.y; + this->unk_24C = -0x1000; + this->unk_224.y = thisx->world.pos.y - player->actor.world.pos.y; + this->unk_246 = 0; + this->unk_250 = 0.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/EnElf_Update.s") + case 5: + colorConfig = -1; + EnElf_SetupAction(this, func_8088E484); + this->unk_254 = 0.0f; + this->unk_248 = player->actor.shape.rot.y; + this->unk_24C = 0; + this->unk_224.y = thisx->world.pos.y - player->actor.world.pos.y; + this->unk_246 = 0; + this->unk_250 = 7.0f; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_80890494.s") + case 7: + this->fairyFlags |= 0x200; + thisx->shape.shadowDraw = func_800B4088; + this->fairyFlags |= 0x100; + colorConfig = -1; + this->fairyFlags |= 0x800; + this->fairyFlags |= 0x1000; + func_8088CC48(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/EnElf_Draw.s") + case 2: + this->fairyFlags |= 0x100; + colorConfig = -1; + this->fairyFlags |= 0x800; + this->fairyFlags |= 0x2000; + this->fairyFlags |= 0x1000; + func_8088CC48(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Elf/func_808908D0.s") + case 6: + colorConfig = -1; + this->fairyFlags |= 0x800; + this->fairyFlags |= 0x2000; + this->fairyFlags |= 0x1000; + func_8088CC48(this, globalCtx); + break; + + case 9: + this->fairyFlags |= 0x1000; + + case 10: + colorConfig = -2; + func_8088CC48(this, globalCtx); + break; + + case 8: + Actor_MarkForDeath(thisx); + return; + + case 3: + colorConfig = Rand_ZeroFloat(11.99f) + 1.0f; + EnElf_SetupAction(this, func_8088E018); + func_8088C51C(this, 0); + break; + + case 4: + EnElf_SetupAction(this, func_8088E0E0); + func_8088C51C(this, 6); + this->fairyFlags |= 8; + { + s32 i; + + for (i = 0; i < 8; i++) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELF, thisx->world.pos.x, + thisx->world.pos.y - 30.0f, thisx->world.pos.z, 0, 0, 0, 6); + } + } + break; + } + + this->unk_23C = 3.0f; + this->innerColor = sInnerColors[0]; + if (colorConfig > 0) { + this->outerColor.r = func_8088CD3C(sColorFlags[colorConfig].r); + this->outerColor.g = func_8088CD3C(sColorFlags[colorConfig].g); + this->outerColor.b = func_8088CD3C(sColorFlags[colorConfig].b); + this->outerColor.a = 0; + } else { + this->innerColor = sInnerColors[-colorConfig]; + this->outerColor = sOuterColors[-colorConfig]; + } +} + +void EnElf_Destroy(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnElf* this = THIS; + + LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNodeGlow); + LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNodeNoGlow); +} + +void func_8088D3EC(EnElf* this, GlobalContext* globalCtx) { + this->unk_224.x = Math_SinS(this->unk_248) * this->unk_254; + this->unk_224.y = Math_SinS(this->unk_246) * this->unk_250; + this->unk_224.z = Math_CosS(this->unk_248) * this->unk_254; + this->unk_248 += this->unk_24C; + this->unk_246 += this->unk_24A; +} + +void func_8088D470(EnElf* this, GlobalContext* globalCtx) { + f32 xzScale = (Math_CosS(this->unk_246) * this->unk_250) + this->unk_254; + + this->unk_224.x = Math_SinS(this->unk_248) * xzScale; + this->unk_224.y = 0.0f; + this->unk_224.z = Math_CosS(this->unk_248) * xzScale; + + this->unk_248 += this->unk_24C; + this->unk_246 += this->unk_24A; +} + +void func_8088D504(EnElf* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + this->unk_246 = (this->unk_248 * 2) & 0xFFFF; + this->unk_224.x = Math_SinS(this->unk_248) * this->unk_254; + this->unk_224.y = Math_SinS(this->unk_246) * this->unk_250; + this->unk_224.z = -Math_SinS(player->actor.shape.rot.y) * this->unk_224.x; + this->unk_224.x = Math_CosS(player->actor.shape.rot.y) * this->unk_224.x; + this->unk_248 += this->unk_24C; +} + +void func_8088D5A0(EnElf* this, Vec3f* arg1, f32 arg2) { + f32 yVelTarget = ((arg1->y + this->unk_224.y) - this->actor.world.pos.y) * arg2; + f32 yVelAbs = fabsf(yVelTarget); + f32 yVelDirection = (yVelTarget >= 0.0f) ? 1.0f : -1.0f; + + yVelAbs = CLAMP(yVelAbs, 0.0f, 30.0f); + Math_StepToF(&this->actor.velocity.y, yVelAbs * yVelDirection, 32.0f); +} + +void func_8088D660(EnElf* this, Vec3f* targetPos, f32 arg2) { + f32 xVelTarget = ((targetPos->x + this->unk_224.x) - this->actor.world.pos.x) * arg2; + f32 zVelTarget = ((targetPos->z + this->unk_224.z) - this->actor.world.pos.z) * arg2; + f32 xVelDirection = (xVelTarget >= 0.0f) ? 1.0f : -1.0f; + f32 zVelDirection = (zVelTarget >= 0.0f) ? 1.0f : -1.0f; + + xVelTarget = fabsf(xVelTarget); + zVelTarget = fabsf(zVelTarget); + + xVelTarget = CLAMP(xVelTarget, 0.0f, 30.0f) * xVelDirection; + zVelTarget = CLAMP(zVelTarget, 0.0f, 30.0f) * zVelDirection; + + func_8088D5A0(this, targetPos, arg2); + Math_StepToF(&this->actor.velocity.x, xVelTarget, 1.5f); + Math_StepToF(&this->actor.velocity.z, zVelTarget, 1.5f); + Actor_ApplyMovement(&this->actor); +} + +void func_8088D7F8(EnElf* this, Vec3f* targetPos) { + func_8088D5A0(this, targetPos, 0.2f); + this->actor.velocity.x = 0.0f; + this->actor.velocity.z = 0.0f; + Actor_ApplyMovement(&this->actor); + this->actor.world.pos.x = targetPos->x + this->unk_224.x; + this->actor.world.pos.z = targetPos->z + this->unk_224.z; +} + +void func_8088D864(EnElf* this, Vec3f* targetPos) { + func_8088D5A0(this, targetPos, 0.2f); + this->actor.velocity.z = 0.0f; + this->actor.velocity.x = 0.0f; + Actor_ApplyMovement(&this->actor); + this->actor.world.pos.x = targetPos->x + this->unk_224.x; + this->actor.world.pos.z = targetPos->z + this->unk_224.z; +} + +void func_8088D8D0(EnElf* this, Vec3f* arg1) { + f32 yVelTarget = (((Math_SinS(this->unk_246) * this->unk_250) + arg1->y) - this->actor.world.pos.y) * 0.2f; + f32 yVelAbs = fabsf(yVelTarget); + f32 yVelDirection = (yVelTarget >= 0.0f) ? 1.0f : -1.0f; + + this->unk_246 += this->unk_24A; + yVelAbs = CLAMP(yVelAbs, 0.0f, 30.0f); + + Math_StepToF(&this->actor.velocity.y, yVelAbs * yVelDirection, 1.5f); +} + +void func_8088D9BC(EnElf* this, GlobalContext* globalCtx) { + s32 pad[2]; + Player* player = GET_PLAYER(globalCtx); + s16 targetYaw; + Vec3f* vec = &this->unk_224; + + if (this->fairyFlags & 0x4000) { + Math_SmoothStepToF(&this->actor.speedXZ, 5.0f, 0.5f, 1.0f, 0.01f); + } else { + Math_SmoothStepToF(&this->actor.speedXZ, this->unk_254, 0.2f, 0.5f, 0.01f); + } + + switch (this->unk_244) { + case 0: + targetYaw = Math_FAtan2F(-(this->actor.world.pos.z - vec->z), -(this->actor.world.pos.x - vec->x)); + break; + + case 3: + targetYaw = Math_FAtan2F(-(this->actor.world.pos.z - player->actor.world.pos.z), + -(this->actor.world.pos.x - player->actor.world.pos.x)); + break; + + case 2: + targetYaw = Math_FAtan2F(this->actor.world.pos.z - player->actor.world.pos.z, + this->actor.world.pos.x - player->actor.world.pos.x); + break; + + default: + targetYaw = this->unk_24C; + break; + } + + if (this->fairyFlags & 0x4000) { + Math_SmoothStepToS(&this->unk_258, targetYaw, 10, this->unk_248, 0x1000); + } else { + Math_SmoothStepToS(&this->unk_258, targetYaw, 10, this->unk_248, 0x20); + } + + this->actor.world.rot.y = this->unk_258; + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); +} + +void func_8088DB4C(EnElf* this, Vec3f* arg1, f32 arg2, f32 arg3, f32 arg4) { + f32 xVelTarget = ((arg1->x + this->unk_224.x) - this->actor.world.pos.x) * arg4; + f32 zVelTarget = ((arg1->z + this->unk_224.z) - this->actor.world.pos.z) * arg4; + f32 xzVelocity; + f32 clampedXZ; + + arg4 += 0.3f; + arg3 += 30.0f; + + func_8088D5A0(this, arg1, arg4); + + xzVelocity = sqrtf(SQ(xVelTarget) + SQ(zVelTarget)); + clampedXZ = CLAMP(xzVelocity, arg2, arg3); + this->actor.speedXZ = clampedXZ; + + if ((xzVelocity != clampedXZ) && (xzVelocity != 0.0f)) { + xzVelocity = clampedXZ / xzVelocity; + xVelTarget *= xzVelocity; + zVelTarget *= xzVelocity; + } + + Math_StepToF(&this->actor.velocity.x, xVelTarget, 5.0f); + Math_StepToF(&this->actor.velocity.z, zVelTarget, 5.0f); + Actor_ApplyMovement(&this->actor); +} + +s32 func_8088DCA4(EnElf* this) { + if (this->disappearTimer > 0) { + this->disappearTimer--; + } else { + this->disappearTimer--; + if (this->disappearTimer > -10) { + Actor_SetScale(&this->actor, (this->disappearTimer + 10) * 0.008f * 0.1f); + } else { + Actor_MarkForDeath(&this->actor); + return true; + } + } + return false; +} + +void func_8088DD34(EnElf* this, GlobalContext* globalCtx) { + Player* refActor = GET_PLAYER(globalCtx); + s32 pad; + Player* player2 = GET_PLAYER(globalCtx); + f32 heightDiff; + + SkelAnime_Update(&this->skelAnime); + + if (Rand_ZeroOne() < 0.05f) { + this->unk_250 = Rand_ZeroFloat(10.0f) + 10.0f; + this->unk_24A = (s32)Rand_ZeroFloat(0x400) + 0x200; + } + + func_8088CBAC(this, globalCtx); + if (this->fairyFlags & 0x800) { + this->unk_224.y = player2->bodyPartsPos[0].y; + } + + func_8088D8D0(this, &this->unk_224); + func_8088D9BC(this, globalCtx); + if (Actor_HasParent(&this->actor, globalCtx)) { + if (this->fairyFlags & 0x400) { + Actor_SetCollectibleFlag(globalCtx, this->unk_260); + } + Actor_MarkForDeath(&this->actor); + return; + } + + if (func_801233E4(globalCtx)) { + if ((this->fairyFlags & 0x4000) && (this->fairyFlags & 0x100) && func_8088DCA4(this)) { + return; + } + return; + } + + heightDiff = this->actor.world.pos.y - refActor->actor.world.pos.y; + + if ((this->fairyFlags & 0x1000) && (heightDiff > 0.0f) && (heightDiff < 60.0f) && + !func_8088C804(&this->actor.world.pos, &refActor->actor.world.pos, 10.0f)) { + func_80115908(globalCtx, 0x80); + if (this->fairyFlags & 0x200) { + Parameter_AddMagic(globalCtx, ((void)0, gSaveContext.unk_3F30) + (gSaveContext.doubleMagic * 0x30) + 0x30); + } + gSaveContext.unk_1016 = 0; + this->unk_254 = 50.0f; + this->unk_248 = refActor->actor.shape.rot.y; + this->unk_24C = -0x1000; + this->unk_224.y = 30.0f; + this->unk_250 = 0.0f; + this->unk_246 = 0; + EnElf_SetupAction(this, func_8088E0F0); + if (this->fairyFlags & 0x400) { + Actor_SetCollectibleFlag(globalCtx, this->unk_260); + } + return; + } + + if (this->fairyFlags & 0x100) { + if (func_8088DCA4(this)) { + return; + } + } else { + Actor_SetScale(&this->actor, 0.008f); + } + + if (this->fairyFlags & 0x2000) { + func_800B8A1C(&this->actor, globalCtx, 0xBA, 80.0f, 60.0f); + } +} + +void func_8088E018(EnElf* this, GlobalContext* globalCtx) { + Vec3f parentPos; + Actor* parent; + + SkelAnime_Update(&this->skelAnime); + func_8088D3EC(this, globalCtx); + parent = this->actor.parent; + + if ((parent != NULL) && (parent->update != NULL)) { + parentPos = this->actor.parent->world.pos; + parentPos.y += (1500.0f * this->actor.scale.y) + 40.0f; + func_8088D660(this, &parentPos, 0.2f); + } else { + Actor_MarkForDeath(&this->actor); + } + this->unk_258 = Math_FAtan2F(this->actor.velocity.z, this->actor.velocity.x); +} + +void func_8088E0E0(EnElf* this, GlobalContext* globalCtx) { +} + +void func_8088E0F0(EnElf* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + SkelAnime_Update(&this->skelAnime); + Math_SmoothStepToF(&this->unk_254, 30.0f, 0.1f, 4.0f, 1.0f); + + this->unk_224.x = Math_CosS(this->unk_248) * this->unk_254; + this->unk_224.y += this->unk_250; + + switch (this->unk_246) { + case 0: + if (this->unk_250 < 2.0f) { + this->unk_250 += 0.1f; + } else { + gSaveContext.healthAccumulator = 160; + this->unk_246++; + } + break; + + case 1: + if (this->unk_250 > -1.0f) { + this->unk_250 -= 0.2f; + } + break; + } + + this->unk_224.z = Math_SinS(this->unk_248) * -this->unk_254; + this->unk_248 += this->unk_24C; + func_8088D660(this, &player->actor.world.pos, 0.2f); + + if (this->unk_250 < 0.0f) { + if ((this->unk_224.y < 20.0f) && (this->unk_224.y > 0.0f)) { + Actor_SetScale(&this->actor, this->unk_224.y * 0.008f * 0.05f); + } + } + + if (this->unk_224.y < -10.0f) { + Actor_MarkForDeath(&this->actor); + return; + } + + this->unk_258 = Math_FAtan2F(this->actor.velocity.z, this->actor.velocity.x); + func_8088F5F4(this, globalCtx, 32); + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FIATY_HEAL - SFX_FLAG); +} + +void func_8088E304(EnElf* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + SkelAnime_Update(&this->skelAnime); + if (this->unk_224.y > 200.0f) { + Actor_MarkForDeath(&this->actor); + return; + } + + if (this->unk_24A >= 0x7E) { + this->unk_254 += 0.1f; + this->unk_250 += 0.5f; + this->unk_224.y += this->unk_250; + } else { + this->unk_24A++; + if (this->unk_254 < 30.0f) { + this->unk_254 += 0.5f; + } + + if (this->unk_224.y > 0.0f) { + this->unk_224.y -= 0.7f; + } + } + + this->unk_224.x = Math_CosS(this->unk_248) * this->unk_254; + this->unk_224.z = Math_SinS(this->unk_248) * -this->unk_254; + this->unk_248 += this->unk_24C; + + func_8088D7F8(this, &player->bodyPartsPos[0]); + this->unk_258 = Math_FAtan2F(this->actor.velocity.z, this->actor.velocity.x); + func_8088F5F4(this, globalCtx, 0x20); + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FIATY_HEAL - SFX_FLAG); +} + +void func_8088E484(EnElf* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + SkelAnime_Update(&this->skelAnime); + + this->unk_224.z = 0.0f; + this->unk_224.x = 0.0f; + this->unk_224.y += this->unk_250; + this->unk_250 -= 0.35f; + + if (this->unk_250 <= 0.0f) { + EnElf_SetupAction(this, func_8088E304); + this->unk_24C = 0x800; + this->unk_24A = 0; + this->unk_250 = 0.0f; + this->unk_254 = 1.0f; + } + + func_8088D7F8(this, &player->bodyPartsPos[0]); + Actor_SetScale(&this->actor, (1.0f - (SQ(this->unk_250) * SQ(1.0f / 9.0f))) * 0.008f); + this->unk_258 = Math_FAtan2F(this->actor.velocity.z, this->actor.velocity.x); + func_8088F5F4(this, globalCtx, 32); + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FIATY_HEAL - SFX_FLAG); +} + +void func_8088E5A8(EnElf* this, GlobalContext* globalCtx) { + if (this->fairyFlags & 4) { + func_8088EFA4(this, globalCtx); + } + + SkelAnime_Update(&this->skelAnime); + + this->unk_26C(this, globalCtx); +} + +void func_8088E60C(EnElf* this, GlobalContext* globalCtx) { + s16 glowLightRadius; + Player* player = GET_PLAYER(globalCtx); + + if (player->stateFlags1 & 0x400) { + glowLightRadius = 200; + } else { + glowLightRadius = 100; + } + + if ((this->unk_244 == 6) || (player->stateFlags1 & 2) || (this->fairyFlags & 0x8000)) { + glowLightRadius = 0; + } + + if (func_800EE29C(globalCtx, 0xC9)) { + if (globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0xC9)]->unk0 == 6) { + glowLightRadius = 0; + } + } + + if (this->fairyFlags & 0x20) { + Player* player = GET_PLAYER(globalCtx); + + Lights_PointNoGlowSetInfo(&this->lightInfoNoGlow, player->actor.world.pos.x, player->actor.world.pos.y + 60.0f, + player->actor.world.pos.z, 255, 255, 255, 200); + } else { + Lights_PointNoGlowSetInfo(&this->lightInfoNoGlow, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 255, 255, 255, -1); + } + + Lights_PointGlowSetInfo(&this->lightInfoGlow, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 255, 255, 255, glowLightRadius); + this->unk_258 = Math_FAtan2F(this->actor.velocity.z, this->actor.velocity.x); + Actor_SetScale(&this->actor, this->actor.scale.x); +} + +void func_8088E850(EnElf* this, GlobalContext* globalCtx) { + Vec3f nextPos; + Player* player = GET_PLAYER(globalCtx); + Actor* arrowPointedActor; + f32 xScale; + f32 distFromLinksHead; + u32 sp38; + + func_8088F214(this, globalCtx); + func_8088E5A8(this, globalCtx); + xScale = 0.0f; + + if (func_800EE29C(globalCtx, 0xC9)) { + sp38 = func_800EE200(globalCtx, 0xC9); + func_808908D0(&nextPos, globalCtx, sp38); + this->actor.shape.rot.y = globalCtx->csCtx.npcActions[sp38]->unk8; + this->actor.shape.rot.x = globalCtx->csCtx.npcActions[sp38]->unk6; + if (globalCtx->csCtx.npcActions[sp38]->unk0 == 5) { + func_8088F5F4(this, globalCtx, 16); + } + + if (this->unk_244 == 8) { + func_8088D864(this, &nextPos); + } else { + func_8088D660(this, &nextPos, 0.2f); + } + + if ((globalCtx->sceneNum == SCENE_CLOCKTOWER) && (gSaveContext.sceneSetupIndex == 0) && + (globalCtx->csCtx.unk_12 == 0) && + ((globalCtx->csCtx.frames == 0x95) || (globalCtx->csCtx.frames == 0x17D) || + (globalCtx->csCtx.frames == 0x24F))) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_WHITE_FAIRY_DASH); + } + + if ((globalCtx->sceneNum == SCENE_SECOM) && (gSaveContext.sceneSetupIndex == 0) && + (globalCtx->csCtx.unk_12 == 4) && (globalCtx->csCtx.frames == 0x5F)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_WHITE_FAIRY_DASH); + } + } else { + this->actor.shape.rot.x = 0; + distFromLinksHead = Math_Vec3f_DistXYZ(&player->bodyPartsPos[8], &this->actor.world.pos); + switch (this->unk_244) { + case 5: + func_8088D660(this, &player->bodyPartsPos[8], 1.0f - (this->unk_24A * 0.033333335f)); + xScale = Math_Vec3f_DistXYZ(&player->bodyPartsPos[8], &this->actor.world.pos); + + if (distFromLinksHead < 7.0f) { + this->unk_25C = 0; + xScale = 0; + } else if (distFromLinksHead < 25.0f) { + xScale = (xScale - 5.0f) * 0.05f; + xScale = 1.0f - xScale; + xScale = (1.0f - SQ(xScale)) * 0.008f; + } else { + xScale = 0.008f; + } + func_8088F5F4(this, globalCtx, 16); + break; + + case 6: + func_8088D660(this, &player->bodyPartsPos[8], 0.2f); + this->actor.world.pos = player->bodyPartsPos[8]; + break; + + case 9: + nextPos = player->bodyPartsPos[8]; + nextPos.y += 1500.0f * this->actor.scale.y; + + func_8088D7F8(this, &nextPos); + func_8088F5F4(this, globalCtx, 16); + + if (this->unk_254 <= 19.0f) { + this->unk_254 += 1.0f; + } + + if (this->unk_254 >= 21.0f) { + this->unk_254 -= 1.0f; + } + + if (this->unk_25C < 0x20) { + this->unk_24C = (this->unk_25C * 240) + 0x200; + } + break; + + case 10: + nextPos = GET_ACTIVE_CAM(globalCtx)->eye; + nextPos.y += -2000.0f * this->actor.scale.y; + func_8088DB4C(this, &nextPos, 0.0f, 30.0f, 0.2f); + break; + + default: + arrowPointedActor = globalCtx->actorCtx.targetContext.unk38; + if ((player->stateFlags1 & 0x40) && (player->targetActor != NULL)) { + Math_Vec3f_Copy(&nextPos, &player->targetActor->focus.pos); + } else { + Math_Vec3f_Copy(&nextPos, &globalCtx->actorCtx.targetContext.unk0); + } + nextPos.y += 1500.0f * this->actor.scale.y; + + if (arrowPointedActor != NULL) { + func_8088DB4C(this, &nextPos, 0.0f, 30.0f, 0.2f); + if (this->actor.speedXZ >= 5.0f) { + func_8088F5F4(this, globalCtx, 0x10); + } + } else { + if ((this->timer % 32) == 0) { + this->unk_23C = Rand_ZeroFloat(7.0f) + 3.0f; + } + + if (this->fairyFlags & 2) { + if (distFromLinksHead < 30.0f) { + this->fairyFlags ^= 2; + } + func_8088DB4C(this, &nextPos, 0.0f, 30.0f, 0.2f); + func_8088F5F4(this, globalCtx, 0x10); + } else { + if (distFromLinksHead > 100.0f) { + this->fairyFlags |= 2; + if (this->unk_269 == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_BELL_DASH_NORMAL); + } + this->unk_25C = 100; + } + func_8088DB4C(this, &nextPos, 0.0f, this->unk_23C, 0.2f); + } + } + break; + } + } + + if (this->unk_244 == 5) { + this->actor.scale.x = xScale; + } else if (this->unk_244 == 6) { + this->actor.scale.x = 0.0f; + } else { + Math_SmoothStepToF(&this->actor.scale.x, 0.008f, 0.3f, 0.00080000004f, 0.000080000005f); + } + + func_8088E60C(this, globalCtx); + + if (!func_800EE29C(globalCtx, 0xC9)) { + this->actor.shape.rot.y = this->unk_258; + } +} + +void func_8088EF18(Color_RGBAf* dest, Color_RGBAf* newColor, Color_RGBAf* curColor, f32 rate) { + Color_RGBAf rgbaDiff; + + rgbaDiff.r = newColor->r - curColor->r; + rgbaDiff.g = newColor->g - curColor->g; + rgbaDiff.b = newColor->b - curColor->b; + rgbaDiff.a = newColor->a - curColor->a; + + dest->r += rgbaDiff.r * rate; + dest->g += rgbaDiff.g * rate; + dest->b += rgbaDiff.b * rate; + dest->a += rgbaDiff.a * rate; +} + +void func_8088EFA4(EnElf* this, GlobalContext* globalCtx) { + Actor* arrayPointerActor = globalCtx->actorCtx.targetContext.unk38; + Player* player = GET_PLAYER(globalCtx); + f32 transitionRate; + + if (!(this->unk_264 & 8)) { + this->unk_264 &= ~0x10; + } + + if (this->unk_264 & 8) { + if (this->unk_264 & 0x10) { + this->unk_238 = 1.0f; + this->unk_264 &= ~8; + this->unk_268 = 0; + this->unk_264 &= ~0x10; + } else { + this->innerColor.r = 255.0f; + this->innerColor.g = 0.0f; + this->innerColor.b = 0.0f; + this->innerColor.a = 255.0f; + + this->outerColor.r = 200.0f; + this->outerColor.g = 80.0f; + this->outerColor.b = 80.0f; + this->outerColor.a = 0.0f; + } + } else if (globalCtx->actorCtx.targetContext.unk40 != 0.0f) { + this->unk_268 = 0; + this->unk_238 = 1.0f; + if (!this->unk_269) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_BELL_DASH_NORMAL); + } + } else if (this->unk_268 == 0) { + if ((arrayPointerActor == NULL) || + (Math_Vec3f_DistXYZ(&this->actor.world.pos, &globalCtx->actorCtx.targetContext.unk0) < 50.0f)) { + this->unk_268 = 1; + } + } else if (this->unk_238 != 0.0f) { + if (Math_StepToF(&this->unk_238, 0.0f, 0.25f)) { + this->innerColor = globalCtx->actorCtx.targetContext.unk18; + this->outerColor = globalCtx->actorCtx.targetContext.unk28; + } else { + transitionRate = 0.25f / this->unk_238; + func_8088EF18(&this->innerColor, &globalCtx->actorCtx.targetContext.unk18, &this->innerColor, + transitionRate); + func_8088EF18(&this->outerColor, &globalCtx->actorCtx.targetContext.unk28, &this->outerColor, + transitionRate); + } + } + + if (this->fairyFlags & 1) { + if ((arrayPointerActor == NULL) || (player->unk_730 == NULL)) { + this->fairyFlags ^= 1; + } + } else if ((arrayPointerActor != NULL) && (player->unk_730 != NULL)) { + u8 temp = this->unk_269; + u16 targetSfxId = this->unk_269 == 0 ? NA_SE_PL_WALK_GROUND - SFX_FLAG : NA_SE_PL_WALK_GROUND - SFX_FLAG; + + if (!temp) { + Audio_PlayActorSound2(&this->actor, targetSfxId); + } + this->fairyFlags |= 1; + } +} + +void func_8088F214(EnElf* this, GlobalContext* globalCtx) { + s32 sp34; + Actor* arrowPointedActor; + Player* player = GET_PLAYER(globalCtx); + s32 pad; + + if (globalCtx->csCtx.state != 0) { + if (func_800EE29C(globalCtx, 0xC9)) { + switch (globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0xC9)]->unk0) { + case 4: + sp34 = 7; + break; + + case 3: + sp34 = 4; + break; + + case 1: + sp34 = 8; + break; + + default: + sp34 = 0; + break; + } + } else { + sp34 = 0; + this->unk_25C = 100; + } + } else if (this->unk_264 & 8) { + sp34 = 1; + func_800B9010(&this->actor, NA_SE_EV_BELL_ANGER - SFX_FLAG); + } else { + arrowPointedActor = globalCtx->actorCtx.targetContext.unk38; + if (player->stateFlags1 & 0x400) { + sp34 = 10; + this->unk_25C = 100; + } else if ((arrowPointedActor == NULL) || (arrowPointedActor->category == 4)) { + if (arrowPointedActor != NULL) { + this->unk_25C = 100; + player->stateFlags2 |= 0x100000; + sp34 = 0; + } else { + switch (this->unk_244) { + case 0: + if (this->unk_25C != 0) { + this->unk_25C--; + sp34 = 0; + } else if (!(player->stateFlags1 & 0x40)) { + if (this->unk_269 == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_NAVY_VANISH); + } + sp34 = 5; + } else { + sp34 = 0; + } + break; + + case 5: + if (this->unk_25C != 0) { + if (this->unk_24A > 0) { + this->unk_24A--; + sp34 = 5; + } else { + player->stateFlags2 |= 0x100000; + sp34 = 0; + } + } else { + sp34 = 6; + } + break; + + case 6: + sp34 = 6; + break; + + case 9: + sp34 = this->unk_244; + if (this->unk_25C > 0) { + this->unk_25C--; + } else { + sp34 = 0; + } + break; + + default: + sp34 = 0; + break; + } + } + } else { + sp34 = 1; + } + + switch (sp34) { + case 0: + if (!(player->stateFlags2 & 0x100000)) { + sp34 = 5; + if (this->unk_269 == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_NAVY_VANISH); + } + } + break; + + case 6: + if (player->stateFlags2 & 0x100000) { + sp34 = 9; + this->unk_25C = 0x2A; + if (this->unk_269 == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_BELL_DASH_NORMAL); + } + } else if (player->stateFlags1 & 0x40) { + player->stateFlags2 |= 0x100000; + sp34 = 0; + this->unk_25C = 0; + } + break; + + case 5: + player->stateFlags2 &= ~0x100000; + break; + + default: + player->stateFlags2 |= 0x100000; + break; + } + } + + if (sp34 != this->unk_244) { + func_8088C51C(this, sp34); + if (sp34 == 9) { + this->unk_254 = Math_Vec3f_DistXZ(&player->bodyPartsPos[8], &this->actor.world.pos); + this->unk_248 = Math_Vec3f_Yaw(&this->actor.world.pos, &player->bodyPartsPos[8]); + } + } +} + +void func_8088F5F4(EnElf* this, GlobalContext* globalCtx, s32 sparkleLife) { + static Vec3f sparkleVelocity = { 0.0f, -0.05f, 0.0f }; + static Vec3f sparkleAccel = { 0.0f, -0.025f, 0.0f }; + s32 pad; + Vec3f sparklePos; + Color_RGBA8 primColor; + Color_RGBA8 envColor; + + if (!(this->fairyFlags & 8)) { + sparklePos.x = randPlusMinusPoint5Scaled(6.0f) + this->actor.world.pos.x; + sparklePos.y = (Rand_ZeroOne() * 6.0f) + this->actor.world.pos.y; + sparklePos.z = randPlusMinusPoint5Scaled(6.0f) + this->actor.world.pos.z; + + primColor.r = this->innerColor.r; + primColor.g = this->innerColor.g; + primColor.b = this->innerColor.b; + + envColor.r = this->outerColor.r; + envColor.g = this->outerColor.g; + envColor.b = this->outerColor.b; + + EffectSsKiraKira_SpawnDispersed(globalCtx, &sparklePos, &sparkleVelocity, &sparkleAccel, &primColor, &envColor, + 1000, sparkleLife); + } +} + +void func_8088F9E4(Actor* thisx, GlobalContext* globalCtx) { + EnElf* this = THIS; + s32 bgId; + + thisx->floorHeight = BgCheck_EntityRaycastFloor5_2(globalCtx, &globalCtx->colCtx, &thisx->floorPoly, &bgId, + &this->actor, &thisx->world.pos); + thisx->shape.shadowAlpha = 50; +} + +void func_8088FA38(EnElf* this, GlobalContext* globalCtx) { + Vec3f refPos; + Player* player = GET_PLAYER(globalCtx); + + if (this->fairyFlags & 0x10) { + refPos = globalCtx->actorCtx.targetContext.unk0; + + if (this->unk_234 != NULL) { + refPos = this->unk_234->world.pos; + } else { + if ((player->unk_730 == NULL) || (&player->actor == player->unk_730) || (&this->actor == player->unk_730) || + (this->unk_264 & 4)) { + refPos.x = player->bodyPartsPos[7].x + (Math_SinS(player->actor.shape.rot.y) * 20.0f); + refPos.y = player->bodyPartsPos[7].y + 5.0f; + refPos.z = player->bodyPartsPos[7].z + (Math_CosS(player->actor.shape.rot.y) * 20.0f); + this->unk_264 &= ~4; + } + } + this->actor.focus.pos = refPos; + this->fairyFlags &= ~0x10; + } + + func_8088E5A8(this, globalCtx); + refPos = this->actor.focus.pos; + func_8088DB4C(this, &refPos, 0, 30.0f, 0.2f); + + if (this->actor.speedXZ >= 5.0f) { + func_8088F5F4(this, globalCtx, 0x10); + } + + Math_SmoothStepToF(&this->actor.scale.x, 0.008f, 0.3f, 0.00080000004f, 0.000080000005f); + func_8088E60C(this, globalCtx); +} + +void func_8088FC34(EnElf* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->unk_258, 5, 0x1000, 0x400); + this->timer++; + + if (this->unk_234 == NULL) { + if (this->unk_264 & 0x20) { + this->unk_240 = 0.0f; + } else { + Math_StepToF(&this->unk_240, 1.0f, 0.05f); + } + func_800FD2B4(globalCtx, SQ(this->unk_240), player->actor.projectedPos.z + 780.0f, 0.2f, 0.5f); + } +} + +void func_8088FD04(EnElf* this) { + if (ActorCutscene_GetCurrentIndex() == this->actor.cutscene) { + this->unk_264 &= ~1; + this->unk_264 |= 2; + } else if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + this->unk_264 |= 1; + } else if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_Start(this->actor.cutscene, &this->actor); + this->unk_264 &= ~1; + this->unk_264 |= 2; + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + this->unk_264 |= 1; + } +} + +void func_8088FDCC(EnElf* this) { + this->actor.update = func_8089010C; + func_8088C51C(this, 0); + this->fairyFlags &= ~0x20; + this->actor.focus.pos = this->actor.world.pos; + this->unk_234 = NULL; + if ((this->unk_264 & 2) && (this->actor.cutscene != 0x7C)) { + ActorCutscene_Stop(this->actor.cutscene); + } + this->unk_264 &= ~0x20; +} + +void func_8088FE64(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnElf* this = THIS; + + func_8088FA38(this, globalCtx); + + switch (func_80152498(&globalCtx->msgCtx)) { + case 4: + if (func_80147624(globalCtx)) { + if (globalCtx->msgCtx.unk11F04 == 0x202) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_8019F230(); + break; + + case 1: + func_8019F208(); + break; + } + } + + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 - 1); + break; + + case 1: + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + break; + } + } + break; + + case 5: + if (func_80147624(globalCtx)) { + switch (globalCtx->msgCtx.unk11F04) { + case 576: + func_80151938(globalCtx, 0x245); + break; + + case 0x21D: + case 0x21E: + case 0x21F: + case 0x220: + case 0x221: + case 0x222: + case 0x223: + case 0x23F: + case 0x241: + case 0x242: + case 0x243: + case 0x244: + switch (CURRENT_DAY) { + case 1: + func_80151938(globalCtx, 0x246); + break; + + case 2: + func_80151938(globalCtx, 0x247); + break; + + case 3: + if (!gSaveContext.isNight) { + func_80151938(globalCtx, 0x248); + } else if ((gSaveContext.time < CLOCK_TIME(6, 0)) && + (gSaveContext.weekEventReg[74] & 0x20)) { + func_80151938(globalCtx, 0x225); + } else { + func_80151938(globalCtx, 0x249); + } + break; + } + break; + + default: + func_801477B4(globalCtx); + func_8088FDCC(this); + break; + } + } + break; + + case 2: + func_8088FDCC(this); + break; + } + + func_8088FC34(this, globalCtx); + + if (this->unk_264 & 1) { + func_8088FD04(this); + } +} + +void func_8089010C(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnElf* this = THIS; + Player* player = GET_PLAYER(globalCtx); + u16 temp_v0 = ElfMessage_GetFirstCycleHint(globalCtx); + + if (temp_v0 != this->unk_266) { + this->unk_266 = temp_v0; + gSaveContext.tatlTimer = 0; + } + + if ((player->tatlTextId == 0) && (player->unk_730 == NULL)) { + if ((gSaveContext.tatlTimer >= 600) && (gSaveContext.tatlTimer <= 3000)) { + player->tatlTextId = ElfMessage_GetFirstCycleHint(globalCtx); + } + } + + if (player->tatlTextId < 0) { + thisx->flags |= 0x10000; + } + + if (func_800B84D0(thisx, globalCtx)) { + func_8019FDC8(&D_801DB4A4, NA_SE_VO_NA_LISTEN, 0x20); + thisx->focus.pos = thisx->world.pos; + + if (thisx->textId == ElfMessage_GetFirstCycleHint(globalCtx)) { + this->fairyFlags |= 0x80; + gSaveContext.tatlTimer = 3001; + } + + this->fairyFlags |= 0x10; + this->fairyFlags |= 0x20; + thisx->update = func_8088FE64; + func_8088C51C(this, 3); + if (this->elfMsg != NULL) { + this->elfMsg->flags |= 0x100; + thisx->cutscene = this->elfMsg->cutscene; + if (thisx->cutscene != -1) { + func_8088FD04(this); + } + if (this->elfMsg->home.rot.x == -0x961) { + this->unk_234 = this->elfMsg; + func_800B86C8(thisx, globalCtx, this->elfMsg); + } + } else { + thisx->cutscene = -1; + } + thisx->flags &= ~0x10000; + } else if (this->unk_264 & 4) { + thisx->focus.pos = thisx->world.pos; + this->fairyFlags |= 0x10; + this->fairyFlags |= 0x20; + thisx->update = func_8088FE64; + func_8088C51C(this, 3); + } else { + this->actionFunc(this, globalCtx); + + if (!func_801690CC(globalCtx)) { + if (gSaveContext.tatlTimer < 25800) { + gSaveContext.tatlTimer++; + } else if (!(this->fairyFlags & 0x80)) { + gSaveContext.tatlTimer = 0; + } + } + } + + this->elfMsg = NULL; + this->timer++; + + if ((this->unk_240 >= 0.0f) && func_800FD2B4(globalCtx, SQ(this->unk_240) * this->unk_240, + player->actor.projectedPos.z + 780.0f, 0.2f, 0.5f)) { + Math_StepToF(&this->unk_240, -0.05f, 0.05f); + } + + if (this->unk_269 > 0) { + this->unk_269--; + } + + if (!this->unk_269 && (globalCtx->csCtx.state != 0)) { + this->unk_269 = 1; + } +} + +void EnElf_Update(Actor* thisx, GlobalContext* globalCtx) { + EnElf* this = THIS; + + this->actionFunc(this, globalCtx); + + thisx->shape.rot.y = this->unk_258; + this->timer++; + + if (this->fairyFlags & 0x200) { + func_8088F9E4(thisx, globalCtx); + } +} + +s32 EnElf_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, + Gfx** gfx) { + static Vec3f zeroVec = { 0.0f, 0.0f, 0.0f }; + s32 pad; + EnElf* this = THIS; + Vec3f sp34; + f32 scale; + + if (limbIndex == 6) { + scale = ((Math_SinS(this->timer * 4096) * 0.1f) + 1.0f) * 0.012f; + if (this->fairyFlags & 0x200) { + scale *= 2.0f; + } + scale *= this->actor.scale.x * 124.99999f; + + Matrix_MultiplyVector3fByState(&zeroVec, &sp34); + Matrix_InsertTranslation(sp34.x, sp34.y, sp34.z, MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + } + + if ((this->fairyFlags & 0x200) && + ((limbIndex == 4) || (limbIndex == 7) || (limbIndex == 11) || (limbIndex == 14))) { + *dList = NULL; + } + return false; +} + +void EnElf_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnElf* this = THIS; + Player* player = GET_PLAYER(globalCtx); + s32 pad; + s32 pad2; + + if (player->currentMask != PLAYER_MASK_GIANT) { + if (!(this->fairyFlags & 8) && + (!func_800EE29C(globalCtx, 0xC9) || + (globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0xC9)]->unk0 != 6)) && + (!(player->stateFlags1 & 0x100000) || (kREG(90) < this->actor.projectedPos.z))) { + Gfx* dListHead = GRAPH_ALLOC(globalCtx->state.gfxCtx, sizeof(Gfx) * 4); + f32 alphaScale; + s32 envAlpha; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C94C(globalCtx->state.gfxCtx); + + envAlpha = (this->timer * 50) & 0x1FF; + envAlpha = (envAlpha >= 0x100) ? 511 - envAlpha : envAlpha; + + alphaScale = (this->disappearTimer < 0) ? (this->disappearTimer * 0.0011666666f) + 1.0f : 1.0f; + + gSPSegment(POLY_XLU_DISP++, 0x08, dListHead); + + gDPPipeSync(dListHead++); + gDPSetPrimColor(dListHead++, 0, 0x01, (u8)(s8)this->innerColor.r, (u8)(s8)this->innerColor.g, + (u8)(s8)this->innerColor.b, (u8)(s8)(this->innerColor.a * alphaScale)); + + if (this->fairyFlags & 4) { + gDPSetRenderMode(dListHead++, G_RM_PASS, G_RM_CLD_SURF2); + } else { + gDPSetRenderMode(dListHead++, G_RM_PASS, G_RM_ZB_CLD_SURF2); + } + + gSPEndDisplayList(dListHead); + + gDPSetEnvColor(POLY_XLU_DISP++, (u8)(s8)this->outerColor.r, (u8)(s8)this->outerColor.g, + (u8)(s8)this->outerColor.b, (u8)(s8)(envAlpha * alphaScale)); + + POLY_XLU_DISP = SkelAnime_Draw(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + EnElf_OverrideLimbDraw, NULL, &this->actor, POLY_XLU_DISP); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + } +} + +void func_808908D0(Vec3f* vec, GlobalContext* globalCtx, u32 action) { + Vec3f startPos; + Vec3f endPos; + CsCmdActorAction* npcAction = globalCtx->csCtx.npcActions[action]; + f32 lerp; + + startPos.x = npcAction->unk0C.x; + startPos.y = npcAction->unk0C.y; + startPos.z = npcAction->unk0C.z; + + endPos.x = npcAction->unk18.x; + endPos.y = npcAction->unk18.y; + endPos.z = npcAction->unk18.z; + + lerp = func_800F5A8C(npcAction->endFrame, npcAction->startFrame, globalCtx->csCtx.frames, globalCtx); + VEC3F_LERPIMPDST(vec, &startPos, &endPos, lerp); +} diff --git a/src/overlays/actors/ovl_En_Elf/z_en_elf.h b/src/overlays/actors/ovl_En_Elf/z_en_elf.h index 0bc20043c..52c5e2af1 100644 --- a/src/overlays/actors/ovl_En_Elf/z_en_elf.h +++ b/src/overlays/actors/ovl_En_Elf/z_en_elf.h @@ -6,12 +6,46 @@ struct EnElf; typedef void (*EnElfActionFunc)(struct EnElf*, GlobalContext*); +typedef void (*EnElfUnkFunc)(struct EnElf*, GlobalContext*); + +#define ENELF_GET_F(thisx) ((thisx)->params & 0xF) +#define ENELF_GET_FE00(thisx) (((thisx)->params & 0xFE00) >> 9) typedef struct EnElf { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x120]; - /* 0x0264 */ u16 unk264; - /* 0x0266 */ char unk_266[0xA]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[7]; + /* 0x01B2 */ Vec3s morphTable[7]; + /* 0x01DC */ Color_RGBAf innerColor; + /* 0x01EC */ Color_RGBAf outerColor; + /* 0x01FC */ LightInfo lightInfoGlow; + /* 0x020C */ LightNode* lightNodeGlow; + /* 0x0210 */ LightInfo lightInfoNoGlow; + /* 0x0220 */ LightNode* lightNodeNoGlow; + /* 0x0224 */ Vec3f unk_224; + /* 0x0230 */ Actor* elfMsg; + /* 0x0234 */ Actor* unk_234; + /* 0x0238 */ f32 unk_238; + /* 0x023C */ f32 unk_23C; + /* 0x0240 */ f32 unk_240; + /* 0x0244 */ s16 unk_244; + /* 0x0246 */ s16 unk_246; + /* 0x0248 */ s16 unk_248; + /* 0x024A */ s16 unk_24A; + /* 0x024C */ s16 unk_24C; + /* 0x0250 */ f32 unk_250; + /* 0x0254 */ f32 unk_254; + /* 0x0258 */ s16 unk_258; + /* 0x025A */ u16 timer; + /* 0x025C */ s16 unk_25C; + /* 0x025E */ s16 disappearTimer; + /* 0x0260 */ s16 unk_260; + /* 0x0262 */ u16 fairyFlags; + /* 0x0264 */ u16 unk_264; + /* 0x0266 */ u16 unk_266; + /* 0x0268 */ u8 unk_268; + /* 0x0269 */ u8 unk_269; + /* 0x026C */ EnElfUnkFunc unk_26C; /* 0x0270 */ EnElfActionFunc actionFunc; } EnElf; // size = 0x274 diff --git a/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c b/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c index 1e87473cd..cd574fb31 100644 --- a/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c +++ b/src/overlays/actors/ovl_En_Elfbub/z_en_elfbub.c @@ -154,12 +154,12 @@ void EnElfbub_Draw(Actor* thisx, GlobalContext* globalCtx2) { func_8012C2DC(globalCtx->state.gfxCtx); - Matrix_InsertTranslation(0.0f, 0.0f, 1.0f, 1); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); - Matrix_Scale(this->xyScale + 1.0f, this->xyScale + 1.0f, 1.0f, 1); - Matrix_InsertZRotation_s(this->zRot, 1); - Matrix_Scale(this->xScale + 1.0f, 1.0f, 1.0f, 1); - Matrix_InsertZRotation_s(this->zRot * -1, 1); + Matrix_InsertTranslation(0.0f, 0.0f, 1.0f, MTXMODE_APPLY); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + Matrix_Scale(this->xyScale + 1.0f, this->xyScale + 1.0f, 1.0f, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->zRot, MTXMODE_APPLY); + Matrix_Scale(this->xScale + 1.0f, 1.0f, 1.0f, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->zRot * -1, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, D_06001000); diff --git a/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c b/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c index 1efecd257..e0970a76e 100644 --- a/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c +++ b/src/overlays/actors/ovl_En_Elforg/z_en_elforg.c @@ -5,6 +5,7 @@ */ #include "z_en_elforg.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x00000010 @@ -72,7 +73,8 @@ void EnElforg_Init(Actor* thisx, GlobalContext* globalCtx) { Actor_SetScale(&this->actor, 0.01f); this->flags = 0; this->direction = 0; - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0402CA98, &D_0402B494, this->jointTable, this->jointTable, 10); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gStrayFairySkel, &gStrayFairyFlyingAnim, this->jointTable, + this->jointTable, STRAY_FAIRY_LIMB_MAX); this->skelAnime.playSpeed = 1.0f; ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f); this->actor.shape.shadowAlpha = 255; @@ -575,13 +577,14 @@ s32 EnElforg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLi EnElforg* this = THIS; if (this->direction < 0) { - if (limbIndex == 9) { + if (limbIndex == STRAY_FAIRY_LIMB_LEFT_FACING_HEAD) { *dList = NULL; } - } else if (limbIndex == 1) { + } else if (limbIndex == STRAY_FAIRY_LIMB_RIGHT_FACING_HEAD) { *dList = NULL; } - return 0; + + return false; } void EnElforg_Draw(Actor* thisx, GlobalContext* globalCtx) { @@ -589,25 +592,26 @@ void EnElforg_Draw(Actor* thisx, GlobalContext* globalCtx) { EnElforg* this = THIS; OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); switch (this->area) { case STRAY_FAIRY_AREA_WOODFALL: - AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_0402C908)); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(gStrayFairyWoodfallTexAnim)); break; case STRAY_FAIRY_AREA_SNOWHEAD: - AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_0402C890)); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(gStrayFairySnowheadTexAnim)); break; case STRAY_FAIRY_AREA_GREAT_BAY: - AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_0402C980)); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(gStrayFairyGreatBayTexAnim)); break; case STRAY_FAIRY_AREA_STONE_TOWER: - AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_0402C9F8)); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(gStrayFairyStoneTowerTexAnim)); break; default: - AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_0402C818)); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(gStrayFairyClockTownTexAnim)); break; } - Matrix_InsertMatrix(&globalCtx->mf_187FC, 1); + Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_APPLY); POLY_XLU_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, diff --git a/src/overlays/actors/ovl_En_Elforg/z_en_elforg.h b/src/overlays/actors/ovl_En_Elforg/z_en_elforg.h index 5195235a3..fbf982beb 100644 --- a/src/overlays/actors/ovl_En_Elforg/z_en_elforg.h +++ b/src/overlays/actors/ovl_En_Elforg/z_en_elforg.h @@ -33,6 +33,20 @@ typedef enum { STRAY_FAIRY_AREA_MAX } StrayFairyArea; +typedef enum { + /* 0 */ STRAY_FAIRY_LIMB_NONE, + /* 1 */ STRAY_FAIRY_LIMB_RIGHT_FACING_HEAD, + /* 2 */ STRAY_FAIRY_LIMB_LEFT_WING, + /* 3 */ STRAY_FAIRY_LIMB_RIGHT_WING, + /* 4 */ STRAY_FAIRY_LIMB_GLOW, + /* 5 */ STRAY_FAIRY_LIMB_TORSO, + /* 6 */ STRAY_FAIRY_LIMB_RIGHT_ARM, + /* 7 */ STRAY_FAIRY_LIMB_PELVIS_AND_LEGS, + /* 8 */ STRAY_FAIRY_LIMB_LEFT_ARM, + /* 9 */ STRAY_FAIRY_LIMB_LEFT_FACING_HEAD, + /* 10 */ STRAY_FAIRY_LIMB_MAX, +} StrayFairyLimbs; + struct EnElforg; typedef void (*EnElforgActionFunc)(struct EnElforg*, GlobalContext*); @@ -40,11 +54,11 @@ typedef void (*EnElforgActionFunc)(struct EnElforg*, GlobalContext*); typedef struct EnElforg { /* 0x000 */ Actor actor; /* 0x144 */ SkelAnime skelAnime; - /* 0x188 */ Vec3s jointTable[10]; + /* 0x188 */ Vec3s jointTable[STRAY_FAIRY_LIMB_MAX]; /* 0x1C4 */ ColliderCylinder collider; /* 0x210 */ Actor* enemy; /* 0x214 */ u16 flags; - /* 0x216 */ s16 direction; // negative when facing left, positive when facing right + /* 0x216 */ s16 direction; // negative when facing right, positive when facing left /* 0x218 */ s16 area; /* 0x21C */ s32 timer; /* 0x220 */ s32 secondaryTimer; diff --git a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c index 94641b569..2672c209f 100644 --- a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c +++ b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.c @@ -1,7 +1,7 @@ /* * File: z_en_encount1.c * Overlay: ovl_En_Encount1 - * Description: + * Description: Spawner for Dragonflies, Skullfish, and Wallmasters */ #include "z_en_encount1.h" diff --git a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h index e473615cb..72638d9a6 100644 --- a/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h +++ b/src/overlays/actors/ovl_En_Encount1/z_en_encount1.h @@ -10,7 +10,7 @@ typedef void (*EnEncount1ActionFunc)(struct EnEncount1*, GlobalContext*); typedef struct EnEncount1 { /* 0x0000 */ Actor actor; /* 0x0144 */ EnEncount1ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x1C]; + /* 0x0148 */ char unk_148[0x1C]; } EnEncount1; // size = 0x164 extern const ActorInit En_Encount1_InitVars; diff --git a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c index a5f6b1d7a..f196fa54b 100644 --- a/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c +++ b/src/overlays/actors/ovl_En_Encount2/z_en_encount2.c @@ -284,7 +284,7 @@ void EnEncount2_DrawParticles(EnEncount2* this, GlobalContext* globalCtx) { gDPPipeSync(POLY_XLU_DISP++); gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 255); gDPSetEnvColor(POLY_XLU_DISP++, 250, 180, 255, sPtr->alpha); - Matrix_InsertMatrix(&globalCtx->mf_187FC, MTXMODE_APPLY); + Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_APPLY); Matrix_InsertZRotation_f(DEGTORAD(globalCtx->state.frames * 20.0f), MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); diff --git a/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c b/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c index 0a4a55c4b..184eb8728 100644 --- a/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c +++ b/src/overlays/actors/ovl_En_Encount3/z_en_encount3.c @@ -1,7 +1,7 @@ /* * File: z_en_encount3.c * Overlay: ovl_En_Encount3 - * Description: + * Description: Garo spawner */ #include "z_en_encount3.h" diff --git a/src/overlays/actors/ovl_En_Encount3/z_en_encount3.h b/src/overlays/actors/ovl_En_Encount3/z_en_encount3.h index 49c7ccef4..dbfe78052 100644 --- a/src/overlays/actors/ovl_En_Encount3/z_en_encount3.h +++ b/src/overlays/actors/ovl_En_Encount3/z_en_encount3.h @@ -10,7 +10,7 @@ typedef void (*EnEncount3ActionFunc)(struct EnEncount3*, GlobalContext*); typedef struct EnEncount3 { /* 0x0000 */ Actor actor; /* 0x0144 */ EnEncount3ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x84]; + /* 0x0148 */ char unk_148[0x84]; } EnEncount3; // size = 0x1CC extern const ActorInit En_Encount3_InitVars; diff --git a/src/overlays/actors/ovl_En_Encount4/z_en_encount4.c b/src/overlays/actors/ovl_En_Encount4/z_en_encount4.c index 5a0bc632a..d4f6c4487 100644 --- a/src/overlays/actors/ovl_En_Encount4/z_en_encount4.c +++ b/src/overlays/actors/ovl_En_Encount4/z_en_encount4.c @@ -1,7 +1,7 @@ /* * File: z_en_encount4.c * Overlay: ovl_En_Encount4 - * Description: + * Description: Spawner for Stalchild and Fire Wall in Keeta chase */ #include "z_en_encount4.h" diff --git a/src/overlays/actors/ovl_En_Ending_Hero/z_en_ending_hero.c b/src/overlays/actors/ovl_En_Ending_Hero/z_en_ending_hero.c index 3206eef53..e94c19f25 100644 --- a/src/overlays/actors/ovl_En_Ending_Hero/z_en_ending_hero.c +++ b/src/overlays/actors/ovl_En_Ending_Hero/z_en_ending_hero.c @@ -1,7 +1,7 @@ /* * File: z_en_ending_hero.c * Overlay: ovl_En_Ending_Hero - * Description: + * Description: Mayor Dotour at wedding during the credits */ #include "z_en_ending_hero.h" diff --git a/src/overlays/actors/ovl_En_Ending_Hero2/z_en_ending_hero2.c b/src/overlays/actors/ovl_En_Ending_Hero2/z_en_ending_hero2.c index d6864d741..045bf8deb 100644 --- a/src/overlays/actors/ovl_En_Ending_Hero2/z_en_ending_hero2.c +++ b/src/overlays/actors/ovl_En_Ending_Hero2/z_en_ending_hero2.c @@ -1,7 +1,7 @@ /* * File: z_en_ending_hero2.c * Overlay: ovl_En_Ending_Hero2 - * Description: + * Description: Viscen watching moon disappearance and wedding */ #include "z_en_ending_hero2.h" diff --git a/src/overlays/actors/ovl_En_Ending_Hero3/z_en_ending_hero3.c b/src/overlays/actors/ovl_En_Ending_Hero3/z_en_ending_hero3.c index 4a39d382a..2f9c8391f 100644 --- a/src/overlays/actors/ovl_En_Ending_Hero3/z_en_ending_hero3.c +++ b/src/overlays/actors/ovl_En_Ending_Hero3/z_en_ending_hero3.c @@ -1,7 +1,7 @@ /* * File: z_en_ending_hero3.c * Overlay: ovl_En_Ending_Hero3 - * Description: + * Description: Mutoh watching moon disappearance and wedding */ #include "z_en_ending_hero3.h" diff --git a/src/overlays/actors/ovl_En_Ending_Hero4/z_en_ending_hero4.c b/src/overlays/actors/ovl_En_Ending_Hero4/z_en_ending_hero4.c index 46fca27d6..fd5eae624 100644 --- a/src/overlays/actors/ovl_En_Ending_Hero4/z_en_ending_hero4.c +++ b/src/overlays/actors/ovl_En_Ending_Hero4/z_en_ending_hero4.c @@ -1,7 +1,7 @@ /* * File: z_en_ending_hero4.c * Overlay: ovl_En_Ending_Hero4 - * Description: + * Description: Soldiers watching moon disappearance and Indigo-Go's */ #include "z_en_ending_hero4.h" diff --git a/src/overlays/actors/ovl_En_Ending_Hero5/z_en_ending_hero5.c b/src/overlays/actors/ovl_En_Ending_Hero5/z_en_ending_hero5.c index b7b3d6b8e..77fc67308 100644 --- a/src/overlays/actors/ovl_En_Ending_Hero5/z_en_ending_hero5.c +++ b/src/overlays/actors/ovl_En_Ending_Hero5/z_en_ending_hero5.c @@ -1,7 +1,7 @@ /* * File: z_en_ending_hero5.c * Overlay: ovl_En_Ending_Hero5 - * Description: + * Description: Carpenters watching moon disappearance and Indigo-Go's */ #include "z_en_ending_hero5.h" diff --git a/src/overlays/actors/ovl_En_Estone/z_en_estone.h b/src/overlays/actors/ovl_En_Estone/z_en_estone.h index eec7f2d24..848d41f8b 100644 --- a/src/overlays/actors/ovl_En_Estone/z_en_estone.h +++ b/src/overlays/actors/ovl_En_Estone/z_en_estone.h @@ -10,7 +10,7 @@ typedef void (*EnEstoneActionFunc)(struct EnEstone*, GlobalContext*); typedef struct EnEstone { /* 0x0000 */ Actor actor; /* 0x0144 */ EnEstoneActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x2C2C]; + /* 0x0148 */ char unk_148[0x2C2C]; } EnEstone; // size = 0x2D74 extern const ActorInit En_Estone_InitVars; diff --git a/src/overlays/actors/ovl_En_Fall/z_en_fall.c b/src/overlays/actors/ovl_En_Fall/z_en_fall.c index 43582bf26..155493dbd 100644 --- a/src/overlays/actors/ovl_En_Fall/z_en_fall.c +++ b/src/overlays/actors/ovl_En_Fall/z_en_fall.c @@ -1,10 +1,24 @@ /* * File: z_en_fall.c * Overlay: ovl_En_Fall - * Description: The Moon and related effects + * Description: The moon and related effects, along with the Moon's Tear that falls from its eye. + * + * This actor handles mutliple types of moon as well as a variety of effects. Specifically, it handles: + * - A high-detail moon, used in Termina Field, the Clock Tower, and a few cutscenes + * - A high-detail open-mouthed moon, used in the cutscene prior to warping to the moon's interior. + * - An enlarged high-detail moon, used for when the moon is crashing. + * - A low-detail moon, used everywhere else. Its object file is named "Lodmoon". + * - The Moon's Tear that can be seen falling from the telescope, along with its associated fire trail. + * - The ball of fire that surrounds the moon when it is crashing. + * - The debris that rises from the ground as the moon is crashing. + * - The ring of fire that expands outward when the moon is almost done crashing. */ #include "z_en_fall.h" +#include "objects/object_fall/object_fall.h" +#include "objects/object_fall2/object_fall2.h" +#include "objects/object_lodmoon/object_lodmoon.h" +#include "objects/object_moonston/object_moonston.h" #define FLAGS 0x00000030 @@ -14,16 +28,34 @@ void EnFall_Init(Actor* thisx, GlobalContext* globalCtx); void EnFall_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnFall_Update(Actor* thisx, GlobalContext* globalCtx); -void func_80A6C3FC(EnFall* this, GlobalContext* globalCtx); -void func_80A6C9A8(EnFall* this, GlobalContext* globalCtx); -void func_80A6CA9C(EnFall* this, GlobalContext* globalCtx); -void func_80A6CB74(EnFall* this, GlobalContext* globalCtx); -void func_80A6CD38(EnFall* this, GlobalContext* globalCtx); -void func_80A6CD74(EnFall* this, GlobalContext* globalCtx); -void func_80A6CF60(EnFall* this, GlobalContext* globalCtx); -void func_80A6CF70(EnFall* this, GlobalContext* globalCtx); +void EnFall_Setup(EnFall* this, GlobalContext* globalCtx); +void EnFall_CrashingMoon_PerformCutsceneActions(EnFall* this, GlobalContext* globalCtx); +void EnFall_StoppedOpenMouthMoon_PerformCutsceneActions(EnFall* this, GlobalContext* globalCtx); +void EnFall_StoppedClosedMouthMoon_PerformCutsceneActions(EnFall* this, GlobalContext* globalCtx); +void EnFall_ClockTowerOrTitleScreenMoon_PerformCutsceneActions(EnFall* this, GlobalContext* globalCtx); +void EnFall_Moon_PerformDefaultActions(EnFall* this, GlobalContext* globalCtx); +void EnFall_MoonsTear_Fall(EnFall* this, GlobalContext* globalCtx); +void EnFall_FireBall_Update(Actor* thisx, GlobalContext* globalCtx); +void EnFall_RisingDebris_Update(Actor* thisx, GlobalContext* globalCtx); +void EnFall_FireRing_Update(Actor* thisx, GlobalContext* globalCtx); +void EnFall_Moon_Draw(Actor* thisx, GlobalContext* globalCtx); +void EnFall_OpenMouthMoon_Draw(Actor* thisx, GlobalContext* globalCtx); +void EnFall_LodMoon_DrawWithoutLerp(Actor* thisx, GlobalContext* globalCtx); +void EnFall_LodMoon_DrawWithLerp(Actor* thisx, GlobalContext* globalCtx); +void EnFall_FireBall_Draw(Actor* thisx, GlobalContext* globalCtx); +void EnFall_RisingDebris_Draw(Actor* thisx, GlobalContext* globalCtx); +void EnFall_FireRing_Draw(Actor* thisx, GlobalContext* globalCtx); +void EnFall_MoonsTear_Draw(Actor* thisx, GlobalContext* globalCtx); + +typedef struct { + u8 dListIndex; + Vec3f pos; + Vec3f velocity; + Vec3s rot; +} EnFallDebrisParticle; + +EnFallDebrisParticle debrisParticles[50]; -#if 0 const ActorInit En_Fall_InitVars = { ACTOR_EN_FALL, ACTORCAT_ITEMACTION, @@ -36,75 +68,792 @@ const ActorInit En_Fall_InitVars = { (ActorFunc)NULL, }; -#endif +/** + * Sets the scale of the moon depending on the current day. On the Final Day, + * it also moves the moon closer to the ground depending on the current time. + */ +void EnFall_Moon_AdjustScaleAndPosition(EnFall* this, GlobalContext* globalCtx) { + u16 currentTime = gSaveContext.time; + u16 dayStartTime = this->dayStartTime; + f32 finalDayRelativeHeight; -extern UNK_TYPE D_06000198; -extern UNK_TYPE D_060004C0; -extern UNK_TYPE D_060010E0; -extern UNK_TYPE D_060011D0; -extern UNK_TYPE D_06001220; -extern UNK_TYPE D_06002970; -extern UNK_TYPE D_06004E38; -extern UNK_TYPE D_060077F0; + if (currentTime < dayStartTime) { + finalDayRelativeHeight = 1.0f - (((f32)dayStartTime - (f32)currentTime) * (1.0f / 0x10000)); + } else { + finalDayRelativeHeight = ((f32)currentTime - (f32)dayStartTime) * (1.0f / 0x10000); + } + switch (CURRENT_DAY) { + case 0: + Actor_SetScale(&this->actor, this->scale * 1.2f); + this->actor.world.pos.y = this->actor.home.pos.y; + break; + case 1: + Actor_SetScale(&this->actor, this->scale * 2.4f); + this->actor.world.pos.y = this->actor.home.pos.y; + break; + case 2: + Actor_SetScale(&this->actor, this->scale * 3.6f); + this->actor.world.pos.y = this->actor.home.pos.y; + break; + case 3: + Actor_SetScale(&this->actor, this->scale * 3.6f); + if (EN_FALL_TYPE(&this->actor) == EN_FALL_TYPE_LODMOON_INVERTED_STONE_TOWER) { + this->actor.world.pos.y = + this->actor.home.pos.y + (finalDayRelativeHeight * 6700.0f * (this->scale * 6.25f)); + } else { + this->actor.world.pos.y = + this->actor.home.pos.y - (finalDayRelativeHeight * 6700.0f * (this->scale * 6.25f)); + } + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6BF90.s") +void EnFall_RisingDebris_ResetParticles(EnFall* this) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6C1DC.s") + for (i = 0; i < ARRAY_COUNT(debrisParticles); i++) { + debrisParticles[i].dListIndex = 3; + } + this->activeDebrisParticleCount = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/EnFall_Init.s") +void EnFall_Init(Actor* thisx, GlobalContext* globalCtx) { + EnFall* this = THIS; + s32 objectIndex; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/EnFall_Destroy.s") + this->eyeGlowIntensity = 0.0f; + this->flags = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6C3AC.s") + // This system is basically never used in the final game; all instances + // of EnFall will use the default case. + switch (EN_FALL_SCALE(&this->actor)) { + case 1: + this->scale = 0.08f; + break; + case 2: + this->scale = 0.04f; + break; + case 3: + this->scale = 0.02f; + break; + case 4: + this->scale = 0.01f; + break; + default: + this->scale = 0.16f; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6C3FC.s") + switch (EN_FALL_TYPE(&this->actor)) { + case EN_FALL_TYPE_LODMOON_NO_LERP: + case EN_FALL_TYPE_LODMOON: + case EN_FALL_TYPE_LODMOON_INVERTED_STONE_TOWER: + objectIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_LODMOON); + break; + case EN_FALL_TYPE_MOONS_TEAR: + objectIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_MOONSTON); + break; + case EN_FALL_TYPE_STOPPED_MOON_OPEN_MOUTH: + objectIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_FALL2); + break; + default: + objectIndex = Object_GetIndex(&globalCtx->objectCtx, OBJECT_FALL); + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6C7C0.s") + if (objectIndex < 0) { + Actor_MarkForDeath(&this->actor); + return; + } + this->objIndex = objectIndex; + this->actionFunc = EnFall_Setup; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6C9A8.s") +void EnFall_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6CA9C.s") +/** + * Finds the Termina Field moon so the Moon's Tear can spawn in the correct place. + */ +Actor* EnFall_MoonsTear_GetTerminaFieldMoon(GlobalContext* globalCtx) { + Actor* itemAction = globalCtx->actorCtx.actorList[ACTORCAT_ITEMACTION].first; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6CB74.s") + while (itemAction != NULL) { + if (itemAction->id == ACTOR_EN_FALL && EN_FALL_TYPE(itemAction) == EN_FALL_TYPE_TERMINA_FIELD_MOON) { + return itemAction; + } + itemAction = itemAction->next; + } + return NULL; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6CD38.s") +void EnFall_Setup(EnFall* this, GlobalContext* globalCtx) { + Actor* moon; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6CD74.s") + if (Object_IsLoaded(&globalCtx->objectCtx, this->objIndex)) { + this->actor.objBankIndex = this->objIndex; + this->actionFunc = EnFall_Moon_PerformDefaultActions; + switch (EN_FALL_TYPE(&this->actor)) { + case EN_FALL_TYPE_TITLE_SCREEN_MOON: + this->actor.draw = EnFall_Moon_Draw; + this->actionFunc = EnFall_ClockTowerOrTitleScreenMoon_PerformCutsceneActions; + Actor_SetScale(&this->actor, this->scale); + break; + case EN_FALL_TYPE_STOPPED_MOON_CLOSED_MOUTH: + this->actor.draw = EnFall_Moon_Draw; + this->actionFunc = EnFall_StoppedClosedMouthMoon_PerformCutsceneActions; + Actor_SetScale(&this->actor, this->scale * 3.0f); + if (!(gSaveContext.weekEventReg[0x19] & 2)) { + Actor_MarkForDeath(&this->actor); + } + break; + case EN_FALL_TYPE_CLOCK_TOWER_MOON: + this->actionFunc = EnFall_ClockTowerOrTitleScreenMoon_PerformCutsceneActions; + Actor_SetScale(&this->actor, this->scale * 3.0f); + this->actor.draw = EnFall_Moon_Draw; + if (gSaveContext.weekEventReg[0x19] & 2) { + Actor_MarkForDeath(&this->actor); + } + break; + case EN_FALL_TYPE_CRASHING_MOON: + this->actor.draw = EnFall_Moon_Draw; + Actor_SetScale(&this->actor, this->scale * 5.3999996f); + this->actionFunc = EnFall_CrashingMoon_PerformCutsceneActions; + break; + case EN_FALL_TYPE_CRASH_FIRE_BALL: + this->actor.update = EnFall_FireBall_Update; + this->actor.draw = EnFall_FireBall_Draw; + this->scale = 1.0f; + this->actor.shape.rot.z = 0; + this->fireBallIntensity = 0.0f; + this->fireBallAlpha = 100; + this->actor.shape.rot.x = this->actor.shape.rot.z; + break; + case EN_FALL_TYPE_CRASH_RISING_DEBRIS: + this->actor.update = EnFall_RisingDebris_Update; + this->actor.draw = EnFall_RisingDebris_Draw; + this->scale = 1.0f; + EnFall_RisingDebris_ResetParticles(this); + Actor_SetScale(&this->actor, 1.0f); + this->actor.shape.rot.x = 0; + break; + case EN_FALL_TYPE_LODMOON_NO_LERP: + this->actor.draw = EnFall_LodMoon_DrawWithoutLerp; + this->dayStartTime = CLOCK_TIME(6, 0); + this->currentDay = CURRENT_DAY; + EnFall_Moon_AdjustScaleAndPosition(this, globalCtx); + break; + case EN_FALL_TYPE_LODMOON: + case EN_FALL_TYPE_LODMOON_INVERTED_STONE_TOWER: + this->actor.draw = EnFall_LodMoon_DrawWithLerp; + this->dayStartTime = CLOCK_TIME(6, 0); + this->currentDay = CURRENT_DAY; + EnFall_Moon_AdjustScaleAndPosition(this, globalCtx); + break; + case EN_FALL_TYPE_MOONS_TEAR: + this->actor.update = EnFall_Update; + this->actor.draw = NULL; + this->actionFunc = EnFall_MoonsTear_Fall; + Actor_SetScale(&this->actor, 0.02f); + if (!(globalCtx->actorCtx.unk5 & 2)) { + Actor_MarkForDeath(&this->actor); + } + moon = EnFall_MoonsTear_GetTerminaFieldMoon(globalCtx); + this->actor.child = moon; + if (moon == NULL) { + Actor_MarkForDeath(&this->actor); + } + break; + case EN_FALL_TYPE_STOPPED_MOON_OPEN_MOUTH: + this->actor.draw = NULL; + this->actionFunc = EnFall_StoppedOpenMouthMoon_PerformCutsceneActions; + Actor_SetScale(&this->actor, this->scale * 3.0f); + break; + case EN_FALL_TYPE_CRASH_FIRE_RING: + this->actor.update = EnFall_FireRing_Update; + this->actor.draw = EnFall_FireRing_Draw; + Actor_SetScale(&this->actor, 0.2f); + break; + default: + this->actor.draw = EnFall_Moon_Draw; + this->dayStartTime = CLOCK_TIME(6, 0); + this->currentDay = CURRENT_DAY; + EnFall_Moon_AdjustScaleAndPosition(this, globalCtx); + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6CECC.s") +void EnFall_CrashingMoon_HandleGiantsCutscene(EnFall* this, GlobalContext* globalCtx) { + static s32 sGiantsCutsceneState = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6CF60.s") + if (globalCtx->sceneNum == SCENE_00KEIKOKU && gSaveContext.sceneSetupIndex == 1 && globalCtx->csCtx.unk_12 == 0) { + switch (sGiantsCutsceneState) { + case 0: + if (globalCtx->csCtx.state != 0) { + sGiantsCutsceneState += 2; + } + break; + case 2: + if (CHECK_QUEST_ITEM(QUEST_REMAINS_ODOWLA) && CHECK_QUEST_ITEM(QUEST_REMAINS_GOHT) && + CHECK_QUEST_ITEM(QUEST_REMAINS_GYORG) && CHECK_QUEST_ITEM(QUEST_REMAINS_TWINMOLD)) { + if (gSaveContext.weekEventReg[0x5D] & 4) { + if (ActorCutscene_GetCanPlayNext(0xC)) { + ActorCutscene_Start(0xC, &this->actor); + sGiantsCutsceneState++; + } else { + ActorCutscene_SetIntentToPlay(0xC); + } + } else if (ActorCutscene_GetCanPlayNext(0xB)) { + ActorCutscene_Start(0xB, &this->actor); + gSaveContext.weekEventReg[0x5D] |= 4; + sGiantsCutsceneState++; + } else { + ActorCutscene_SetIntentToPlay(0xB); + } + } else if (globalCtx->csCtx.frames > 1600) { + globalCtx->nextEntranceIndex = 0x2C00; + gSaveContext.nextCutsceneIndex = 0xFFF2; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->unk_1887F = 2; + gSaveContext.nextTransition = 2; + sGiantsCutsceneState = 9; + } + break; + case 9: + globalCtx->csCtx.frames--; + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6CF70.s") +void EnFall_CrashingMoon_PerformCutsceneActions(EnFall* this, GlobalContext* globalCtx) { + EnFall_CrashingMoon_HandleGiantsCutscene(this, globalCtx); + if (func_800EE29C(globalCtx, 0x85)) { + if (func_800EE29C(globalCtx, 0x85) && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x85)]->unk0 == 1) { + this->actor.draw = NULL; + } else { + this->actor.draw = EnFall_Moon_Draw; + if (func_800EE29C(globalCtx, 0x85) && + globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x85)]->unk0 == 2) { + func_800EDF24(&this->actor, globalCtx, func_800EE200(globalCtx, 0x85)); + } + } + } else { + this->actor.draw = NULL; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/EnFall_Update.s") +void EnFall_StoppedOpenMouthMoon_PerformCutsceneActions(EnFall* this, GlobalContext* globalCtx) { + if (func_800EE29C(globalCtx, 0x85)) { + switch (globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x85)]->unk0) { + case 3: + if (this->eyeGlowIntensity == 0.0f) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_MOON_EYE_FLASH); + } + this->eyeGlowIntensity += 0.033333335f; + if (this->eyeGlowIntensity > 1.0f) { + this->eyeGlowIntensity = 1.0f; + } + break; + case 4: + this->actor.draw = EnFall_OpenMouthMoon_Draw; + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D100.s") +void EnFall_StoppedClosedMouthMoon_PerformCutsceneActions(EnFall* this, GlobalContext* globalCtx) { + if (func_800EE29C(globalCtx, 0x85)) { + switch (globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x85)]->unk0) { + case 2: + func_800EDF24(&this->actor, globalCtx, func_800EE200(globalCtx, 0x85)); + break; + case 4: + this->actor.draw = NULL; + break; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D220.s") + if (globalCtx->sceneNum == SCENE_OKUJOU && gSaveContext.sceneSetupIndex == 2) { + switch (globalCtx->csCtx.unk_12) { + case 0: + switch (globalCtx->csCtx.frames) { + case 1060: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_MOON_SCREAM1); + break; + case 1089: + Audio_PlayActorSound2(&this->actor, NA_SE_EV_MOON_CRY); + break; + case 1303: + Audio_PlayActorSound2(&this->actor, NA_SE_EV_SLIP_MOON); + break; + } + if (globalCtx->csCtx.frames >= 1145) { + func_800B9010(&this->actor, NA_SE_EV_FALL_POWER - SFX_FLAG); + } + break; + case 1: + switch (globalCtx->csCtx.frames) { + case 561: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_MOON_SCREAM1); + break; + case 590: + Audio_PlayActorSound2(&this->actor, NA_SE_EV_MOON_CRY); + break; + case 737: + Audio_PlayActorSound2(&this->actor, NA_SE_EV_SLIP_MOON); + break; + } + if (globalCtx->csCtx.frames >= 650) { + func_800B9010(&this->actor, NA_SE_EV_FALL_POWER - SFX_FLAG); + } + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D444.s") +void EnFall_ClockTowerOrTitleScreenMoon_PerformCutsceneActions(EnFall* this, GlobalContext* globalCtx) { + if (globalCtx->csCtx.state != 0 && globalCtx->sceneNum == SCENE_OKUJOU) { + func_800B9010(&this->actor, NA_SE_EV_MOON_FALL - SFX_FLAG); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D504.s") +/** + * This is rarely used in the final game. One example of where it *is* used + * is when the moon is crashing; there is a second, smaller moon hidden within + * the larger moon that uses this action function. + */ +void EnFall_Moon_PerformDefaultActions(EnFall* this, GlobalContext* globalCtx) { + u16 currentDay; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D698.s") + if (func_800EE29C(globalCtx, 0x85)) { + if (func_800EE29C(globalCtx, 0x85) && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x85)]->unk0 == 1) { + this->actor.draw = NULL; + } else { + Actor_SetScale(&this->actor, this->scale * 3.6f); + this->actor.draw = EnFall_Moon_Draw; + if (func_800EE29C(globalCtx, 0x85) && + globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x85)]->unk0 == 2) { + func_800EDF24(&this->actor, globalCtx, func_800EE200(globalCtx, 0x85)); + } + } + } else { + if (this->actor.draw == NULL) { + this->actor.draw = EnFall_Moon_Draw; + } + currentDay = CURRENT_DAY; + if ((u16)this->currentDay != (u32)currentDay) { + this->currentDay = currentDay; + this->dayStartTime = gSaveContext.time; + } + EnFall_Moon_AdjustScaleAndPosition(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D75C.s") +void EnFall_MoonsTear_Initialize(EnFall* this) { + s32 pad[2]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D88C.s") + this->actor.draw = EnFall_MoonsTear_Draw; + if (this->actor.child != NULL) { + // The focus of the child needs to be shifted in EnFall_Moon_Draw first, + // otherwise the tear will spawn in the wrong place. + Math_Vec3f_Copy(&this->actor.world.pos, &this->actor.child->focus.pos); + } + this->actor.world.rot.y = Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos); + this->actor.world.rot.x = Math_Vec3f_Pitch(&this->actor.world.pos, &this->actor.home.pos); + this->actor.speedXZ = Math_Vec3f_DistXYZ(&this->actor.world.pos, &this->actor.home.pos) / 82.0f; + this->actor.shape.rot.x = this->actor.world.rot.x; + this->actor.shape.rot.y = this->actor.world.rot.y; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6D98C.s") +void EnFall_DoNothing(EnFall* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6DA7C.s") +void EnFall_MoonsTear_Fall(EnFall* this, GlobalContext* globalCtx) { + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6DC20.s") + if (func_800EE29C(globalCtx, 0x205) && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x205)]->unk0 == 2 && + this->actor.draw == NULL) { + EnFall_MoonsTear_Initialize(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6DC40.s") + if (this->actor.draw != NULL) { + if (Math_Vec3f_StepTo(&this->actor.world.pos, &this->actor.home.pos, this->actor.speedXZ) <= 0.0f) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_GORON_BOUND_1); + gSaveContext.weekEventReg[0x4A] |= 0x80; + gSaveContext.weekEventReg[0x4A] |= 0x20; + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_TEST, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, -2); + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, CLEAR_TAG_LARGE_EXPLOSION); + this->actor.draw = NULL; + this->actionFunc = EnFall_DoNothing; + } else { + func_800B9010(&this->actor, NA_SE_EV_MOONSTONE_FALL - SFX_FLAG); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6DD3C.s") +void EnFall_Update(Actor* thisx, GlobalContext* globalCtx) { + EnFall* this = THIS; + this->actionFunc(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6E07C.s") +/** + * Updates the alpha for every vertex in the fire ball so that some parts of + * the sphere are more transparent or opaque than others. + */ +void EnFall_FireBall_SetPerVertexAlpha(f32 fireBallAlpha) { + static u8 sAlphaTableIndex[] = { + 4, 4, 0, 1, 1, 1, 1, 1, 1, 3, 3, 0, 0, 3, 0, 1, 1, 1, 4, 0, 4, 0, 1, 1, 1, 3, 0, 3, 0, 1, 1, 1, 4, 4, 1, + 1, 0, 4, 4, 0, 1, 1, 1, 1, 1, 1, 3, 3, 0, 0, 3, 3, 0, 0, 1, 1, 1, 1, 1, 4, 0, 4, 4, 0, 4, 4, 1, 1, 1, 1, + 1, 1, 3, 3, 0, 0, 3, 3, 0, 0, 1, 1, 1, 1, 1, 1, 4, 4, 0, 4, 0, 1, 1, 1, 3, 0, 3, 3, 0, 0, 1, 1, 1, 1, 1, + 1, 4, 4, 0, 4, 4, 0, 1, 1, 1, 1, 1, 1, 3, 3, 0, 0, 0, 0, 0, 2, 2, 1, 1, 0, 0, 2, 2, 0, 1, 1, 0, 0, 1, 0, + 2, 0, 0, 1, 0, 2, 0, 0, 2, 1, 2, 0, 1, 0, 1, 0, 0, 1, 2, 2, 0, 0, 2, 1, 1, 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, + 0, 0, 2, 0, 2, 2, 0, 1, 1, 0, 0, 1, 0, 0, 1, 2, 2, 0, 0, 0, 2, 2, 1, 1, 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, + }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6E214.s") + s32 pad; + u8 perVertexAlphaTable[5]; + Vtx* vertices = Lib_SegmentedToVirtual(&object_fall_Vtx_0004C0); + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fall/func_80A6E37C.s") + if (fireBallAlpha > 1.0f) { + fireBallAlpha = 1.0f; + } + perVertexAlphaTable[0] = 0; + perVertexAlphaTable[1] = (s8)(255.0f * fireBallAlpha); + perVertexAlphaTable[2] = (s8)(155.0f * fireBallAlpha); + perVertexAlphaTable[3] = (s8)(104.0f * fireBallAlpha); + perVertexAlphaTable[4] = (s8)(54.0f * fireBallAlpha); + + for (i = 0; i < ARRAY_COUNT(sAlphaTableIndex); i++, vertices++) { + vertices->v.cn[3] = perVertexAlphaTable[sAlphaTableIndex[i]]; + } +} + +void EnFall_FireBall_Update(Actor* thisx, GlobalContext* globalCtx) { + EnFall* this = THIS; + + if (globalCtx->sceneNum == SCENE_00KEIKOKU && gSaveContext.sceneSetupIndex == 0 && globalCtx->csCtx.unk_12 == 2) { + globalCtx->skyboxCtx.rotY -= 0.05f; + } + + if (func_800EE29C(globalCtx, 0x1C2)) { + this->actor.draw = EnFall_FireBall_Draw; + if (this->flags & EN_FALL_FLAG_FIRE_BALL_INTENSIFIES) { + this->fireBallIntensity += 0.01f; + if (this->fireBallIntensity > 1.0f) { + this->fireBallIntensity = 1.0f; + } + } + func_800EDF24(&this->actor, globalCtx, func_800EE200(globalCtx, 0x1C2)); + + switch (globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x1C2)]->unk0) { + default: + this->actor.draw = NULL; + this->fireBallAlpha = 0; + break; + case 2: + if (this->fireBallAlpha < 100) { + this->fireBallAlpha += 4; + } + if (this->fireBallAlpha > 100) { + this->fireBallAlpha = 100; + } + EnFall_FireBall_SetPerVertexAlpha(this->fireBallAlpha * 0.01f); + break; + case 3: + if (this->fireBallAlpha > 0) { + this->fireBallAlpha -= 2; + } + if (this->fireBallAlpha < 0) { + this->fireBallAlpha = 0; + } + EnFall_FireBall_SetPerVertexAlpha(this->fireBallAlpha * 0.01f); + break; + case 4: + this->flags |= EN_FALL_FLAG_FIRE_BALL_INTENSIFIES; + break; + case 5: + break; + } + } else { + this->actor.draw = NULL; + } + + if (func_800EE29C(globalCtx, 0x1C2) && this->fireBallAlpha > 0) { + func_8019F128(NA_SE_EV_MOON_FALL_LAST - SFX_FLAG); + } + Actor_SetScale(&this->actor, this->scale * 1.74f); +} + +void EnFall_RisingDebris_UpdateParticles(EnFall* this) { + s32 i; + + for (i = 0; i < ARRAY_COUNT(debrisParticles); i++) { + if (debrisParticles[i].dListIndex < 3) { + debrisParticles[i].pos.x += debrisParticles[i].velocity.x; + debrisParticles[i].pos.y += debrisParticles[i].velocity.y; + debrisParticles[i].pos.z += debrisParticles[i].velocity.z; + debrisParticles[i].rot.x += 0x64; + debrisParticles[i].rot.y += 0xC8; + debrisParticles[i].rot.z += 0x12C; + if ((this->actor.world.pos.y + 3000.0f) < debrisParticles[i].pos.y) { + debrisParticles[i].dListIndex = 3; + this->activeDebrisParticleCount--; + } + } + } +} + +s32 EnFall_RisingDebris_InitializeParticles(EnFall* this) { + s16 angle; + s32 i; + f32 scale; + + for (i = 0; i < ARRAY_COUNT(debrisParticles); i++) { + if (debrisParticles[i].dListIndex >= 3) { + debrisParticles[i].dListIndex = (s32)Rand_ZeroFloat(3.0f); + debrisParticles[i].pos.x = this->actor.world.pos.x; + debrisParticles[i].pos.y = this->actor.world.pos.y; + debrisParticles[i].pos.z = this->actor.world.pos.z; + angle = randPlusMinusPoint5Scaled(0x10000); + scale = (1.0f - (Rand_ZeroFloat(1.0f) * Rand_ZeroFloat(1.0f))) * 3000.0f; + debrisParticles[i].pos.x += Math_SinS(angle) * scale; + debrisParticles[i].pos.z += Math_CosS(angle) * scale; + debrisParticles[i].velocity.x = 0.0f; + debrisParticles[i].velocity.z = 0.0f; + debrisParticles[i].velocity.y = 80.0f; + debrisParticles[i].rot.x = randPlusMinusPoint5Scaled(0x10000); + debrisParticles[i].rot.y = randPlusMinusPoint5Scaled(0x10000); + debrisParticles[i].rot.z = randPlusMinusPoint5Scaled(0x10000); + this->activeDebrisParticleCount++; + return true; + } + } + + return false; +} + +void EnFall_RisingDebris_Update(Actor* thisx, GlobalContext* globalCtx) { + EnFall* this = THIS; + + if (func_800EE29C(globalCtx, 0x1C3)) { + if (func_800EE29C(globalCtx, 0x1C3) && + globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x1C3)]->unk0 == 2) { + EnFall_RisingDebris_UpdateParticles(this); + EnFall_RisingDebris_InitializeParticles(this); + } else if (this->activeDebrisParticleCount != 0) { + EnFall_RisingDebris_ResetParticles(this); + } + } else if (thisx->home.rot.x != 0) { + EnFall_RisingDebris_UpdateParticles(this); + EnFall_RisingDebris_InitializeParticles(this); + } +} + +void EnFall_FireRing_Update(Actor* thisx, GlobalContext* globalCtx) { + EnFall* this = THIS; + + if (func_800EE29C(globalCtx, 0x1C2) && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x1C2)]->unk0 == 5) { + if (!(this->flags & EN_FALL_FLAG_FIRE_RING_APPEARS)) { + Audio_PlayActorSound2(&this->actor, NA_SE_IT_DM_RING_EXPLOSION); + } + this->flags |= EN_FALL_FLAG_FIRE_RING_APPEARS; + } + if (this->flags & EN_FALL_FLAG_FIRE_RING_APPEARS) { + this->fireRingAlpha += 0.033333335f; + if (this->fireRingAlpha > 1.0f) { + this->fireRingAlpha = 1.0f; + } + if (this->actor.scale.x < 18.0f) { + this->actor.scale.x += 0.2f; + } + this->actor.scale.z = this->actor.scale.x; + this->actor.scale.y = Math_SinS(this->fireWallYScale) * 5.0f; + if (this->fireWallYScale < 0x4000) { + this->fireWallYScale += 0x147; + } + } +} + +void EnFall_Moon_Draw(Actor* thisx, GlobalContext* globalCtx) { + // This offsets the moon's focus so that the Moon's Tear actually falls + // out of its eye when looking at it through the telescope. + static Vec3f sFocusOffset[] = { 1800.0f, 1000.0f, 4250.0f }; + EnFall* this = THIS; + s32 primColor; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + Matrix_MultiplyVector3fByState(sFocusOffset, &this->actor.focus.pos); + primColor = (this->eyeGlowIntensity * 200.0f) + 40.0f; + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x80, primColor, primColor, primColor, 255); + gSPDisplayList(POLY_OPA_DISP++, object_fall_DL_0077F0); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnFall_OpenMouthMoon_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnFall* this = THIS; + s32 primColor; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + primColor = (this->eyeGlowIntensity * 200.0f) + 40.0f; + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x80, primColor, primColor, primColor, 255); + gSPDisplayList(POLY_OPA_DISP++, object_fall2_DL_002970); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnFall_LodMoon_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnFall* this = THIS; + s32 primColor; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 20, 25, 30, 0, 0x3E7, 0x3200); + gDPSetRenderMode(POLY_OPA_DISP++, G_RM_PASS, G_RM_AA_ZB_OPA_SURF2); + gSPLoadGeometryMode(POLY_OPA_DISP++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_SHADING_SMOOTH); + primColor = (this->eyeGlowIntensity * 200.0f) + 40.0f; + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0x80, primColor, primColor, primColor, 255); + gSPDisplayList(POLY_OPA_DISP++, object_lodmoon_DL_0010E0); + gSPLoadGeometryMode(POLY_OPA_DISP++, G_ZBUFFER | G_SHADE | G_CULL_BACK | G_LIGHTING | G_SHADING_SMOOTH); + gSPDisplayList(POLY_OPA_DISP++, object_lodmoon_DL_001158); + POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnFall_LodMoon_DrawWithoutLerp(Actor* thisx, GlobalContext* globalCtx) { + EnFall_LodMoon_Draw(thisx, globalCtx); +} + +/** + * If the moon is more than 9000 units away from the eye, this will lerp it + * to be 9000 units away before drawing it. + */ +void EnFall_LodMoon_DrawWithLerp(Actor* thisx, GlobalContext* globalCtx) { + f32 distanceToEye = Actor_DistanceToPoint(thisx, &globalCtx->view.eye); + f32 scale; + Vec3f translation; + + if (distanceToEye > 9000.0f) { + scale = 9000.0f / distanceToEye; + translation.x = (-(globalCtx->view.eye.x - thisx->world.pos.x) * scale) + globalCtx->view.eye.x; + translation.y = (-(globalCtx->view.eye.y - thisx->world.pos.y) * scale) + globalCtx->view.eye.y; + translation.z = (-(globalCtx->view.eye.z - thisx->world.pos.z) * scale) + globalCtx->view.eye.z; + Matrix_InsertTranslation(translation.x, translation.y, translation.z, MTXMODE_NEW); + Matrix_Scale(thisx->scale.x, thisx->scale.y, thisx->scale.z, MTXMODE_APPLY); + Matrix_RotateY(thisx->shape.rot.y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(thisx->shape.rot.x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(thisx->shape.rot.z, MTXMODE_APPLY); + } + EnFall_LodMoon_Draw(thisx, globalCtx); +} + +void EnFall_FireBall_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnFall* this = THIS; + u32 gameplayFrames = globalCtx->gameplayFrames; + + OPEN_DISPS(globalCtx->state.gfxCtx); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C2DC(globalCtx->state.gfxCtx); + this->fireBallYTexScroll1 += (s32)(4.0f + (this->fireBallIntensity * 12.0f)); + this->fireBallYTexScroll2 += (s32)(2.0f + (this->fireBallIntensity * 6.0f)); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, + (s32)(((1.0f - this->fireBallIntensity) * 160.0f) + (255.0f * this->fireBallIntensity)), + (s32)((70.0f * (1.0f - this->fireBallIntensity)) + (255.0f * this->fireBallIntensity)), + (s32)(70.0f * (1.0f - this->fireBallIntensity)), 255); + gDPSetEnvColor( + POLY_XLU_DISP++, (s32)(((1.0f - this->fireBallIntensity) * 50.0f) + (200.0f * this->fireBallIntensity)), + (s32)(20.0f * (1.0f - this->fireBallIntensity)), (s32)(20.0f * (1.0f - this->fireBallIntensity)), 255); + + // Glowing sphere of fire + gSPSegment(POLY_XLU_DISP++, 0x09, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, gameplayFrames, -this->fireBallYTexScroll2, 64, 64, 1, + -gameplayFrames, -this->fireBallYTexScroll1, 64, 64)); + + // "Flecks" of fire + gSPSegment(POLY_XLU_DISP++, 0x0A, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, gameplayFrames * 2, -this->fireBallYTexScroll1, 64, 64, 1, + -gameplayFrames * 2, -this->fireBallYTexScroll1, 64, 64)); + + gDPSetColorDither(POLY_XLU_DISP++, G_CD_NOISE); + gDPSetAlphaDither(POLY_XLU_DISP++, G_AD_NOISE); + gSPDisplayList(POLY_XLU_DISP++, object_fall_DL_0011D0); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnFall_RisingDebris_Draw(Actor* thisx, GlobalContext* globalCtx) { + static Gfx* sDebrisDLists[] = { object_fall_DL_000220, object_fall_DL_000428, object_fall_DL_000498 }; + EnFall* this = THIS; + f32 scale = this->scale * 0.06f; + s32 i; + + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C28C(globalCtx->state.gfxCtx); + gSPDisplayList(POLY_OPA_DISP++, object_fall_DL_000198); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, 255); + for (i = 0; i < ARRAY_COUNT(debrisParticles); i++) { + if (debrisParticles[i].dListIndex < 3) { + Matrix_InsertTranslation(debrisParticles[i].pos.x, debrisParticles[i].pos.y, debrisParticles[i].pos.z, + MTXMODE_NEW); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + Matrix_InsertRotation(debrisParticles[i].rot.x, debrisParticles[i].rot.y, debrisParticles[i].rot.z, + MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, sDebrisDLists[debrisParticles[i].dListIndex]); + } + } + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnFall_FireRing_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnFall* this = THIS; + + if (!(this->fireRingAlpha <= 0.0f)) { + if (this->fireRingAlpha > 1.0f) { + this->fireRingAlpha = 1.0f; + } + OPEN_DISPS(globalCtx->state.gfxCtx); + AnimatedMat_DrawXlu(globalCtx, Lib_SegmentedToVirtual(&object_fall_Matanimheader_004E38)); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C2DC(globalCtx->state.gfxCtx); + gDPSetColorDither(POLY_XLU_DISP++, G_CD_NOISE); + gDPSetAlphaDither(POLY_XLU_DISP++, G_AD_NOISE); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 255, 255, 255, (s32)(this->fireRingAlpha * 255.0f)); + gSPDisplayList(POLY_XLU_DISP++, object_fall_DL_003C30); + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void EnFall_MoonsTear_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + + OPEN_DISPS(globalCtx->state.gfxCtx); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_moonston_Matanimheader_001220)); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C28C(globalCtx->state.gfxCtx); + gSPDisplayList(POLY_OPA_DISP++, object_moonston_DL_000400); + Matrix_Scale(3.0f, 3.0f, 6.0f, MTXMODE_APPLY); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C2DC(globalCtx->state.gfxCtx); + gSPDisplayList(POLY_XLU_DISP++, object_moonston_DL_0004C8); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Fall/z_en_fall.h b/src/overlays/actors/ovl_En_Fall/z_en_fall.h index fb149f7e5..0124087d9 100644 --- a/src/overlays/actors/ovl_En_Fall/z_en_fall.h +++ b/src/overlays/actors/ovl_En_Fall/z_en_fall.h @@ -3,14 +3,54 @@ #include "global.h" +#define EN_FALL_SCALE(thisx) ((thisx)->params & 0x7F) +#define EN_FALL_TYPE(thisx) (((thisx)->params & 0xF80) >> 7) + +#define EN_FALL_FLAG_FIRE_BALL_INTENSIFIES (1 << 0) +#define EN_FALL_FLAG_FIRE_RING_APPEARS (1 << 1) + +typedef enum { + /* 0 */ EN_FALL_TYPE_TERMINA_FIELD_MOON, + /* 1 */ EN_FALL_TYPE_TITLE_SCREEN_MOON, + /* 2 */ EN_FALL_TYPE_CRASHING_MOON, + /* 3 */ EN_FALL_TYPE_CRASH_FIRE_BALL, + /* 4 */ EN_FALL_TYPE_CRASH_RISING_DEBRIS, + /* 5 */ EN_FALL_TYPE_LODMOON_NO_LERP, // unused in final game + /* 6 */ EN_FALL_TYPE_LODMOON, + /* 7 */ EN_FALL_TYPE_STOPPED_MOON_CLOSED_MOUTH, + /* 8 */ EN_FALL_TYPE_MOONS_TEAR, + /* 9 */ EN_FALL_TYPE_CLOCK_TOWER_MOON, + /* 10 */ EN_FALL_TYPE_STOPPED_MOON_OPEN_MOUTH, + /* 11 */ EN_FALL_TYPE_CRASH_FIRE_RING, + /* 12 */ EN_FALL_TYPE_LODMOON_INVERTED_STONE_TOWER, +} EnFallType; + struct EnFall; typedef void (*EnFallActionFunc)(struct EnFall*, GlobalContext*); typedef struct EnFall { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1C]; - /* 0x0160 */ EnFallActionFunc actionFunc; + /* 0x000 */ Actor actor; + /* 0x144 */ s16 dayStartTime; + /* 0x146 */ s16 currentDay; + /* 0x148 */ u8 objIndex; + /* 0x14C */ f32 scale; + /* 0x150 */ union { + f32 eyeGlowIntensity; + f32 fireBallIntensity; + f32 fireRingAlpha; + }; + /* 0x154 */ u16 flags; + /* 0x158 */ union { + s32 fireBallAlpha; + s32 activeDebrisParticleCount; + }; + /* 0x15C */ union { + s16 fireBallYTexScroll1; + s16 fireWallYScale; + }; + /* 0x15E */ s16 fireBallYTexScroll2; + /* 0x160 */ EnFallActionFunc actionFunc; } EnFall; // size = 0x164 extern const ActorInit En_Fall_InitVars; diff --git a/src/overlays/actors/ovl_En_Fg/z_en_fg.c b/src/overlays/actors/ovl_En_Fg/z_en_fg.c index 197f07606..f91ee7a31 100644 --- a/src/overlays/actors/ovl_En_Fg/z_en_fg.c +++ b/src/overlays/actors/ovl_En_Fg/z_en_fg.c @@ -383,7 +383,7 @@ void EnFg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec if ((limbIndex == 7) || (limbIndex == 8)) { OPEN_DISPS(globalCtx->state.gfxCtx); Matrix_StatePush(); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, *dList); Matrix_StatePop(); @@ -477,7 +477,7 @@ void EnFg_DrawDust(GlobalContext* globalCtx, EnFgEffectDust* dustEffect) { gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 0, 0, 0, alpha); gDPPipeSync(POLY_XLU_DISP++); Matrix_InsertTranslation(dustEffect->pos.x, dustEffect->pos.y, dustEffect->pos.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(dustEffect->xyScale, dustEffect->xyScale, 1.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); diff --git a/src/overlays/actors/ovl_En_Firefly/z_en_firefly.h b/src/overlays/actors/ovl_En_Firefly/z_en_firefly.h index 72a4739cb..e4439ec36 100644 --- a/src/overlays/actors/ovl_En_Firefly/z_en_firefly.h +++ b/src/overlays/actors/ovl_En_Firefly/z_en_firefly.h @@ -34,7 +34,7 @@ typedef struct EnFirefly { /* 0x2F4 */ u32 unk_2F4; /* 0x2F8 */ Vec3f unk_2F8; /* 0x304 */ Vec3f unk_304; - /* 0x304 */ Vec3f unk_310; + /* 0x310 */ Vec3f unk_310; /* 0x31C */ ColliderSphere collider; } EnFirefly; // size = 0x374 diff --git a/src/overlays/actors/ovl_En_Fish/z_en_fish.c b/src/overlays/actors/ovl_En_Fish/z_en_fish.c index 61f08534b..8368dbc7d 100644 --- a/src/overlays/actors/ovl_En_Fish/z_en_fish.c +++ b/src/overlays/actors/ovl_En_Fish/z_en_fish.c @@ -5,6 +5,7 @@ */ #include "z_en_fish.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x00000000 @@ -15,19 +16,56 @@ void EnFish_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnFish_Update(Actor* thisx, GlobalContext* globalCtx); void EnFish_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_8091FA60[1] = { +void func_8091DF68(Actor* thisx, GlobalContext* globalCtx); +void func_8091E070(EnFish* this); +void func_8091E128(Actor* thisx, GlobalContext* globalCtx); +void func_8091E2E0(EnFish* this); +void func_8091E34C(Actor* thisx, GlobalContext* globalCtx2); +void func_8091E5EC(EnFish* this); +void func_8091E658(Actor* thisx, GlobalContext* globalCtx); +void func_8091E810(EnFish* this); +void func_8091E880(Actor* thisx, GlobalContext* globalCtx); +void func_8091E9A4(EnFish* this); +void func_8091EAF0(Actor* thisx, GlobalContext* globalCtx); +void func_8091ECF4(EnFish* this); +void func_8091ED70(Actor* thisx, GlobalContext* globalCtx); +void func_8091EF30(EnFish* this); +void func_8091EFE8(Actor* thisx, GlobalContext* globalCtx); +void func_8091F344(EnFish* this); +void func_8091F3BC(Actor* thisx, GlobalContext* globalCtx); +void func_8091F994(Actor* thisx, GlobalContext* globalCtx); + +static ColliderJntSphElementInit sJntSphElementsInit[1] = { { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 5 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_8091FA84 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 1, D_8091FA60, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit, +}; + +static Color_RGB8 D_8091FA94[] = { + { 255, 155, 55 }, + { 255, 47, 157 }, + { 215, 97, 7 }, }; const ActorInit En_Fish_InitVars = { @@ -42,87 +80,874 @@ const ActorInit En_Fish_InitVars = { (ActorFunc)EnFish_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_8091FAC0[] = { +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 720, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 40, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 40, ICHAIN_STOP), }; -#endif +f32 func_8091D630(Vec3f* arg0, Vec3f* arg1) { + return SQ(arg0->x - arg1->x) + SQ(arg0->z - arg1->z); +} -extern ColliderJntSphElementInit D_8091FA60[1]; -extern ColliderJntSphInit D_8091FA84; -extern InitChainEntry D_8091FAC0[]; +void func_8091D660(EnFish* this) { + Animation_Change(&this->skelAnime, &gameplay_keep_Anim_02F0EC, 1.0f, 0.0f, + Animation_GetLastFrame(&gameplay_keep_Anim_02F0EC), 1, 2.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091D630.s") +void func_8091D6C4(EnFish* this) { + Animation_Change(&this->skelAnime, &gameplay_keep_Anim_02E65C, 1.0f, 0.0f, + Animation_GetLastFrame(&gameplay_keep_Anim_02E65C), 1, 2.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091D660.s") +void func_8091D728(EnFish* this) { + f32 phi_f0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091D6C4.s") + this->actor.scale.x = this->unk_250 * this->unk_25C; + this->actor.scale.y = this->unk_254 * this->unk_25C; + this->actor.scale.z = this->unk_258 * this->unk_25C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091D728.s") + if (this->actor.scale.z > 0.00001f) { + phi_f0 = 1.0f / this->actor.scale.z; + } else { + phi_f0 = 0.0f; + } + this->unk_264 = 16.0f * phi_f0; + this->unk_266 = 12.0f * phi_f0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091D7C4.s") +void func_8091D7C4(EnFish* this) { + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091D840.s") + Math_ScaledStepToS(&this->actor.world.rot.x, this->unk_268, this->unk_26E); + Math_ScaledStepToS(&this->actor.world.rot.y, this->unk_26A, this->unk_270); + if (this->actor.world.rot.z != this->unk_26C) { + Math_ScaledStepToS(&this->actor.world.rot.z, this->unk_26C, this->unk_272); + } + this->actor.shape.rot = this->actor.world.rot; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091D904.s") +void func_8091D840(Actor* thisx, GlobalContext* globalCtx, s32 arg2, f32 arg3) { + EnFish* this = THIS; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091D944.s") + for (i = 0; i < arg2; i++) { + EffectSsBubble_Spawn(globalCtx, &this->actor.world.pos, 0.0f, arg3, arg3, (Rand_ZeroOne() * 0.09f) + 0.06f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091DA14.s") +void func_8091D904(EnFish* this) { + this->unk_242 = 400; + this->unk_25C = this->unk_260 * 0.1f; + func_8091D728(this); + this->actor.draw = NULL; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/EnFish_Init.s") +Actor* func_8091D944(EnFish* this, GlobalContext* globalCtx) { + f32 distSq; + Actor* retActor = NULL; + f32 minDistSq = FLT_MAX; + Actor* foundActor = globalCtx->actorCtx.actorList[ACTORCAT_ITEMACTION].first; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/EnFish_Destroy.s") + while (foundActor != NULL) { + if ((foundActor->id == ACTOR_EN_FISH) && (foundActor->params == ENFISH_2) && + (foundActor->room == this->actor.room)) { + distSq = Math3D_Vec3fDistSq(&foundActor->world.pos, &this->actor.world.pos); + if (retActor == NULL) { + retActor = foundActor; + minDistSq = distSq; + } else if (distSq < minDistSq) { + minDistSq = distSq; + } + } + foundActor = foundActor->next; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091DD48.s") + return retActor; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091DDF4.s") +s32 func_8091DA14(EnFish* this, GlobalContext* globalCtx) { + return globalCtx->sceneNum == SCENE_LABO && func_8091D944(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091DEE4.s") +void EnFish_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnFish* this = THIS; + s16 sp36 = this->actor.params; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091DF68.s") + Collider_InitJntSph(globalCtx, &this->collider); + if (sp36 == ENFISH_2) { + this->actor.draw = NULL; + this->actor.update = func_8091F994; + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091E070.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + this->unk_250 = 1.0f; + this->unk_254 = 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091E128.s") + if (sp36 == ENFISH_MINUS1) { + this->unk_258 = (Rand_ZeroOne() * 0.9f) + 0.6f; + this->unk_25C = ((Rand_ZeroOne() * 1.2f) + 0.6f) * 0.01f; + } else { + this->unk_258 = 1.0f; + this->unk_25C = 0.01f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091E2E0.s") + this->unk_260 = this->unk_25C; + func_8091D728(this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091E34C.s") + if ((this->unk_258 * this->unk_25C * 100.0f) < 1.02f) { + this->unk_278 = 2; + } else if ((this->unk_258 * this->unk_25C * 100.0f) < 2.0f) { + this->unk_278 = 1; + } else { + this->unk_278 = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091E5EC.s") + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gameplay_keep_Skel_02F028, &gameplay_keep_Anim_02F0EC, + this->jointTable, this->morphTable, 7); + Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElements); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091E658.s") + this->actor.colChkInfo.mass = this->unk_25C * 30.0f; + this->unk_244 = (u32)Rand_Next() >> 0x10; + this->unk_246 = (u32)Rand_Next() >> 0x10; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091E810.s") + if (sp36 == ENFISH_0) { + this->actor.flags |= 0x10; + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 8.0f); + func_8091E810(this); + } else if (sp36 == ENFISH_1) { + func_8091F344(this); + } else { + func_8091E070(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091E880.s") +void EnFish_Destroy(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnFish* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091E9A4.s") + Collider_DestroyJntSph(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091EAF0.s") +void func_8091DD48(EnFish* this) { + this->actor.shape.yOffset += (Math_SinS(this->unk_246) * 5.0f) + (Math_SinS(this->unk_244) * 10.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091ECF4.s") + if (this->actor.shape.yOffset < -200.0f) { + this->actor.shape.yOffset = -200.0f; + } else if (this->actor.shape.yOffset > 200.0f) { + this->actor.shape.yOffset = 200.0f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091ED70.s") +s32 func_8091DDF4(EnFish* this, GlobalContext* globalCtx) { + s32 pad; + Player* player = GET_PLAYER(globalCtx); + Vec3f sp1C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091EF30.s") + if (this->actor.xzDistToPlayer < 50.0f) { + sp1C.x = (Math_SinS(BINANG_ROT180(this->actor.yawTowardsPlayer)) * 30.0f) + player->actor.world.pos.x; + sp1C.y = player->actor.world.pos.y; + sp1C.z = (Math_CosS(BINANG_ROT180(this->actor.yawTowardsPlayer)) * 30.0f) + player->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091EFE8.s") + if (func_8091D630(&sp1C, &this->actor.world.pos) <= SQ(30.0f)) { + return true; + } + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091F344.s") +void func_8091DEE4(EnFish* this) { + static s16 D_8091FACC[] = { 85, 60, 45 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091F3BC.s") + this->actor.gravity = 0.0f; + this->actor.minVelocityY = 0.0f; + this->unk_240 = Rand_S16Offset(5, D_8091FACC[this->unk_278]); + this->unk_248 = 0; + this->unk_26E = 400; + this->unk_272 = 400; + this->unk_268 = 0; + this->unk_26C = 0; + func_8091D660(this); + this->unk_24C = 0.0f; + this->unkFunc = func_8091DF68; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091F5A4.s") +void func_8091DF68(Actor* thisx, GlobalContext* globalCtx) { + EnFish* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091F830.s") + func_8091DD48(this); + Math_SmoothStepToF(&thisx->speedXZ, 0.0f, 0.05f, 0.3f, 0.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/EnFish_Update.s") + if ((thisx->speedXZ * 1.4f) + 0.8f > 2.0f) { + this->skelAnime.playSpeed = 2.0f; + } else { + this->skelAnime.playSpeed = (thisx->speedXZ * 1.4f) + 0.8f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/func_8091F994.s") + this->unk_270 >>= 1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fish/EnFish_Draw.s") + if (this->unk_240 <= 0) { + func_8091E070(this); + } else if (thisx == thisx->child) { + func_8091E5EC(this); + } else if ((thisx->xzDistToPlayer < 60.0f) || (this->unk_276 > 0)) { + func_8091E2E0(this); + } +} + +void func_8091E070(EnFish* this) { + static s16 D_8091FAD4[] = { 20, 30, 40 }; + s16 phi_a1; + + this->actor.gravity = 0.0f; + this->actor.minVelocityY = 0.0f; + + if ((Rand_Next() & 3) == 0) { + if (((Rand_Next() & 7) == 0) && (this->unk_278 != 0)) { + phi_a1 = 80; + } else { + phi_a1 = 45; + } + } else { + phi_a1 = D_8091FAD4[this->unk_278]; + } + this->unk_240 = Rand_S16Offset(15, phi_a1); + this->unk_248 = 0; + this->unk_26E = 400; + this->unk_272 = 400; + this->unk_26C = 0; + func_8091D660(this); + this->unkFunc = func_8091E128; +} + +void func_8091E128(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnFish* this = THIS; + + func_8091DD48(this); + Math_SmoothStepToF(&thisx->speedXZ, 1.8f, 0.08f, 0.4f, 0.0f); + + if ((func_8091D630(&thisx->world.pos, &thisx->home.pos) > SQ(80.0f)) || (this->unk_240 < 4)) { + this->unk_270 = this->unk_264; + this->unk_26A = Math_Vec3f_Yaw(&thisx->world.pos, &thisx->home.pos); + this->unk_24C = 1.0f; + } else if ((thisx->child != NULL) && (thisx != thisx->child)) { + this->unk_270 = this->unk_264; + this->unk_26A = Math_Vec3f_Yaw(&thisx->world.pos, &thisx->child->world.pos); + this->unk_24C = 1.2f; + } else { + this->unk_270 >>= 2; + this->unk_24C = 0.0f; + } + + if ((thisx->speedXZ * 1.5f) + 0.8f > 4.0f) { + this->skelAnime.playSpeed = 4.0f; + } else { + this->skelAnime.playSpeed = (thisx->speedXZ * 1.5f) + 0.8f; + } + + if (this->unk_240 <= 0) { + func_8091DEE4(this); + } else if (thisx == thisx->child) { + func_8091E5EC(this); + } else if ((thisx->xzDistToPlayer < 60.0f) || (this->unk_276 > 0)) { + func_8091E2E0(this); + } +} + +void func_8091E2E0(EnFish* this) { + this->actor.gravity = 0.0f; + this->actor.minVelocityY = 0.0f; + this->unk_240 = Rand_S16Offset(10, 40); + this->unk_248 = 0; + this->unk_26E = 400; + this->unk_272 = 400; + this->unk_268 = 0; + this->unk_26C = 0; + func_8091D660(this); + this->unkFunc = func_8091E34C; +} + +void func_8091E34C(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnFish* this = THIS; + s32 sp3C = thisx->xzDistToPlayer < 60.0f; + s32 sp38 = this->unk_276 > 0; + s32 pad; + + func_8091DD48(this); + Math_SmoothStepToF(&thisx->speedXZ, 4.2f, 0.08f, 1.4f, 0.0f); + + if (func_8091D630(&thisx->world.pos, &thisx->home.pos) > SQ(160.0f)) { + this->unk_270 = this->unk_264; + this->unk_26A = Math_Vec3f_Yaw(&thisx->world.pos, &thisx->home.pos); + this->unk_24C = 0.8f; + } else if ((thisx->child != NULL) && (thisx != thisx->child)) { + this->unk_270 = this->unk_266; + this->unk_26A = Math_Vec3f_Yaw(&thisx->world.pos, &thisx->child->world.pos); + this->unk_24C = 1.0f; + } else if (sp3C) { + this->unk_26A = BINANG_ROT180(thisx->yawTowardsPlayer); + if ((globalCtx->state.frames & 0x10) == 0) { + if ((globalCtx->state.frames & 0x20) == 0) { + this->unk_26A += 0x2000; + } + } else if ((globalCtx->state.frames & 0x20) == 0) { + this->unk_26A -= 0x2000; + } + this->unk_270 = this->unk_266; + this->unk_24C = 1.2f; + } else if (sp38 != 0) { + if ((globalCtx->state.frames & 0x10) == 0) { + s16 temp = BINANG_SUB(thisx->shape.rot.y, this->unk_274); + + if (temp < 0) { + this->unk_26A = BINANG_SUB(this->unk_274, 0x4000); + } else { + this->unk_26A = BINANG_ADD(this->unk_274, 0x4000); + } + } else { + this->unk_26A = BINANG_ROT180(this->unk_274); + } + this->unk_24C = 1.2f; + this->unk_270 = this->unk_266; + } else { + this->unk_270 >>= 2; + this->unk_24C = 0.0f; + } + + if ((thisx->speedXZ * 1.5f) + 0.8f > 4.0f) { + this->skelAnime.playSpeed = 4.0f; + } else { + this->skelAnime.playSpeed = (thisx->speedXZ * 1.5f) + 0.8f; + } + + if ((this->unk_240 <= 0) || (!sp3C && (sp38 == 0))) { + func_8091DEE4(this); + } else if (thisx == thisx->child) { + func_8091E5EC(this); + } +} + +void func_8091E5EC(EnFish* this) { + this->actor.gravity = 0.0f; + this->actor.minVelocityY = 0.0f; + this->unk_26E = 400; + this->unk_272 = 400; + this->unk_268 = 0; + this->unk_26C = 0; + func_8091D660(this); + this->unk_240 = Rand_S16Offset(10, 30); + this->unk_248 = 0; + this->unkFunc = func_8091E658; +} + +void func_8091E658(Actor* thisx, GlobalContext* globalCtx) { + EnFish* this = THIS; + Player* player = GET_PLAYER(globalCtx); + s32 pad; + Vec3f sp38; + s32 pad2; + s16 sp32; + + func_8091DD48(this); + Math_SmoothStepToF(&thisx->speedXZ, 1.8f, 0.1f, 0.5f, 0.0f); + + if (func_8091D630(&thisx->world.pos, &thisx->home.pos) > SQ(80.0f)) { + this->unk_270 = this->unk_264; + this->unk_26A = Math_Vec3f_Yaw(&thisx->world.pos, &thisx->home.pos); + this->unk_24C = 1.0f; + } else { + if ((globalCtx->state.frames & 0x40) == 0) { + sp32 = BINANG_ADD(thisx->yawTowardsPlayer, 0x9000); + } else { + sp32 = BINANG_ADD(thisx->yawTowardsPlayer, 0x7000); + } + + sp38.x = (Math_SinS(sp32) * 20.0f) + player->actor.world.pos.x; + sp38.y = player->actor.world.pos.y; + sp38.z = (Math_CosS(sp32) * 20.0f) + player->actor.world.pos.z; + + this->unk_270 = this->unk_264; + this->unk_26A = Math_Vec3f_Yaw(&thisx->world.pos, &sp38); + this->unk_24C = 1.2f; + } + + if ((thisx->speedXZ * 1.5f) + 0.8f > 4.0f) { + this->skelAnime.playSpeed = 4.0f; + } else { + this->skelAnime.playSpeed = (thisx->speedXZ * 1.5f) + 0.8f; + } + + if (this->unk_240 <= 0) { + func_8091DEE4(this); + } +} + +void func_8091E810(EnFish* this) { + this->unk_270 = 0; + this->unk_26A = 0; + this->actor.gravity = -1.0f; + this->actor.minVelocityY = -10.0f; + this->actor.shape.yOffset = 0.0f; + func_8091D6C4(this); + this->unk_248 = 5; + this->unkFunc = func_8091E880; + this->unk_24C = 0.0f; + this->unk_240 = 300; +} + +void func_8091E880(Actor* thisx, GlobalContext* globalCtx) { + EnFish* this = THIS; + + Math_SmoothStepToF(&this->actor.speedXZ, 0.0f, 0.1f, 0.1f, 0.0f); + this->unk_26E = 0x43; + this->unk_272 = 0x43; + this->unk_268 = 0x4000; + this->unk_26C = -0x4000; + if (this->actor.bgCheckFlags & 1) { + this->unk_240 = 400; + func_8091E9A4(this); + } else if (this->actor.bgCheckFlags & 0x20) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_DIVE_INTO_WATER_L); + func_8091D840(thisx, globalCtx, 10, 15.0f); + if (func_8091DA14(this, globalCtx)) { + func_8091EF30(this); + } else { + func_8091ECF4(this); + } + } else if ((this->unk_240 <= 0) && (this->actor.params == ENFISH_0) && + (this->actor.floorHeight < BGCHECK_Y_MIN + 10)) { + Actor_MarkForDeath(&this->actor); + } +} + +void func_8091E9A4(EnFish* this) { + s32 pad[2]; + s32 sp24; + f32 temp_f0; + + this->actor.gravity = -1.0f; + this->actor.minVelocityY = -10.0f; + + temp_f0 = Rand_ZeroOne(); + if (temp_f0 < 0.1f) { + this->actor.velocity.y = (Rand_ZeroOne() * 3.0f) + 2.5f; + sp24 = true; + } else if (temp_f0 < 0.2f) { + this->actor.velocity.y = (Rand_ZeroOne() * 1.2f) + 0.2f; + sp24 = true; + } else { + this->actor.velocity.y = 0.0f; + if (Rand_ZeroOne() < 0.2f) { + sp24 = true; + } else { + sp24 = false; + } + } + + this->actor.shape.yOffset = 300.0f; + func_8091D6C4(this); + this->unkFunc = func_8091EAF0; + this->unk_248 = 5; + this->unk_24C = 0.0f; + if (sp24 && (this->actor.draw != NULL)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FISH_LEAP); + } +} + +void func_8091EAF0(Actor* thisx, GlobalContext* globalCtx) { + EnFish* this = THIS; + s32 sp40 = globalCtx->state.frames; + s16 phi_v1; + + Math_SmoothStepToF(&this->actor.speedXZ, Rand_ZeroOne() * 0.2f, 0.1f, 0.1f, 0.0f); + phi_v1 = (s16)((((sp40 >> 5) & 2) | ((sp40 >> 2) & 1)) << 0xB) * 0.3f; + if (sp40 & 4) { + phi_v1 *= -1; + } + this->unk_268 = phi_v1; + this->unk_26E = 0xA6B; + this->unk_26C = 0x4000; + this->unk_272 = 0x29B; + this->unk_270 = ((Math_SinS(this->unk_244) * 1333.0f) + (Math_SinS(this->unk_246) * 667.0f)) * Rand_ZeroOne(); + + if (this->unk_270 >= 0) { + this->unk_26A = BINANG_ADD(this->actor.world.rot.y, 0x4000); + } else { + this->unk_26A = BINANG_SUB(this->actor.world.rot.y, 0x4000); + this->unk_270 = -this->unk_270; + } + + if (this->unk_240 <= 0) { + Actor_MarkForDeath(&this->actor); + } else if (this->unk_240 <= 60) { + if (sp40 & 4) { + this->actor.draw = EnFish_Draw; + } else { + this->actor.draw = NULL; + } + } else if (this->actor.bgCheckFlags & 0x20) { + if (func_8091DA14(this, globalCtx)) { + func_8091EF30(this); + } else { + func_8091ECF4(this); + } + } else if (this->actor.bgCheckFlags & 1) { + func_8091E9A4(this); + } +} + +void func_8091ECF4(EnFish* this) { + this->actor.home.pos = this->actor.world.pos; + this->actor.gravity = 0.0f; + this->actor.minVelocityY = 0.0f; + this->actor.shape.yOffset = 0.0f; + this->actor.flags |= 0x10; + this->unk_240 = 200; + func_8091D660(this); + this->unkFunc = func_8091ED70; + this->unk_248 = 5; + this->unk_24C = 0.0f; +} + +void func_8091ED70(Actor* thisx, GlobalContext* globalCtx) { + EnFish* this = THIS; + s32 pad; + s16 sp2E; + + if (this->unk_240 >= 0xBF) { + func_8091D840(thisx, globalCtx, 2, 25.0f); + } + + Math_SmoothStepToF(&thisx->speedXZ, 2.8f, 0.1f, 0.4f, 0.0f); + + if ((thisx->bgCheckFlags & 8) || !(thisx->bgCheckFlags & 0x20)) { + sp2E = Math_Vec3f_Yaw(&thisx->world.pos, &thisx->home.pos); + thisx->home.rot.y = Rand_S16Offset(-100, 100) + sp2E; + thisx->speedXZ *= 0.5f; + } + + this->unk_268 = 0; + this->unk_26A = thisx->home.rot.y; + this->unk_26C = 0; + this->unk_26E = 1000; + this->unk_270 = 2000; + this->unk_272 = 0x29B; + + if (thisx->bgCheckFlags & 1) { + Math_StepToF(&thisx->world.pos.y, thisx->home.pos.y - 4.0f, 2.0f); + } else { + Math_StepToF(&thisx->world.pos.y, thisx->home.pos.y - 10.0f, 2.0f); + } + + if (this->unk_240 < 100) { + this->unk_25C *= 0.982f; + func_8091D728(this); + } + + if ((thisx->speedXZ * 1.5f) + 1.0f > 4.8f) { + this->skelAnime.playSpeed = 4.8f; + } else { + this->skelAnime.playSpeed = (thisx->speedXZ * 1.5f) + 1.0f; + } + + if (this->unk_240 <= 0) { + Actor_MarkForDeath(thisx); + } +} + +void func_8091EF30(EnFish* this) { + this->actor.gravity = -2.0f; + this->actor.minVelocityY = -10.0f; + this->actor.shape.yOffset = 0.0f; + if (this->actor.velocity.y < -1.0f) { + this->actor.velocity.y = -1.0f; + } + this->actor.flags |= 0x10; + this->actor.home.pos.x = this->actor.world.pos.x; + this->actor.home.pos.y = this->actor.world.pos.y - 20.0f; + this->actor.home.pos.z = this->actor.world.pos.z; + func_8091D660(this); + this->unk_240 = 15; + this->unk_279 = 10; + this->unkFunc = func_8091EFE8; + this->unk_248 = 5; + this->unk_24C = 0.0f; +} + +void func_8091EFE8(Actor* thisx, GlobalContext* globalCtx) { + EnFish* this = THIS; + s32 temp_v0_2; + Actor* sp3C = func_8091D944(this, globalCtx); + f32 temp_f0; + f32 sp34; + f32 sp30; + s16 sp2E; + + if (sp3C == 0) { + Actor_MarkForDeath(&this->actor); + return; + } + + if (this->unk_240 <= 0) { + this->unk_240 = Rand_S16Offset(5, 35); + } + + if (this->unk_277 == 0) { + Math_SmoothStepToF(&this->actor.speedXZ, 2.8f, 0.1f, 0.4f, 0.0f); + if (this->unk_240 < 6) { + this->actor.speedXZ *= 0.75f; + } + } + + if ((this->actor.bgCheckFlags & 8) && !(this->actor.bgCheckFlags & 0x20)) { + this->actor.speedXZ *= 0.5f; + } + + if (!((u32)Rand_Next() >> 0x1B) || ((this->actor.bgCheckFlags & 8) && !((u32)Rand_Next() >> 0x1E)) || + !(this->actor.bgCheckFlags & 0x20)) { + temp_f0 = Rand_ZeroOne(); + sp34 = (1.0f - SQ(temp_f0)) * sp3C->home.rot.x; + sp30 = Rand_ZeroOne() * sp3C->home.rot.z; + sp2E = (u32)Rand_Next() >> 0x10; + this->actor.home.pos.x = (Math_SinS(sp2E) * sp34) + sp3C->world.pos.x; + this->actor.home.pos.y = sp3C->world.pos.y + sp30; + this->actor.home.pos.z = (Math_CosS(sp2E) * sp34) + sp3C->world.pos.z; + this->actor.home.rot.y = + Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos) + Rand_S16Offset(-100, 100); + } + + this->unk_268 = Math_Vec3f_Pitch(&this->actor.world.pos, &this->actor.home.pos); + this->unk_26C = 0; + this->unk_26A = this->actor.home.rot.y; + + temp_v0_2 = BINANG_SUB(this->unk_268, this->actor.shape.rot.x); + temp_v0_2 = ABS_ALT(temp_v0_2); + + temp_v0_2 = temp_v0_2 / 11; + if (temp_v0_2 > 800) { + temp_v0_2 = 800; + } else if (temp_v0_2 < 100) { + temp_v0_2 = 100; + } + + if (this->unk_279 > 0) { + this->unk_279--; + this->unk_26E = 1000; + } else { + this->unk_26E = temp_v0_2; + } + + if (this->unk_240 < 10) { + this->unk_270 = 400; + } else { + this->unk_270 = 2000; + } + + this->unk_272 = 0x29B; + if (fabsf(this->actor.world.pos.y - this->actor.home.pos.y) < 2.0f) { + this->actor.gravity = 0.0f; + } else if (this->actor.home.pos.y < this->actor.world.pos.y) { + this->actor.gravity = -0.15f; + } else { + this->actor.gravity = 0.15f; + } + + this->actor.velocity.y *= 0.8f; + if ((this->actor.speedXZ * 1.5f) + 1.0f > 4.8f) { + this->skelAnime.playSpeed = 4.8f; + } else { + this->skelAnime.playSpeed = (this->actor.speedXZ * 1.5f) + 1.0f; + } +} + +void func_8091F344(EnFish* this) { + this->actor.gravity = 0.0f; + this->actor.minVelocityY = 0.0f; + this->unk_240 = Rand_S16Offset(5, 35); + this->unk_248 = 1; + this->unk_268 = 0; + this->unk_26C = 0; + this->unk_26E = 1500; + this->unk_272 = 0; + func_8091D660(this); + this->unkFunc = func_8091F3BC; + this->unk_24C = 0.0f; +} + +void func_8091F3BC(Actor* thisx, GlobalContext* globalCtx) { + static Vec3f D_8091FADC = { 0.0f, 0.04f, 0.09f }; + static Vec3f D_8091FAE8 = { 0.5f, 0.1f, 0.15f }; + EnFish* this = THIS; + s32 sp40 = globalCtx->gameplayFrames; + Vec3f* sp3C; + f32 phi_f0; + f32 temp_f2; + + if ((this->actor.xzDistToPlayer < 60.0f) || ((sp40 & 0x1FF) < 20)) { + if (this->unk_240 < 12) { + sp3C = &D_8091FAE8; + } else { + sp3C = &D_8091FADC; + } + } else if (this->unk_240 < 4) { + sp3C = &D_8091FAE8; + } else { + sp3C = &D_8091FADC; + } + + func_8091DD48(this); + Math_StepToF(&this->actor.world.pos.y, this->actor.home.pos.y, 2.0f); + Math_SmoothStepToF(&this->actor.speedXZ, sp3C->x, sp3C->y, sp3C->z, 0.0f); + this->unk_24C = 0.0f; + + if (func_8091D630(&this->actor.world.pos, &this->actor.home.pos) > SQ(15.0f)) { + this->unk_26A = Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos); + this->unk_270 = 0x85; + phi_f0 = 0.4f; + } else if (this->unk_240 < 4) { + this->unk_26A = sp40 << 7; + this->unk_270 = 0x43; + phi_f0 = 0.4f; + } else { + this->unk_270 = 0; + phi_f0 = 0.0f; + } + + temp_f2 = this->actor.speedXZ + 0.4f + phi_f0; + this->skelAnime.playSpeed = CLAMP(temp_f2, 0.5f, 1.6f); + + if (this->unk_240 <= 0) { + this->unk_240 = Rand_S16Offset(5, 80); + } +} + +void func_8091F5A4(Actor* thisx, GlobalContext* globalCtx) { + EnFish* this = THIS; + Actor* temp_v0_2; + s16 temp_v0; + s16 temp_v0_4; + s32 temp_v1; + s32 phi_v1; + f32 phi_f0; + + if (this->unk_240 > 0) { + this->unk_240--; + } + + this->unk_244 += 0x111; + this->unk_246 += 0x500; + + if ((this->actor.child != NULL) && (this->actor.child->update == NULL) && (thisx != this->actor.child)) { + this->actor.child = NULL; + } + + if ((this->unkFunc == NULL) || (this->unkFunc(&this->actor, globalCtx), (this->actor.update != NULL))) { + if ((ABS_ALT(BINANG_SUB(this->unk_26A, this->actor.shape.rot.y)) > 0x3000) && (this->unk_270 > 1000)) { + this->skelAnime.playSpeed += this->unk_24C; + } + SkelAnime_Update(&this->skelAnime); + func_8091D7C4(this); + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + if (this->unk_248 != 0) { + u32 temp = (globalCtx->sceneNum ^ SCENE_LABO) != 0; + phi_f0 = BREG(1) + 10.0f; + + if (temp) { + phi_f0 = 6.0f; + } + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 17.5f, phi_f0, 0.0f, this->unk_248); + } + + if ((this->actor.xzDistToPlayer < 70.0f) && (this->unkFunc != func_8091EFE8)) { + ColliderJntSphElement* element = &this->collider.elements[0]; + + element->dim.worldSphere.center.x = this->actor.world.pos.x; + element->dim.worldSphere.center.y = this->actor.world.pos.y; + element->dim.worldSphere.center.z = this->actor.world.pos.z; + element->dim.worldSphere.radius = this->unk_25C * 500.0f; + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + Actor_SetHeight(&this->actor, this->actor.shape.yOffset * 0.01f); + + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + if (this->actor.params == ENFISH_0) { + Actor_MarkForDeath(&this->actor); + } else { + func_8091D904(this); + } + } else if (func_8091DDF4(this, globalCtx)) { + func_800B8A1C(&this->actor, globalCtx, 0xBA, 80.0f, 25.0f); + } + } +} + +void func_8091F830(Actor* thisx, GlobalContext* globalCtx) { + EnFish* this = THIS; + + if (this->actor.params == ENFISH_1) { + Actor_MarkForDeath(&this->actor); + return; + } + + if ((this->actor.child != NULL) && (this->actor.child->update == NULL) && (thisx != this->actor.child)) { + this->actor.child = NULL; + } + + if ((this->unkFunc == NULL) || (this->unkFunc(&this->actor, globalCtx), (this->actor.update != NULL))) { + func_8091D7C4(this); + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + + if (this->unk_242 == 20) { + this->actor.draw = EnFish_Draw; + } else if (this->unk_242 == 0) { + this->unk_25C = this->unk_260; + func_8091D728(this); + } else if (this->unk_242 < 20) { + this->unk_25C += 0.1f * this->unk_260; + if (this->unk_260 < this->unk_25C) { + this->unk_25C = this->unk_260; + } + func_8091D728(this); + } + } +} + +void EnFish_Update(Actor* thisx, GlobalContext* globalCtx) { + EnFish* this = THIS; + + if (this->unk_242 > 0) { + this->unk_242--; + func_8091F830(thisx, globalCtx); + } else { + func_8091F5A4(thisx, globalCtx); + } + + if (this->unk_276 > 0) { + this->unk_276--; + } +} + +void func_8091F994(Actor* thisx, GlobalContext* globalCtx) { +} + +void EnFish_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnFish* this = THIS; + Color_RGB8* colour = &D_8091FA94[this->unk_278]; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, colour->r, colour->g, colour->b, 255); + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + NULL, NULL, NULL); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Fish/z_en_fish.h b/src/overlays/actors/ovl_En_Fish/z_en_fish.h index 7d4a9f0cf..fd35ef626 100644 --- a/src/overlays/actors/ovl_En_Fish/z_en_fish.h +++ b/src/overlays/actors/ovl_En_Fish/z_en_fish.h @@ -5,11 +5,47 @@ struct EnFish; +typedef void (*EnFishUnkFunc)(Actor*, GlobalContext*); + +enum { + /* -1 */ ENFISH_MINUS1 = -1, + /* 0 */ ENFISH_0, + /* 1 */ ENFISH_1, + /* 2 */ ENFISH_2, +}; + typedef struct EnFish { /* 0x000 */ Actor actor; - /* 0x144 */ char unk144[0x133]; - /* 0x277 */ s8 unk_277; - /* 0x278 */ char unk278[0x4]; + /* 0x144 */ ColliderJntSph collider; + /* 0x164 */ ColliderJntSphElement colliderElements[1]; + /* 0x1A4 */ SkelAnime skelAnime; + /* 0x1E8 */ Vec3s jointTable[7]; + /* 0x212 */ Vec3s morphTable[7]; + /* 0x23C */ EnFishUnkFunc unkFunc; + /* 0x240 */ s16 unk_240; + /* 0x242 */ s16 unk_242; + /* 0x244 */ s16 unk_244; + /* 0x246 */ s16 unk_246; + /* 0x248 */ s32 unk_248; + /* 0x24C */ f32 unk_24C; + /* 0x250 */ f32 unk_250; + /* 0x254 */ f32 unk_254; + /* 0x258 */ f32 unk_258; + /* 0x25C */ f32 unk_25C; + /* 0x260 */ f32 unk_260; + /* 0x264 */ s16 unk_264; + /* 0x266 */ s16 unk_266; + /* 0x268 */ s16 unk_268; + /* 0x26A */ s16 unk_26A; + /* 0x26C */ s16 unk_26C; + /* 0x26E */ s16 unk_26E; + /* 0x270 */ s16 unk_270; + /* 0x272 */ s16 unk_272; + /* 0x274 */ s16 unk_274; + /* 0x276 */ s8 unk_276; + /* 0x277 */ u8 unk_277; + /* 0x278 */ s8 unk_278; + /* 0x279 */ s8 unk_279; } EnFish; // size = 0x27C extern const ActorInit En_Fish_InitVars; diff --git a/src/overlays/actors/ovl_En_Fish2/z_en_fish2.c b/src/overlays/actors/ovl_En_Fish2/z_en_fish2.c index 7b52e0a30..cd553b537 100644 --- a/src/overlays/actors/ovl_En_Fish2/z_en_fish2.c +++ b/src/overlays/actors/ovl_En_Fish2/z_en_fish2.c @@ -1058,7 +1058,7 @@ void EnFish2_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, OPEN_DISPS(globalCtx->state.gfxCtx); Matrix_StatePush(); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, *dList); @@ -1069,11 +1069,11 @@ void EnFish2_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, } if (limbIndex == 14) { - Matrix_MultiplyVector3fByState(&D_801D15B0, &this->unk_318); + Matrix_MultiplyVector3fByState(&gZeroVec3f, &this->unk_318); } if (limbIndex == 17) { - Matrix_MultiplyVector3fByState(&D_801D15B0, &this->unk_300); + Matrix_MultiplyVector3fByState(&gZeroVec3f, &this->unk_300); } Collider_UpdateSpheres(limbIndex, &this->collider); diff --git a/src/overlays/actors/ovl_En_Fishing/z_en_fishing.c b/src/overlays/actors/ovl_En_Fishing/z_en_fishing.c index d1f93bdbc..daa6607bd 100644 --- a/src/overlays/actors/ovl_En_Fishing/z_en_fishing.c +++ b/src/overlays/actors/ovl_En_Fishing/z_en_fishing.c @@ -1,21 +1,204 @@ /* * File: z_en_fishing.c * Overlay: ovl_En_Fishing - * Description: Fishing + * Description: Fishing Pond Elements (Owner, Fish, Props, Effects...) */ #include "z_en_fishing.h" +#include "objects/object_fish/object_fish.h" +#include "overlays/actors/ovl_En_Kanban/z_en_kanban.h" #define FLAGS 0x00000010 #define THIS ((EnFishing*)thisx) +#define WATER_SURFACE_Y(globalCtx) globalCtx->colCtx.colHeader->waterBoxes->minPos.y + void EnFishing_Init(Actor* thisx, GlobalContext* globalCtx); void EnFishing_Destroy(Actor* thisx, GlobalContext* globalCtx); -void EnFishing_Update(Actor* thisx, GlobalContext* globalCtx); -void EnFishing_Draw(Actor* thisx, GlobalContext* globalCtx); +void EnFishing_UpdateFish(Actor* thisx, GlobalContext* globalCtx); +void EnFishing_DrawFish(Actor* thisx, GlobalContext* globalCtx); + +void EnFishing_UpdateOwner(Actor* thisx, GlobalContext* globalCtx); +void EnFishing_DrawOwner(Actor* thisx, GlobalContext* globalCtx); + +typedef struct { + /* 0x00 */ u8 unk_00; + /* 0x02 */ Vec3s pos; + /* 0x08 */ u8 unk_08; + /* 0x0C */ f32 unk_0C; +} FishingFishInit; // size = 0x10 + +#define EFFECT_COUNT 130 + +typedef enum { + /* 0x00 */ FS_EFF_NONE, + /* 0x01 */ FS_EFF_RIPPLE, + /* 0x02 */ FS_EFF_DUST_SPLASH, + /* 0x03 */ FS_EFF_WATER_DUST, + /* 0x04 */ FS_EFF_BUBBLE, + /* 0x05 */ FS_EFF_RAIN_DROP, + /* 0x06 */ FS_EFF_OWNER_HAT, + /* 0x07 */ FS_EFF_RAIN_RIPPLE, + /* 0x08 */ FS_EFF_RAIN_SPLASH +} FishingEffectType; + +typedef struct { + /* 0x00 */ Vec3f pos; + /* 0x0C */ Vec3f vel; + /* 0x18 */ Vec3f accel; + /* 0x24 */ u8 type; + /* 0x25 */ u8 timer; + /* 0x26 */ UNK_TYPE1 unk_26[0x04]; + /* 0x2A */ s16 alpha; + /* 0x2C */ s16 unk_2C; + /* 0x2E */ s16 unk_2E; + /* 0x30 */ f32 unk_30; + /* 0x34 */ f32 unk_34; + /* 0x38 */ f32 unk_38; + /* 0x3C */ f32 unk_3C; +} FishingEffect; // size = 0x40 + +#define POND_PROP_COUNT 140 + +typedef enum { + /* 0x00 */ FS_PROP_NONE, + /* 0x01 */ FS_PROP_REED, + /* 0x02 */ FS_PROP_LILY_PAD, + /* 0x03 */ FS_PROP_ROCK, + /* 0x04 */ FS_PROP_WOOD_POST, + /* 0x23 */ FS_PROP_INIT_STOP = 0x23 +} FishingPropType; + +typedef struct { + /* 0x00 */ u8 type; + /* 0x02 */ Vec3s pos; +} FishingPropInit; // size = 0x08 + +typedef struct { + /* 0x00 */ Vec3f pos; + /* 0x0C */ f32 rotX; + /* 0x10 */ f32 rotY; + /* 0x14 */ f32 reedAngle; + /* 0x18 */ Vec3f projectedPos; + /* 0x24 */ f32 scale; + /* 0x28 */ s16 lilyPadAngle; + /* 0x2C */ f32 lilyPadOffset; + /* 0x30 */ u8 type; + /* 0x32 */ s16 timer; + /* 0x34 */ u8 shouldDraw; + /* 0x38 */ f32 drawDistance; +} FishingProp; // size = 0x3C + +typedef enum { + /* 0x00 */ FS_GROUP_FISH_NONE, + /* 0x01 */ FS_GROUP_FISH_NORMAL +} FishingGroupFishType; + +#define GROUP_FISH_COUNT 60 + +typedef struct { + /* 0x00 */ u8 type; + /* 0x02 */ s16 timer; + /* 0x04 */ Vec3f pos; + /* 0x10 */ Vec3f unk_10; + /* 0x1C */ Vec3f projectedPos; + /* 0x28 */ f32 unk_28; + /* 0x2C */ f32 unk_2C; + /* 0x30 */ f32 unk_30; + /* 0x34 */ f32 unk_34; + /* 0x38 */ f32 unk_38; + /* 0x3C */ s16 unk_3C; + /* 0x3E */ s16 unk_3E; + /* 0x40 */ s16 unk_40; + /* 0x42 */ s16 unk_42; + /* 0x44 */ u8 shouldDraw; +} FishingGroupFish; // size = 0x48 + +#define LINE_SEG_COUNT 200 +#define SINKING_LURE_SEG_COUNT 20 + +static f32 D_809101B0; +static f32 D_809101B4; +static s16 D_809101B8; +static f32 D_809101BC; +static f32 D_809101C0; +static f32 D_809101C4; +static f32 D_809101C8; +static s16 D_809101CC; +static f32 D_809101D0; +static Vec3f sRodTipPos; +static Vec3f sReelLinePos[LINE_SEG_COUNT]; +static Vec3f sReelLineRot[LINE_SEG_COUNT]; +static Vec3f sReelLineUnk[LINE_SEG_COUNT]; +static Vec3f sLureHookRefPos[2]; +static f32 sLureHookRotY[2]; +static u8 D_80911E28; +static Vec3f sSinkingLurePos[SINKING_LURE_SEG_COUNT]; +static s16 D_80911F20; +static f32 sProjectedW; +static Vec3f sCameraEye; +static Vec3f sCameraAt; +static s16 sCameraId; +static f32 D_80911F48; +static f32 D_80911F4C; +static f32 D_80911F50; +static Vec3f sSinkingLureBasePos; +static f32 D_80911F64; +static s32 sRandSeed0; +static s32 sRandSeed1; +static s32 sRandSeed2; +static FishingProp sPondProps[POND_PROP_COUNT]; +static FishingGroupFish sGroupFishes[GROUP_FISH_COUNT]; +static f32 sFishGroupAngle1; +static f32 sFishGroupAngle2; +static f32 sFishGroupAngle3; +static FishingEffect sFishingEffects[EFFECT_COUNT]; +static Vec3f sStreamSoundProjectedPos; +static EnFishing* sFishingMain; +static u8 D_809171C8; +static u8 sLinkAge; +static u8 D_809171CA; +static u8 D_809171CB; +static f32 D_809171CC; +static u8 D_809171D0; +static u8 D_809171D1; +static u8 D_809171D2; +static s16 D_809171D4; +static u8 D_809171D6; +static u16 D_809171D8; +static u16 D_809171DA; +static s8 D_809171DC; +static Vec3f sOwnerHeadPos; +static Vec3s sEffOwnerHatRot; +static u8 D_809171F2; +static s16 D_809171F4; +static s16 D_809171F6; +static EnFishing* sFishingHookedFish; +static s16 D_809171FC; +static s16 D_809171FE; +static s16 D_80917200; +static s16 D_80917202; +static s16 D_80917204; +static u8 D_80917206; +static Vec3f sLurePos; +static Vec3f D_80917218; +static Vec3f sLureRot; +static Vec3f D_80917238; +static Vec3f D_80917248; +static f32 D_80917254; +static f32 D_80917258; +static f32 D_8091725C; +static f32 D_80917260; +static s8 D_80917264; +static s16 D_80917266; +static u8 D_80917268; +static f32 D_8091726C; +static u8 D_80917270; +static s16 D_80917272; +static u8 D_80917274; +static Vec3f D_80917278; -#if 0 const ActorInit En_Fishing_InitVars = { ACTOR_EN_FISHING, ACTORCAT_NPC, @@ -24,181 +207,5503 @@ const ActorInit En_Fishing_InitVars = { sizeof(EnFishing), (ActorFunc)EnFishing_Init, (ActorFunc)EnFishing_Destroy, - (ActorFunc)EnFishing_Update, - (ActorFunc)EnFishing_Draw, + (ActorFunc)EnFishing_UpdateFish, + (ActorFunc)EnFishing_DrawFish, }; -// static ColliderJntSphElementInit sJntSphElementsInit[12] = { -static ColliderJntSphElementInit D_8090CD58[12] = { +static f32 D_8090CCD0 = 0.0f; +static u8 D_8090CCD4 = 0; +static f32 D_8090CCD8 = 0.0f; +static Vec3f D_8090CCDC = { 0.0f, 0.0f, 0.0f }; +static f32 D_8090CCE8 = 0.0f; +static u8 sSinkingLureLocation = 0; +static f32 D_8090CCF0 = 0.0f; +static u8 D_8090CCF4 = true; +static u16 D_8090CCF8 = 0; +static u8 D_8090CCFC = 0; +static s32 D_8090CD00 = 0; +static s16 D_8090CD04 = 0; +static u8 D_8090CD08 = 0; +static u8 D_8090CD0C = 0; +static u8 D_8090CD10 = 0; +static s16 D_8090CD14 = 0; +static Vec3f sFishMouthOffset = { 500.0f, 500.0f, 0.0f }; +static u8 D_8090CD24 = 0; +static f32 D_8090CD28 = 0; +static f32 D_8090CD2C = 0; +static f32 D_8090CD30 = 0.0f; +static f32 D_8090CD34 = 0.0f; +static f32 D_8090CD38 = 0.0f; +static f32 D_8090CD3C = 0.0f; +static f32 D_8090CD40 = 0.0f; +static s16 D_8090CD44 = 0; +static s16 D_8090CD48 = 0; +static u8 D_8090CD4C = 0; +static u8 D_8090CD50 = 0; +static u8 D_8090CD54 = 0; + +static ColliderJntSphElementInit sJntSphElementsInit[12] = { { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 30 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 30 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 30 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 30 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 30 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 30 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 30 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 30 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 30 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 30 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 30 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 30 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_8090CF08 = { - { COLTYPE_NONE, AT_NONE | AT_TYPE_ENEMY, AC_NONE | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 12, D_8090CD58, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_NONE, + AT_NONE | AT_TYPE_ENEMY, + AC_NONE | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 12, + sJntSphElementsInit, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_8090D4D0[] = { +static u8 D_8090CF18 = 0; +static Vec3f sZeroVec = { 0.0f, 0.0f, 0.0f }; +static Vec3f D_8090CF28 = { 0.0f, 0.0f, 2000.0f }; // Unused + +void EnFishing_SetColliderElement(s32 index, ColliderJntSph* collider, Vec3f* pos, f32 scale) { + collider->elements[index].dim.worldSphere.center.x = pos->x; + collider->elements[index].dim.worldSphere.center.y = pos->y; + collider->elements[index].dim.worldSphere.center.z = pos->z; + collider->elements[index].dim.worldSphere.radius = + collider->elements[index].dim.modelSphere.radius * collider->elements[index].dim.scale * scale * 1.6f; +} + +void EnFishing_SeedRand(s32 seed0, s32 seed1, s32 seed2) { + sRandSeed0 = seed0; + sRandSeed1 = seed1; + sRandSeed2 = seed2; +} + +f32 EnFishing_RandZeroOne(void) { + f32 rand; + + // Wichmann-Hill algorithm + sRandSeed0 = (sRandSeed0 * 171) % 30269; + sRandSeed1 = (sRandSeed1 * 172) % 30307; + sRandSeed2 = (sRandSeed2 * 170) % 30323; + + rand = (sRandSeed0 / 30269.0f) + (sRandSeed1 / 30307.0f) + (sRandSeed2 / 30323.0f); + while (rand >= 1.0f) { + rand -= 1.0f; + } + + return fabsf(rand); +} + +s16 EnFishing_SmoothStepToS(s16* pValue, s16 target, s16 scale, s16 step) { + s16 stepSize; + s16 diff; + + diff = target - *pValue; + stepSize = diff / scale; + + if (stepSize > step) { + stepSize = step; + } + + if (stepSize < -step) { + stepSize = -step; + } + + *pValue += stepSize; + + return stepSize; +} + +void EnFishing_SpawnRipple(Vec3f* projectedPos, FishingEffect* effect, Vec3f* pos, f32 arg3, f32 arg4, s16 arg5, + s16 countLimit) { + s16 i; + + if ((projectedPos != NULL) && ((projectedPos->z > 500.0f) || (projectedPos->z < 0.0f))) { + return; + } + + for (i = 0; i < countLimit; i++) { + if (effect->type == FS_EFF_NONE) { + effect->type = FS_EFF_RIPPLE; + effect->pos = *pos; + effect->vel = sZeroVec; + effect->accel = sZeroVec; + effect->unk_30 = arg3 * 0.0025f; + effect->unk_34 = arg4 * 0.0025f; + + if (arg3 > 300.0f) { + effect->alpha = 0; + effect->unk_2E = arg5; + effect->unk_2C = 0; + effect->unk_38 = (effect->unk_34 - effect->unk_30) * 0.05f; + } else { + effect->alpha = arg5; + effect->unk_2C = 1; + effect->unk_38 = (effect->unk_34 - effect->unk_30) * 0.1f; + } + break; + } + + effect++; + } +} + +void EnFishing_SpawnDustSplash(Vec3f* projectedPos, FishingEffect* effect, Vec3f* pos, Vec3f* vel, f32 scale) { + s16 i; + Vec3f accel = { 0.0f, -1.0f, 0.0f }; + + if ((projectedPos != NULL) && ((projectedPos->z > 500.0f) || (projectedPos->z < 0.0f))) { + return; + } + + for (i = 0; i < 100; i++) { + if ((effect->type == FS_EFF_NONE) || (effect->type == FS_EFF_RAIN_DROP) || + (effect->type == FS_EFF_RAIN_RIPPLE) || (effect->type == FS_EFF_RAIN_SPLASH)) { + effect->type = FS_EFF_DUST_SPLASH; + effect->pos = *pos; + effect->vel = *vel; + effect->accel = accel; + effect->alpha = 100 + Rand_ZeroFloat(100.0f); + effect->unk_30 = scale; + break; + } + + effect++; + } +} + +void EnFishing_SpawnWaterDust(Vec3f* projectedPos, FishingEffect* effect, Vec3f* pos, f32 scale) { + s16 i; + Vec3f accel = { 0.0f, 0.05f, 0.0f }; + + if ((projectedPos != NULL) && ((projectedPos->z > 500.0f) || (projectedPos->z < 0.0f))) { + return; + } + + for (i = 0; i < 90; i++) { + if (effect->type == FS_EFF_NONE) { + effect->type = FS_EFF_WATER_DUST; + effect->pos = *pos; + effect->vel = sZeroVec; + effect->accel = accel; + effect->alpha = 255; + effect->timer = Rand_ZeroFloat(100.0f); + effect->unk_30 = scale; + effect->unk_34 = 2.0f * scale; + break; + } + + effect++; + } +} + +void EnFishing_SpawnBubble(Vec3f* projectedPos, FishingEffect* effect, Vec3f* pos, f32 scale, u8 arg4) { + s16 i; + Vec3f vel = { 0.0f, 1.0f, 0.0f }; + + if ((projectedPos != NULL) && ((projectedPos->z > 500.0f) || (projectedPos->z < 0.0f))) { + return; + } + + for (i = 0; i < 90; i++) { + if (effect->type == FS_EFF_NONE) { + effect->type = FS_EFF_BUBBLE; + effect->pos = *pos; + effect->vel = vel; + effect->accel = sZeroVec; + effect->timer = Rand_ZeroFloat(100.0f); + effect->unk_30 = scale; + effect->unk_2C = arg4; + break; + } + + effect++; + } +} + +void EnFishing_SpawnRainDrop(FishingEffect* effect, Vec3f* pos, Vec3f* rot) { + s16 i; + Vec3f velSrc; + + velSrc.x = 0.0f; + velSrc.y = 0.0f; + velSrc.z = 300.0f; + + effect += 30; + + for (i = 30; i < EFFECT_COUNT; i++) { + if (effect->type == FS_EFF_NONE) { + effect->type = FS_EFF_RAIN_DROP; + effect->pos = *pos; + effect->accel = sZeroVec; + effect->unk_34 = rot->x; + effect->unk_38 = rot->y; + effect->unk_3C = rot->z; + Matrix_InsertYRotation_f(rot->y, MTXMODE_NEW); + Matrix_RotateStateAroundXAxis(rot->x); + Matrix_MultiplyVector3fByState(&velSrc, &effect->vel); + break; + } + + effect++; + } +} + +static FishingPropInit sPondPropInits[POND_PROP_COUNT + 1] = { + { FS_PROP_ROCK, { 529, -53, -498 } }, + { FS_PROP_ROCK, { 461, -66, -480 } }, + { FS_PROP_ROCK, { 398, -73, -474 } }, + { FS_PROP_ROCK, { -226, -52, -691 } }, + { FS_PROP_ROCK, { -300, -41, -710 } }, + { FS_PROP_ROCK, { -333, -50, -643 } }, + { FS_PROP_ROCK, { -387, -46, -632 } }, + { FS_PROP_ROCK, { -484, -43, -596 } }, + { FS_PROP_ROCK, { -409, -57, -560 } }, + { FS_PROP_WOOD_POST, { 444, -87, -322 } }, + { FS_PROP_WOOD_POST, { 447, -91, -274 } }, + { FS_PROP_WOOD_POST, { 395, -109, -189 } }, + { FS_PROP_REED, { 617, -29, 646 } }, + { FS_PROP_REED, { 698, -26, 584 } }, + { FS_PROP_REED, { 711, -29, 501 } }, + { FS_PROP_REED, { 757, -28, 457 } }, + { FS_PROP_REED, { 812, -29, 341 } }, + { FS_PROP_REED, { 856, -30, 235 } }, + { FS_PROP_REED, { 847, -31, 83 } }, + { FS_PROP_REED, { 900, -26, 119 } }, + { FS_PROP_LILY_PAD, { 861, -22, 137 } }, + { FS_PROP_LILY_PAD, { 836, -22, 150 } }, + { FS_PROP_LILY_PAD, { 829, -22, 200 } }, + { FS_PROP_LILY_PAD, { 788, -22, 232 } }, + { FS_PROP_LILY_PAD, { 803, -22, 319 } }, + { FS_PROP_LILY_PAD, { 756, -22, 348 } }, + { FS_PROP_LILY_PAD, { 731, -22, 377 } }, + { FS_PROP_LILY_PAD, { 700, -22, 392 } }, + { FS_PROP_LILY_PAD, { 706, -22, 351 } }, + { FS_PROP_LILY_PAD, { 677, -22, 286 } }, + { FS_PROP_LILY_PAD, { 691, -22, 250 } }, + { FS_PROP_LILY_PAD, { 744, -22, 290 } }, + { FS_PROP_LILY_PAD, { 766, -22, 201 } }, + { FS_PROP_LILY_PAD, { 781, -22, 128 } }, + { FS_PROP_LILY_PAD, { 817, -22, 46 } }, + { FS_PROP_LILY_PAD, { 857, -22, -50 } }, + { FS_PROP_LILY_PAD, { 724, -22, 110 } }, + { FS_PROP_LILY_PAD, { 723, -22, 145 } }, + { FS_PROP_LILY_PAD, { 728, -22, 202 } }, + { FS_PROP_LILY_PAD, { 721, -22, 237 } }, + { FS_PROP_LILY_PAD, { 698, -22, 312 } }, + { FS_PROP_LILY_PAD, { 660, -22, 349 } }, + { FS_PROP_LILY_PAD, { 662, -22, 388 } }, + { FS_PROP_LILY_PAD, { 667, -22, 432 } }, + { FS_PROP_LILY_PAD, { 732, -22, 429 } }, + { FS_PROP_LILY_PAD, { 606, -22, 366 } }, + { FS_PROP_LILY_PAD, { 604, -22, 286 } }, + { FS_PROP_LILY_PAD, { 620, -22, 217 } }, + { FS_PROP_LILY_PAD, { 663, -22, 159 } }, + { FS_PROP_LILY_PAD, { 682, -22, 73 } }, + { FS_PROP_LILY_PAD, { 777, -22, 83 } }, + { FS_PROP_LILY_PAD, { 766, -22, 158 } }, + { FS_PROP_REED, { 1073, 0, -876 } }, + { FS_PROP_REED, { 970, 0, -853 } }, + { FS_PROP_REED, { 896, 0, -886 } }, + { FS_PROP_REED, { 646, -27, -651 } }, + { FS_PROP_REED, { 597, -29, -657 } }, + { FS_PROP_REED, { 547, -32, -651 } }, + { FS_PROP_REED, { 690, -29, -546 } }, + { FS_PROP_REED, { 720, -29, -490 } }, + { FS_PROP_REED, { -756, -30, -409 } }, + { FS_PROP_REED, { -688, -34, -458 } }, + { FS_PROP_REED, { -613, -34, -581 } }, + { FS_PROP_LILY_PAD, { -593, -22, -479 } }, + { FS_PROP_LILY_PAD, { -602, -22, -421 } }, + { FS_PROP_LILY_PAD, { -664, -22, -371 } }, + { FS_PROP_LILY_PAD, { -708, -22, -316 } }, + { FS_PROP_LILY_PAD, { -718, -22, -237 } }, + { FS_PROP_REED, { -807, -36, -183 } }, + { FS_PROP_REED, { -856, -29, -259 } }, + { FS_PROP_LILY_PAD, { -814, -22, -317 } }, + { FS_PROP_LILY_PAD, { -759, -22, -384 } }, + { FS_PROP_LILY_PAD, { -718, -22, -441 } }, + { FS_PROP_LILY_PAD, { -474, -22, -567 } }, + { FS_PROP_LILY_PAD, { -519, -22, -517 } }, + { FS_PROP_LILY_PAD, { -539, -22, -487 } }, + { FS_PROP_LILY_PAD, { -575, -22, -442 } }, + { FS_PROP_LILY_PAD, { -594, -22, -525 } }, + { FS_PROP_LILY_PAD, { -669, -22, -514 } }, + { FS_PROP_LILY_PAD, { -653, -22, -456 } }, + { FS_PROP_REED, { -663, -28, -606 } }, + { FS_PROP_REED, { -708, -26, -567 } }, + { FS_PROP_REED, { -739, -27, -506 } }, + { FS_PROP_REED, { -752, -28, -464 } }, + { FS_PROP_REED, { -709, -29, -513 } }, + { FS_PROP_LILY_PAD, { -544, -22, -436 } }, + { FS_PROP_LILY_PAD, { -559, -22, -397 } }, + { FS_PROP_LILY_PAD, { -616, -22, -353 } }, + { FS_PROP_LILY_PAD, { -712, -22, -368 } }, + { FS_PROP_LILY_PAD, { -678, -22, -403 } }, + { FS_PROP_LILY_PAD, { -664, -22, -273 } }, + { FS_PROP_LILY_PAD, { -630, -22, -276 } }, + { FS_PROP_LILY_PAD, { -579, -22, -311 } }, + { FS_PROP_LILY_PAD, { -588, -22, -351 } }, + { FS_PROP_LILY_PAD, { -555, -22, -534 } }, + { FS_PROP_LILY_PAD, { -547, -22, -567 } }, + { FS_PROP_LILY_PAD, { -592, -22, -571 } }, + { FS_PROP_LILY_PAD, { -541, -22, -610 } }, + { FS_PROP_LILY_PAD, { -476, -22, -629 } }, + { FS_PROP_LILY_PAD, { -439, -22, -598 } }, + { FS_PROP_LILY_PAD, { -412, -22, -550 } }, + { FS_PROP_LILY_PAD, { -411, -22, -606 } }, + { FS_PROP_LILY_PAD, { -370, -22, -634 } }, + { FS_PROP_LILY_PAD, { -352, -22, -662 } }, + { FS_PROP_LILY_PAD, { -413, -22, -641 } }, + { FS_PROP_LILY_PAD, { -488, -22, -666 } }, + { FS_PROP_LILY_PAD, { -578, -22, -656 } }, + { FS_PROP_LILY_PAD, { -560, -22, -640 } }, + { FS_PROP_LILY_PAD, { -531, -22, -654 } }, + { FS_PROP_LILY_PAD, { -451, -22, -669 } }, + { FS_PROP_LILY_PAD, { -439, -22, -699 } }, + { FS_PROP_LILY_PAD, { -482, -22, -719 } }, + { FS_PROP_LILY_PAD, { -524, -22, -720 } }, + { FS_PROP_LILY_PAD, { -569, -22, -714 } }, + { FS_PROP_REED, { -520, -27, -727 } }, + { FS_PROP_REED, { -572, -28, -686 } }, + { FS_PROP_REED, { -588, -32, -631 } }, + { FS_PROP_REED, { -622, -34, -571 } }, + { FS_PROP_REED, { -628, -36, -510 } }, + { FS_PROP_REED, { -655, -36, -466 } }, + { FS_PROP_REED, { -655, -41, -393 } }, + { FS_PROP_REED, { -661, -47, -328 } }, + { FS_PROP_REED, { -723, -40, -287 } }, + { FS_PROP_REED, { -756, -33, -349 } }, + { FS_PROP_REED, { -755, -43, -210 } }, + { FS_PROP_LILY_PAD, { -770, -22, -281 } }, + { FS_PROP_LILY_PAD, { -750, -22, -313 } }, + { FS_PROP_LILY_PAD, { -736, -22, -341 } }, + { FS_PROP_LILY_PAD, { -620, -22, -418 } }, + { FS_PROP_LILY_PAD, { -601, -22, -371 } }, + { FS_PROP_LILY_PAD, { -635, -22, -383 } }, + { FS_PROP_LILY_PAD, { -627, -22, -311 } }, + { FS_PROP_LILY_PAD, { -665, -22, -327 } }, + { FS_PROP_LILY_PAD, { -524, -22, -537 } }, + { FS_PROP_LILY_PAD, { -514, -22, -579 } }, + { FS_PROP_LILY_PAD, { -512, -22, -623 } }, + { FS_PROP_LILY_PAD, { -576, -22, -582 } }, + { FS_PROP_LILY_PAD, { -600, -22, -608 } }, + { FS_PROP_LILY_PAD, { -657, -22, -531 } }, + { FS_PROP_LILY_PAD, { -641, -22, -547 } }, + { FS_PROP_INIT_STOP, { 0 } }, +}; + +void EnFishing_InitPondProps(EnFishing* this, GlobalContext* globalCtx) { + FishingProp* prop = &sPondProps[0]; + Vec3f colliderPos; + s16 i; + + EnFishing_SeedRand(1, 29100, 9786); + + for (i = 0; i < POND_PROP_COUNT; i++) { + if (sPondPropInits[i].type == FS_PROP_INIT_STOP) { + break; + } + + prop->type = sPondPropInits[i].type; + prop->pos.x = sPondPropInits[i].pos.x; + prop->pos.y = sPondPropInits[i].pos.y; + prop->pos.z = sPondPropInits[i].pos.z; + prop->rotX = 0.0f; + prop->reedAngle = 0.0f; + + prop->timer = Rand_ZeroFloat(100.0f); + prop->drawDistance = 800.0f; + + if (prop->type == FS_PROP_REED) { + prop->scale = (EnFishing_RandZeroOne() * 0.25f) + 0.75f; + prop->reedAngle = Rand_ZeroFloat(2 * M_PI); + if (sLinkAge == 1) { + prop->scale *= 0.6f; + } + prop->drawDistance = 1200.0f; + } else if (prop->type == FS_PROP_WOOD_POST) { + prop->scale = 0.08f; + prop->drawDistance = 1200.0f; + colliderPos = prop->pos; + colliderPos.y += 50.0f; + EnFishing_SetColliderElement(i, &sFishingMain->collider, &colliderPos, prop->scale * 3.5f); + } else if (prop->type == FS_PROP_LILY_PAD) { + prop->scale = (EnFishing_RandZeroOne() * 0.3f) + 0.5f; + prop->rotY = Rand_ZeroFloat(2 * M_PI); + if (sLinkAge == 1) { + if ((i % 4) != 0) { + prop->scale *= 0.6f; + } else { + prop->type = FS_PROP_NONE; + } + } + } else { + prop->scale = (EnFishing_RandZeroOne() * 0.1f) + 0.3f; + prop->rotY = Rand_ZeroFloat(2 * M_PI); + prop->drawDistance = 1000.0f; + EnFishing_SetColliderElement(i, &sFishingMain->collider, &prop->pos, prop->scale); + } + + prop++; + } +} + +static FishingFishInit sFishInits[] = { + { 0, { 666, -45, 354 }, 38, 0.1f }, { 0, { 681, -45, 240 }, 36, 0.1f }, { 0, { 670, -45, 90 }, 41, 0.05f }, + { 0, { 615, -45, -450 }, 35, 0.2f }, { 0, { 500, -45, -420 }, 39, 0.1f }, { 0, { 420, -45, -550 }, 44, 0.05f }, + { 0, { -264, -45, -640 }, 40, 0.1f }, { 0, { -470, -45, -540 }, 34, 0.2f }, { 0, { -557, -45, -430 }, 54, 0.01f }, + { 0, { -260, -60, -330 }, 47, 0.05f }, { 0, { -500, -60, 330 }, 42, 0.06f }, { 0, { 428, -40, -283 }, 33, 0.2f }, + { 0, { 409, -70, -230 }, 57, 0.0f }, { 0, { 450, -67, -300 }, 63, 0.0f }, { 0, { -136, -65, -196 }, 71, 0.0f }, + { 1, { -561, -35, -547 }, 45, 0.0f }, { 1, { 667, -35, 317 }, 43, 0.0f }, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_U8(targetMode, 5, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 0, ICHAIN_STOP), }; +void EnFishing_Init(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnFishing* this = THIS; + u16 fishCount; + + Actor_ProcessInitChain(thisx, sInitChain); + ActorShape_Init(&thisx->shape, 0.0f, NULL, 0.0f); + + sLinkAge = gSaveContext.linkAge; + + if (thisx->params < 100) { + s16 i; + FishingGroupFish* fish; + + D_809171C8 = 0; + sFishingMain = this; + Collider_InitJntSph(globalCtx, &sFishingMain->collider); + Collider_SetJntSph(globalCtx, &sFishingMain->collider, thisx, &sJntSphInit, sFishingMain->colliderElements); + + thisx->params = 1; + + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gFishingOwnerSkel, &gFishingOwnerAnim, NULL, NULL, 0); + Animation_MorphToLoop(&this->skelAnime, &gFishingOwnerAnim, 0.0f); + + thisx->update = EnFishing_UpdateOwner; + thisx->draw = EnFishing_DrawOwner; + + thisx->shape.rot.y = -0x6000; + thisx->world.pos.x = 160.0f; + thisx->world.pos.y = -2.0f; + thisx->world.pos.z = 1208.0f; + + Actor_SetScale(thisx, 0.011f); + + thisx->focus.pos = thisx->world.pos; + thisx->focus.pos.y += 75.0f; + thisx->flags |= 9; + + if (sLinkAge != 1) { + // HIGH_SCORE(HS_FISHING) from OoT + if (gSaveContext.roomInf[127][2] & 0x1000) { + D_8090CD08 = 0; + } else { + D_8090CD08 = 1; + } + } else { + D_8090CD08 = 2; + } + + D_8090CD04 = 20; + globalCtx->specialEffects = sFishingEffects; + REG(15) = 1; // gTimeIncrement in OoT + D_809171FC = 0; + D_809171F6 = 10; + + Audio_QueueSeqCmd(0x100100FF); + + if (sLinkAge == 1) { + if (gSaveContext.roomInf[127][2] & 0x7F) { + D_809171CC = gSaveContext.roomInf[127][2] & 0x7F; + } else { + D_809171CC = 40.0f; + } + } else if (gSaveContext.roomInf[127][2] & 0x7F000000) { + D_809171CC = (gSaveContext.roomInf[127][2] & 0x7F000000) >> 0x18; + } else { + D_809171CC = 45.0f; + } + + D_809171D1 = (gSaveContext.roomInf[127][2] & 0xFF0000) >> 0x10; + if ((D_809171D1 & 7) == 7) { + globalCtx->roomCtx.unk7A[0] = 90; + D_809171CA = 1; + } else { + globalCtx->roomCtx.unk7A[0] = 40; + D_809171CA = 0; + } + + if ((D_809171D1 & 7) == 6) { + D_809171CB = 100; + } else { + D_809171CB = 0; + } + + for (i = 0; i < EFFECT_COUNT; i++) { + sFishingEffects[i].type = FS_EFF_NONE; + } + + for (i = 0; i < POND_PROP_COUNT; i++) { + sPondProps[i].type = FS_PROP_NONE; + } + + sFishGroupAngle1 = 0.7f; + sFishGroupAngle2 = 2.3f; + sFishGroupAngle3 = 4.6f; + + for (i = 0; i < GROUP_FISH_COUNT; i++) { + fish = &sGroupFishes[i]; + + fish->type = FS_GROUP_FISH_NORMAL; + + if (i <= 20) { + fish->unk_10.x = fish->pos.x = __sinf(sFishGroupAngle1) * 720.0f; + fish->unk_10.z = fish->pos.z = __cosf(sFishGroupAngle1) * 720.0f; + } else if (i <= 40) { + fish->unk_10.x = fish->pos.x = __sinf(sFishGroupAngle2) * 720.0f; + fish->unk_10.z = fish->pos.z = __cosf(sFishGroupAngle2) * 720.0f; + } else { + fish->unk_10.x = fish->pos.x = __sinf(sFishGroupAngle3) * 720.0f; + fish->unk_10.z = fish->pos.z = __cosf(sFishGroupAngle3) * 720.0f; + } + + fish->unk_10.y = fish->pos.y = -35.0f; + + fish->timer = Rand_ZeroFloat(100.0f); + + fish->unk_3C = 0; + fish->unk_3E = 0; + fish->unk_40 = 0; + + if (sLinkAge != 1) { + if (((i >= 15) && (i < 20)) || ((i >= 35) && (i < 40)) || ((i >= 55) && (i < 60))) { + fish->type = FS_GROUP_FISH_NONE; + } + } + } + + EnFishing_InitPondProps(this, globalCtx); + Actor_SpawnAsChild(&globalCtx->actorCtx, thisx, globalCtx, ACTOR_EN_KANBAN, 53.0f, -17.0f, 982.0f, 0, 0, 0, + ENKANBAN_FISHING); + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_FISHING, 0.0f, 0.0f, 0.0f, 0, 0, 0, 200); + + if ((D_809171D1 & 3) == 3) { + if (sLinkAge != 1) { + fishCount = 16; + } else { + fishCount = 17; + } + } else { + fishCount = 15; + } + + for (i = 0; i < fishCount; i++) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_FISHING, sFishInits[i].pos.x, sFishInits[i].pos.y, + sFishInits[i].pos.z, 0, Rand_ZeroFloat(0x10000), 0, 100 + i); + } + + return; + } + + thisx->bgCheckFlags |= 0x800; // Added in MM + + if ((thisx->params < 115) || (thisx->params == 200)) { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gFishingFishSkel, &gFishingFishAnim, NULL, NULL, 0); + Animation_MorphToLoop(&this->skelAnime, &gFishingFishAnim, 0.0f); + } else { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gFishingLoachSkel, &gFishingLoachAnim, NULL, NULL, 0); + Animation_MorphToLoop(&this->skelAnime, &gFishingLoachAnim, 0.0f); + } + + SkelAnime_Update(&this->skelAnime); + + if (thisx->params == 200) { + this->unk_150 = 100; + func_800BC154(globalCtx, &globalCtx->actorCtx, thisx, ACTORCAT_PROP); + thisx->targetMode = 0; + thisx->flags |= 9; + this->lightNode = LightContext_InsertLight(globalCtx, &globalCtx->lightCtx, &this->lightInfo); + } else { + this->unk_150 = 10; + this->unk_152 = 10; + + this->unk_148 = sFishInits[thisx->params - 100].unk_00; + this->unk_1A0 = sFishInits[thisx->params - 100].unk_0C; + this->unk_1A4 = sFishInits[thisx->params - 100].unk_08; + + this->unk_1A4 += Rand_ZeroFloat(4.99999f); + + if ((this->unk_1A4 >= 65.0f) && (Rand_ZeroOne() < 0.05f)) { + this->unk_1A4 += Rand_ZeroFloat(7.99999f); + } + + if (sLinkAge == 1) { + this->unk_1A4 *= 0.73f; + } + } +} + +void EnFishing_Destroy(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnFishing* this = THIS; + + SkelAnime_Free(&this->skelAnime, globalCtx); + + if (thisx->params == 200) { + LightContext_RemoveLight(globalCtx, &globalCtx->lightCtx, this->lightNode); + } else if (thisx->params == 1) { + Collider_DestroyJntSph(globalCtx, &this->collider); + } +} + +void EnFishing_UpdateEffects(FishingEffect* effect, GlobalContext* globalCtx) { + f32 rippleY; + s16 i; + + for (i = 0; i < EFFECT_COUNT; i++) { + if (effect->type) { + effect->timer++; + effect->pos.x += effect->vel.x; + effect->pos.y += effect->vel.y; + effect->pos.z += effect->vel.z; + effect->vel.y += effect->accel.y; + + if (effect->type == FS_EFF_RIPPLE) { + Math_ApproachF(&effect->unk_30, effect->unk_34, 0.2f, effect->unk_38); + + if (effect->unk_2C == 0) { + effect->alpha += 20; + + if (effect->alpha >= effect->unk_2E) { + effect->alpha = effect->unk_2E; + effect->unk_2C++; + } + } else { + effect->alpha -= 8; + + if (effect->alpha <= 0) { + effect->type = FS_EFF_NONE; + } + } + } else if (effect->type == FS_EFF_WATER_DUST) { + Math_ApproachF(&effect->unk_30, effect->unk_34, 0.1f, 0.1f); + effect->alpha -= 10; + + if (effect->pos.y > (WATER_SURFACE_Y(globalCtx) - 5.0f)) { + effect->accel.y = 0.0f; + effect->vel.y = 0.0f; + effect->alpha -= 5; + } + + if (effect->alpha <= 0) { + effect->type = FS_EFF_NONE; + } + } else if (effect->type == FS_EFF_BUBBLE) { + if (effect->unk_2C == 0) { + rippleY = WATER_SURFACE_Y(globalCtx); + } else { + rippleY = 69.0f; + } + + if (effect->pos.y >= rippleY) { + effect->type = FS_EFF_NONE; + + if (Rand_ZeroOne() < 0.3f) { + Vec3f pos = effect->pos; + pos.y = rippleY; + EnFishing_SpawnRipple(NULL, globalCtx->specialEffects, &pos, 20.0f, 60.0f, 150, 90); + } + } + } else if (effect->type == FS_EFF_DUST_SPLASH) { + if (effect->vel.y < -20.0f) { + effect->vel.y = -20.0f; + effect->accel.y = 0.0f; + } + + if (effect->pos.y <= WATER_SURFACE_Y(globalCtx)) { + effect->type = FS_EFF_NONE; + if (Rand_ZeroOne() < 0.5f) { + Vec3f pos = effect->pos; + pos.y = WATER_SURFACE_Y(globalCtx); + EnFishing_SpawnRipple(NULL, globalCtx->specialEffects, &pos, 40.0f, 110.0f, 150, 90); + } + } + } else if (effect->type == FS_EFF_RAIN_DROP) { + if (effect->pos.y < WATER_SURFACE_Y(globalCtx)) { + f32 sqDistXZ = SQ(effect->pos.x) + SQ(effect->pos.z); + + if (sqDistXZ > SQ(920.0f)) { + effect->pos.y = WATER_SURFACE_Y(globalCtx) + ((sqrtf(sqDistXZ) - 920.0f) * 0.11f); + effect->timer = 2; + effect->type = FS_EFF_RAIN_SPLASH; + effect->unk_30 = (KREG(18) + 30) * 0.001f; + } else { + effect->pos.y = WATER_SURFACE_Y(globalCtx) + 3.0f; + effect->timer = 0; + if (Rand_ZeroOne() < 0.75f) { + effect->type = FS_EFF_RAIN_RIPPLE; + effect->vel = sZeroVec; + effect->unk_30 = 30 * 0.001f; + } else { + effect->type = FS_EFF_NONE; + } + } + + effect->vel = sZeroVec; + } + } else if (effect->type >= FS_EFF_RAIN_RIPPLE) { + effect->unk_30 += (KREG(18) + 30) * 0.001f; + + if (effect->timer >= 6) { + effect->type = FS_EFF_NONE; + } + } else if (effect->type == FS_EFF_OWNER_HAT) { + f32 sqDistXZ; + f32 bottomY; + + effect->unk_30 = 0.010000001f; + + Math_ApproachS(&sEffOwnerHatRot.y, 0, 20, 100); + Math_ApproachS(&sEffOwnerHatRot.x, 0, 20, 100); + Math_ApproachS(&sEffOwnerHatRot.z, -0x4000, 20, 100); + + sqDistXZ = SQ(effect->pos.x) + SQ(effect->pos.z); + bottomY = WATER_SURFACE_Y(globalCtx) + ((sqrtf(sqDistXZ) - 920.0f) * 0.147f); + + if (effect->pos.y > (bottomY - 10.0f)) { + effect->pos.y -= 0.1f; + } + + if ((effect->timer % 16) == 0) { + Vec3f pos = effect->pos; + pos.y = WATER_SURFACE_Y(globalCtx); + EnFishing_SpawnRipple(NULL, globalCtx->specialEffects, &pos, 30.0f, 300.0f, 150, 90); + } + + if (effect->unk_2C >= 0) { + effect->unk_2C++; + } + + if (effect->unk_2C == 30) { + func_801518B0(globalCtx, 0x40B3, NULL); + } + + if ((effect->unk_2C >= 100) && (func_80152498(&globalCtx->msgCtx) == 5)) { + if (func_80147624(globalCtx) || !func_80152498(&globalCtx->msgCtx)) { + func_801477B4(globalCtx); + func_801159EC(-50); + effect->unk_2C = -1; + } + } + } + } + + effect++; + } +} + +void EnFishing_DrawEffects(FishingEffect* effect, GlobalContext* globalCtx) { + u8 flag = 0; + f32 rotY; + s16 i; + s32 pad; + FishingEffect* firstEffect = effect; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_StatePush(); + + gDPPipeSync(POLY_XLU_DISP++); + + for (i = 0; i < 100; i++) { + if (effect->type == FS_EFF_RIPPLE) { + if (flag == 0) { + gSPDisplayList(POLY_XLU_DISP++, gFishingRippleSetupDL); + gDPSetEnvColor(POLY_XLU_DISP++, 155, 155, 155, 0); + flag++; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, effect->alpha); + + Matrix_InsertTranslation(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW); + Matrix_Scale(effect->unk_30, 1.0f, effect->unk_30, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_XLU_DISP++, gFishingRippleVtxDL); + } + effect++; + } + + effect = firstEffect; + flag = 0; + for (i = 0; i < 100; i++) { + if (effect->type == FS_EFF_DUST_SPLASH) { + if (flag == 0) { + gSPDisplayList(POLY_XLU_DISP++, gFishingDustSplashSetupDL); + gDPSetEnvColor(POLY_XLU_DISP++, 200, 200, 200, 0); + flag++; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 180, 180, 180, effect->alpha); + + Matrix_InsertTranslation(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + Matrix_Scale(effect->unk_30, effect->unk_30, 1.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_XLU_DISP++, gFishingDustSplashVtxDL); + } + effect++; + } + + effect = firstEffect; + flag = 0; + for (i = 0; i < 100; i++) { + if (effect->type == FS_EFF_WATER_DUST) { + if (flag == 0) { + gSPDisplayList(POLY_OPA_DISP++, gFishingWaterDustSetupDL); + gDPSetEnvColor(POLY_OPA_DISP++, 40, 90, 80, 128); + flag++; + } + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 40, 90, 80, effect->alpha); + + gSPSegment(POLY_OPA_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, effect->timer + (i * 3), + (effect->timer + (i * 3)) * 5, 32, 64, 1, 0, 0, 32, 32)); + + Matrix_InsertTranslation(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + Matrix_Scale(effect->unk_30, effect->unk_30, 1.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_OPA_DISP++, gFishingWaterDustVtxDL); + } + effect++; + } + + effect = firstEffect; + flag = 0; + for (i = 0; i < 100; i++) { + if (effect->type == FS_EFF_BUBBLE) { + if (flag == 0) { + gSPDisplayList(POLY_XLU_DISP++, gFishingBubbleSetupDL); + gDPSetEnvColor(POLY_XLU_DISP++, 150, 150, 150, 0); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 255); + flag++; + } + + Matrix_InsertTranslation(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + Matrix_Scale(effect->unk_30, effect->unk_30, 1.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_XLU_DISP++, gFishingBubbleVtxDL); + } + effect++; + } + + effect = firstEffect + 30; + flag = 0; + for (i = 30; i < EFFECT_COUNT; i++) { + if (effect->type == FS_EFF_RAIN_DROP) { + if (flag == 0) { + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0x14); + gDPSetCombineMode(POLY_XLU_DISP++, G_CC_PRIMITIVE, G_CC_PRIMITIVE); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 150, 255, 255, 30); + flag++; + } + + Matrix_InsertTranslation(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW); + Matrix_InsertYRotation_f(effect->unk_38, MTXMODE_APPLY); + Matrix_RotateStateAroundXAxis(effect->unk_34); + Matrix_InsertZRotation_f(effect->unk_3C, MTXMODE_APPLY); + Matrix_Scale(0.002f, 1.0f, 0.1f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_XLU_DISP++, gFishingRainDropVtxDL); + } + effect++; + } + + func_8012C2DC(globalCtx->state.gfxCtx); + + effect = firstEffect + 30; + flag = 0; + for (i = 30; i < EFFECT_COUNT; i++) { + if (effect->type == FS_EFF_RAIN_RIPPLE) { + if (flag == 0) { + gSPDisplayList(POLY_XLU_DISP++, gFishingRippleSetupDL); + gDPSetEnvColor(POLY_XLU_DISP++, 155, 155, 155, 0); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 130); + flag++; + } + + Matrix_InsertTranslation(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW); + Matrix_Scale(effect->unk_30, 1.0f, effect->unk_30, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_XLU_DISP++, gFishingRippleVtxDL); + } + effect++; + } + + effect = firstEffect + 30; + flag = 0; + for (i = 30; i < EFFECT_COUNT; i++) { + if (effect->type == FS_EFF_RAIN_SPLASH) { + if (flag == 0) { + gSPDisplayList(POLY_XLU_DISP++, gFishingRainSplashSetupDL); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, KREG(19) + 80); + flag++; + } + + if (Rand_ZeroOne() < 0.5f) { + rotY = 0.0f; + } else { + rotY = M_PI; + } + + Matrix_InsertTranslation(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + Matrix_InsertYRotation_f(rotY, MTXMODE_APPLY); + Matrix_Scale(effect->unk_30, effect->unk_30, 1.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_XLU_DISP++, gFishingRainSplashVtxDL); + } + effect++; + } + + effect = firstEffect; + if (effect->type == FS_EFF_OWNER_HAT) { + Matrix_InsertTranslation(effect->pos.x, effect->pos.y, effect->pos.z, MTXMODE_NEW); + Matrix_InsertYRotation_f((sEffOwnerHatRot.y * M_PI) / 32768, MTXMODE_APPLY); + Matrix_RotateStateAroundXAxis((sEffOwnerHatRot.x * M_PI) / 32768); + Matrix_InsertZRotation_f((sEffOwnerHatRot.z * M_PI) / 32768, MTXMODE_APPLY); + Matrix_Scale(effect->unk_30, effect->unk_30, effect->unk_30, MTXMODE_APPLY); + Matrix_InsertTranslation(-1250.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateStateAroundXAxis(M_PI / 2); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_OPA_DISP++, gFishingOwnerHatDL); + } + + Matrix_StatePop(); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnFishing_DrawStreamSplash(GlobalContext* globalCtx) { + s32 pad; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gSPSegment(POLY_XLU_DISP++, 0x09, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, globalCtx->gameplayFrames * 1, + globalCtx->gameplayFrames * 8, 32, 64, 1, -globalCtx->gameplayFrames * 2, 0, 16, 16)); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 225, 235, 50); + + Matrix_InsertTranslation(670.0f, -24.0f, -600.0f, MTXMODE_NEW); + Matrix_Scale(0.02f, 1.0f, 0.02f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gFishingStreamSplashDL); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +s32 func_808FEF70(Vec3f* vec) { + if (((vec->x >= 110.0f) && (vec->x <= 150.0f) && (vec->z <= 1400.0f) && (vec->z >= 1160.0f)) || + ((vec->x >= 110.0f) && (vec->x <= 210.0f) && (vec->z <= 1200.0f) && (vec->z >= 1160.0f))) { + if (vec->y <= 42.0f) { + return true; + } + } + + return false; +} + +void EnFishing_UpdateLine(GlobalContext* globalCtx, Vec3f* basePos, Vec3f* pos, Vec3f* rot, Vec3f* unk) { + s32 i; + s32 k; + f32 dx; + f32 dy; + f32 dz; + f32 rx; + f32 ry; + f32 dist; + f32 spD8; + s32 temp_s2; + s32 pad; + f32 temp_f20; + Vec3f posSrc = { 0.0f, 0.0f, 0.0f }; + Vec3f posStep; + f32 phi_f12; + Vec3f spA4; + Vec3f sp98; + f32 sp94; + f32 sp90; + f32 sp8C; + f32 sqDistXZ; + f32 temp_f18; + + if (D_8090CD24 != 0) { + spA4 = *basePos; + sp98 = pos[LINE_SEG_COUNT - 1]; + + sp94 = sp98.x - spA4.x; + sp90 = sp98.y - spA4.y; + sp8C = sp98.z - spA4.z; + + temp_f20 = sqrtf(SQ(sp94) + SQ(sp90) + SQ(sp8C)) * 0.97f; + if (temp_f20 > 1000.0f) { + temp_f20 = 1000.0f; + } + + D_809101C0 = 200.0f - (temp_f20 * 200.0f * 0.001f); + } + + temp_s2 = D_809101C0; + posSrc.z = 5.0f; + + for (i = 0; i < LINE_SEG_COUNT; i++) { + if (i <= temp_s2) { + pos[i] = *basePos; + } else if (D_8090CD24 != 0) { + temp_f20 = (f32)(i - temp_s2) / (f32)(LINE_SEG_COUNT - temp_s2 + 1); + Math_ApproachF(&pos[i].x, (sp94 * temp_f20) + spA4.x, 1.0f, 20.0f); + Math_ApproachF(&pos[i].y, (sp90 * temp_f20) + spA4.y, 1.0f, 20.0f); + Math_ApproachF(&pos[i].z, (sp8C * temp_f20) + spA4.z, 1.0f, 20.0f); + } + } + + for (i = temp_s2 + 1, k = 0; i < LINE_SEG_COUNT; i++, k++) { + temp_f18 = 2.0f * D_809101C4; + + dx = (pos + i)->x - (pos + i - 1)->x; + spD8 = (pos + i)->y; + + sqDistXZ = SQ((pos + i)->x) + SQ((pos + i)->z); + + if (sqDistXZ > SQ(920.0f)) { + phi_f12 = ((sqrtf(sqDistXZ) - 920.0f) * 0.11f) + WATER_SURFACE_Y(globalCtx); + } else { + phi_f12 = WATER_SURFACE_Y(globalCtx); + } + + if (D_80917206 == 2) { + f32 phi_f2; + + if (spD8 < phi_f12) { + phi_f12 = ((sqrtf(sqDistXZ) - 920.0f) * 0.147f) + WATER_SURFACE_Y(globalCtx); + if (spD8 > phi_f12) { + u8 temp; + + phi_f2 = (spD8 - phi_f12) * 0.05f; + + if (phi_f2 > 0.29999998f) { + phi_f2 = 0.29999998f; + } + if (i >= 100) { + phi_f2 *= (i - 100) * 0.02f; + spD8 -= phi_f2; + } + } + } else { + spD8 -= temp_f18; + } + } else if (i > LINE_SEG_COUNT - 10) { + if (spD8 > phi_f12) { + f32 phi_f2 = (spD8 - phi_f12) * 0.2f; + + phi_f2 = CLAMP_MAX(phi_f2, temp_f18); + spD8 -= phi_f2; + } + } else { + if (spD8 > phi_f12) { + spD8 -= temp_f18; + } + } + + if (func_808FEF70(&pos[i])) { + spD8 = 42.0f; + } + + dy = spD8 - (pos + i - 1)->y; + dz = (pos + i)->z - (pos + i - 1)->z; + + ry = Math_Acot2F(dz, dx); + dist = sqrtf(SQ(dx) + SQ(dz)); + rx = -Math_Acot2F(dist, dy); + + (rot + i - 1)->y = ry; + (rot + i - 1)->x = rx; + + Matrix_InsertYRotation_f(ry, MTXMODE_NEW); + Matrix_RotateStateAroundXAxis(rx); + Matrix_MultiplyVector3fByState(&posSrc, &posStep); + + (pos + i)->x = (pos + i - 1)->x + posStep.x; + (pos + i)->y = (pos + i - 1)->y + posStep.y; + (pos + i)->z = (pos + i - 1)->z + posStep.z; + } +} + +void EnFishing_UpdateLinePos(Vec3f* pos) { + s32 i; + f32 dx; + f32 dy; + f32 dz; + f32 rx; + f32 ry; + f32 dist; + Vec3f posSrc = { 0.0f, 0.0f, 0.0f }; + Vec3f posStep; + s32 min = D_809101C0; + + posSrc.z = 5.0f; + + for (i = LINE_SEG_COUNT - 2; i > min; i--) { + dx = (pos + i)->x - (pos + i + 1)->x; + dy = (pos + i)->y - (pos + i + 1)->y; + dz = (pos + i)->z - (pos + i + 1)->z; + + ry = Math_Acot2F(dz, dx); + dist = sqrtf(SQ(dx) + SQ(dz)); + rx = -Math_Acot2F(dist, dy); + + Matrix_InsertYRotation_f(ry, MTXMODE_NEW); + Matrix_RotateStateAroundXAxis(rx); + Matrix_MultiplyVector3fByState(&posSrc, &posStep); + + (pos + i)->x = (pos + i + 1)->x + posStep.x; + (pos + i)->y = (pos + i + 1)->y + posStep.y; + (pos + i)->z = (pos + i + 1)->z + posStep.z; + } +} + +void EnFishing_DrawLureHook(GlobalContext* globalCtx, Vec3f* pos, Vec3f* refPos, u8 hookIndex) { + f32 dx; + f32 dy; + f32 dz; + f32 rx; + f32 ry; + f32 dist; + f32 offsetY; + Vec3f posSrc = { 0.0f, 0.0f, 1.0f }; + Vec3f posStep; + Player* player = GET_PLAYER(globalCtx); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_StatePush(); + + if ((D_8090CD14 == 3) && ((pos->y > WATER_SURFACE_Y(globalCtx)) || ((D_8090CD0C != 0) && hookIndex))) { + offsetY = 0.0f; + } else if (pos->y < WATER_SURFACE_Y(globalCtx)) { + offsetY = -1.0f; + } else { + offsetY = -3.0f; + } + + dx = refPos->x - pos->x; + dy = refPos->y - pos->y + offsetY; + dz = refPos->z - pos->z; + + ry = Math_Acot2F(dz, dx); + dist = sqrtf(SQ(dx) + SQ(dz)); + rx = -Math_Acot2F(dist, dy); + + Matrix_InsertYRotation_f(ry, MTXMODE_NEW); + Matrix_RotateStateAroundXAxis(rx); + Matrix_MultiplyVector3fByState(&posSrc, &posStep); + + refPos->x = pos->x + posStep.x; + refPos->y = pos->y + posStep.y; + refPos->z = pos->z + posStep.z; + + Matrix_InsertTranslation(pos->x, pos->y, pos->z, MTXMODE_NEW); + + if ((player->actor.speedXZ == 0.0f) && (D_809101B4 == 0.0f)) { + Math_ApproachF(&sLureHookRotY[hookIndex], ry, 0.1f, 0.3f); + } else { + sLureHookRotY[hookIndex] = ry; + } + + Matrix_InsertYRotation_f(sLureHookRotY[hookIndex], MTXMODE_APPLY); + Matrix_RotateStateAroundXAxis(rx); + Matrix_Scale(0.0039999997f, 0.0039999997f, 0.005f, MTXMODE_APPLY); + Matrix_InsertYRotation_f(M_PI, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gFishingLureHookDL); + + Matrix_InsertZRotation_f(M_PI / 2, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gFishingLureHookDL); + + if ((hookIndex == 1) && (D_8090CD0C != 0)) { + Matrix_Scale(2.0f, 2.0f, 2.0f, MTXMODE_APPLY); + Matrix_InsertTranslation(250.0f, 0.0f, -1400.0f, MTXMODE_APPLY); + Matrix_StatePush(); + + if (D_8090CD10 != 0) { + FishingEffect* effect = globalCtx->specialEffects; + MtxF mf; + + Matrix_MultiplyVector3fByState(&sZeroVec, &effect->pos); + Matrix_CopyCurrentState(&mf); + func_8018219C(&mf, &sEffOwnerHatRot, 0); + + D_8090CD10 = 0; + D_8090CD0C = 0; + + effect->type = FS_EFF_OWNER_HAT; + effect->unk_2C = 0; + effect->vel = sZeroVec; + effect->accel = sZeroVec; + } + + Matrix_StatePop(); + Matrix_InsertTranslation(-1250.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_RotateStateAroundXAxis(M_PI / 2); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gFishingOwnerHatDL); + } + + Matrix_StatePop(); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnFishing_UpdateSinkingLure(GlobalContext* globalCtx) { + s32 i; + f32 dx; + f32 dy; + f32 dz; + f32 rx; + f32 ry; + f32 dist; + f32 offsetY; + Vec3f posSrc = { 0.0f, 0.0f, 0.0f }; + Vec3f posStep; + Vec3f sp94; + Vec3f sp88; + f32 offsetX; + f32 offsetZ; + Player* player = GET_PLAYER(globalCtx); + Vec3f* pos; + s32 pad; + + posSrc.z = 0.85f; + + sSinkingLurePos[0] = sLurePos; + + if (D_8090CD54 != 0) { + offsetY = -1.0f; + } else if (sLurePos.y < WATER_SURFACE_Y(globalCtx)) { + offsetY = 0.5f; + } else { + offsetY = -5.0f; + } + + if (D_8090CD14 == 5) { + Matrix_InsertYRotation_f(player->actor.shape.rot.y * (M_PI / 32768), MTXMODE_NEW); + sp94.x = 5.0f; + sp94.y = 0.0f; + sp94.z = 3.0f; + Matrix_MultiplyVector3fByState(&sp94, &sp88); + } + + for (i = 1; i < SINKING_LURE_SEG_COUNT; i++) { + pos = sSinkingLurePos; + + if ((i < 10) && (D_8090CD14 == 5)) { + offsetX = (10 - i) * sp88.x * 0.1f; + offsetZ = (10 - i) * sp88.z * 0.1f; + } else { + offsetX = offsetZ = 0.0f; + } + + dx = (pos + i)->x - (pos + i - 1)->x + offsetX; + dy = (pos + i)->y - (pos + i - 1)->y + offsetY; + dz = (pos + i)->z - (pos + i - 1)->z + offsetZ; + + ry = Math_Acot2F(dz, dx); + dist = sqrtf(SQ(dx) + SQ(dz)); + rx = -Math_Acot2F(dist, dy); + + Matrix_InsertYRotation_f(ry, MTXMODE_NEW); + Matrix_RotateStateAroundXAxis(rx); + Matrix_MultiplyVector3fByState(&posSrc, &posStep); + + (pos + i)->x = (pos + i - 1)->x + posStep.x; + (pos + i)->y = (pos + i - 1)->y + posStep.y; + (pos + i)->z = (pos + i - 1)->z + posStep.z; + } +} + +static f32 sSinkingLureSizes[] = { + 1.0f, 1.5f, 1.8f, 2.0f, 1.8f, 1.6f, 1.4f, 1.2f, 1.0f, 1.0f, + 0.9f, 0.85f, 0.8f, 0.7f, 0.8f, 1.0f, 1.2f, 1.1f, 1.0f, 0.8f, +}; + +void EnFishing_DrawSinkingLure(GlobalContext* globalCtx) { + s16 i; + f32 scale; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + EnFishing_UpdateSinkingLure(globalCtx); + + if (sLurePos.y < WATER_SURFACE_Y(globalCtx)) { + func_8012C28C(globalCtx->state.gfxCtx); + + gSPDisplayList(POLY_OPA_DISP++, gFishingSinkingLureSegmentSetupDL); + + for (i = SINKING_LURE_SEG_COUNT - 1; i >= 0; i--) { + if ((i + D_80911F20) < SINKING_LURE_SEG_COUNT) { + Matrix_InsertTranslation(sSinkingLurePos[i].x, sSinkingLurePos[i].y, sSinkingLurePos[i].z, MTXMODE_NEW); + scale = sSinkingLureSizes[i + D_80911F20] * 0.04f; + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gFishingSinkingLureSegmentVtxDL); + } + } + } else { + func_8012C2DC(globalCtx->state.gfxCtx); + + gSPDisplayList(POLY_XLU_DISP++, gFishingSinkingLureSegmentSetupDL); + + for (i = SINKING_LURE_SEG_COUNT - 1; i >= 0; i--) { + if ((i + D_80911F20) < SINKING_LURE_SEG_COUNT) { + Matrix_InsertTranslation(sSinkingLurePos[i].x, sSinkingLurePos[i].y, sSinkingLurePos[i].z, MTXMODE_NEW); + scale = sSinkingLureSizes[i + D_80911F20] * 0.04f; + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gFishingSinkingLureSegmentVtxDL); + } + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnFishing_DrawLureAndLine(GlobalContext* globalCtx, Vec3f* linePos, Vec3f* lineRot) { + Vec3f posSrc; + Vec3f posStep; + Vec3f hookPos[2]; + s32 i; + s32 spB4 = D_809101C0; + s32 pad; + Player* player = GET_PLAYER(globalCtx); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + Matrix_StatePush(); + + if (D_8090CD54 != 0) { + Vec3f posTemp = sLurePos; + + sLurePos = sSinkingLureBasePos; + EnFishing_DrawSinkingLure(globalCtx); + sLurePos = posTemp; + } + + if ((D_8090CD14 == 4) || (D_8090CD14 == 5)) { + sLurePos = sFishingHookedFish->fishMouthPos; + + if ((D_8090CD14 == 5) && (D_80917206 == 2)) { + Matrix_InsertYRotation_f(player->actor.shape.rot.y * (M_PI / 32768), MTXMODE_NEW); + posSrc.x = 2.0f; + posSrc.y = 0.0f; + posSrc.z = 0.0f; + Matrix_MultiplyVector3fByState(&posSrc, &posStep); + sLurePos.x += posStep.x; + sLurePos.z += posStep.z; + } + } else if (D_8090CD14 == 0) { + sLurePos = sReelLinePos[LINE_SEG_COUNT - 1]; + sLureRot.x = sReelLineRot[LINE_SEG_COUNT - 2].x + M_PI; + + if ((player->actor.speedXZ == 0.0f) && (D_80917200 == 0)) { + Math_ApproachF(&sLureRot.y, sReelLineRot[LINE_SEG_COUNT - 2].y, 0.1f, 0.2f); + } else { + sLureRot.y = sReelLineRot[LINE_SEG_COUNT - 2].y; + } + } + + if (D_80917206 != 2) { + Matrix_InsertTranslation(sLurePos.x, sLurePos.y, sLurePos.z, MTXMODE_NEW); + Matrix_InsertYRotation_f(sLureRot.y + D_80917254, MTXMODE_APPLY); + Matrix_RotateStateAroundXAxis(sLureRot.x); + Matrix_Scale(0.0039999997f, 0.0039999997f, 0.0039999997f, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, 0.0f, D_80917258, MTXMODE_APPLY); + Matrix_InsertZRotation_f(M_PI / 2, MTXMODE_APPLY); + Matrix_InsertYRotation_f(M_PI / 2, MTXMODE_APPLY); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gFishingLureFloatDL); + + posSrc.x = -850.0f; + posSrc.y = 0.0f; + posSrc.z = 0.0f; + Matrix_MultiplyVector3fByState(&posSrc, &D_80917218); + + posSrc.x = 500.0f; + posSrc.z = -300.0f; + Matrix_MultiplyVector3fByState(&posSrc, &hookPos[0]); + EnFishing_DrawLureHook(globalCtx, &hookPos[0], &sLureHookRefPos[0], 0); + + posSrc.x = 2100.0f; + posSrc.z = -50.0f; + Matrix_MultiplyVector3fByState(&posSrc, &hookPos[1]); + EnFishing_DrawLureHook(globalCtx, &hookPos[1], &sLureHookRefPos[1], 1); + } + + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0x14); + + gDPSetCombineMode(POLY_XLU_DISP++, G_CC_PRIMITIVE, G_CC_PRIMITIVE); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 55); + + if ((D_8090CD14 == 4) && ((D_80917274 != 0) || (D_80917206 != 2))) { + f32 rx; + f32 ry; + f32 dist; + f32 dx; + f32 dy; + f32 dz; + + dx = sLurePos.x - sRodTipPos.x; + dy = sLurePos.y - sRodTipPos.y; + dz = sLurePos.z - sRodTipPos.z; + + ry = func_80086B30(dx, dz); + dist = sqrtf(SQ(dx) + SQ(dz)); + rx = -func_80086B30(dy, dist); + + dist = sqrtf(SQ(dx) + SQ(dy) + SQ(dz)) * 0.001f; + + Matrix_InsertTranslation(sRodTipPos.x, sRodTipPos.y, sRodTipPos.z, MTXMODE_NEW); + Matrix_InsertYRotation_f(ry, MTXMODE_APPLY); + Matrix_RotateStateAroundXAxis(rx); + Matrix_Scale(D_809101C8, 1.0f, dist, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gFishingLineVtxDL); + } else { + for (i = spB4; i < LINE_SEG_COUNT - 1; i++) { + if ((i == LINE_SEG_COUNT - 3) && (D_80917206 == 0) && (D_8090CD14 == 3)) { + f32 rx; + f32 ry; + f32 dist; + f32 dx; + f32 dy; + f32 dz; + + dx = D_80917218.x - (linePos + i)->x; + dy = D_80917218.y - (linePos + i)->y; + dz = D_80917218.z - (linePos + i)->z; + + ry = func_80086B30(dx, dz); + dist = sqrtf(SQ(dx) + SQ(dz)); + rx = -func_80086B30(dy, dist); + + dist = sqrtf(SQ(dx) + SQ(dy) + SQ(dz)) * 0.001f; + + Matrix_InsertTranslation((linePos + i)->x, (linePos + i)->y, (linePos + i)->z, MTXMODE_NEW); + Matrix_InsertYRotation_f(ry, MTXMODE_APPLY); + Matrix_RotateStateAroundXAxis(rx); + Matrix_Scale(D_809101C8, 1.0f, dist, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gFishingLineVtxDL); + break; + } + + Matrix_InsertTranslation((linePos + i)->x, (linePos + i)->y, (linePos + i)->z, MTXMODE_NEW); + Matrix_InsertYRotation_f((lineRot + i)->y, MTXMODE_APPLY); + Matrix_RotateStateAroundXAxis((lineRot + i)->x); + Matrix_Scale(D_809101C8, 1.0f, 0.005f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gFishingLineVtxDL); + } + } + + Matrix_StatePop(); + func_8012C2DC(globalCtx->state.gfxCtx); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +static f32 sRodScales[22] = { + 1.0f, 1.0f, 1.0f, 0.9625f, 0.925f, 0.8875f, 0.85f, 0.8125f, + 0.775f, 0.73749995f, 0.7f, 0.6625f, 0.625f, 0.5875f, 0.54999995f, 0.5125f, + 0.47499996f, 0.4375f, 0.39999998f, 0.36249995f, 0.325f, 0.28749996f, +}; + +static f32 sRodBendRatios[22] = { + 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.06f, 0.12f, 0.18f, 0.24f, 0.30f, 0.36f, + 0.42f, 0.48f, 0.54f, 0.60f, 0.60f, 0.5142f, 0.4285f, 0.3428f, 0.2571f, 0.1714f, 0.0857f, +}; + +static Vec3f sRodTipOffset = { 0.0f, 0.0f, 0.0f }; + +void EnFishing_DrawRod(GlobalContext* globalCtx) { + s16 i; + f32 spC8; + f32 spC4; + f32 spC0; + Input* input = CONTROLLER1(globalCtx); + Player* player = GET_PLAYER(globalCtx); + s32 pad; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (D_80911E28 != 0) { + D_80911E28--; + + Math_ApproachF(&D_8090CD40, 35.0f, 1.0f, 100.0f); + Math_ApproachF(&D_8090CD3C, -0.8f, 1.0f, 0.4f); + Math_ApproachS(&player->actor.shape.rot.x, -4000, 2, 15000); + } else { + s16 target = 0; + + if ((D_8090CD14 == 4) && (D_80917274 != 0)) { + target = Math_SinS(D_809171FE * 25600) * 1500.0f; + } else { + Math_ApproachZeroF(&D_8090CD40, 0.1f, 10.0f); + Math_ApproachZeroF(&D_8090CD3C, 1.0f, 0.05f); + } + + Math_ApproachS(&player->actor.shape.rot.x, target, 5, 1000); + } + + if ((D_8090CD14 == 3) || (D_8090CD14 == 4)) { + if ((input->rel.stick_x == 0) && (D_8090CD44 != 0)) { + D_8090CD30 = 0.0f; + } + if ((input->rel.stick_y == 0) && (D_8090CD48 != 0)) { + D_8090CD34 = 0.0f; + } + + spC8 = player->unk_B08[1]; + Math_SmoothStepToF(&player->unk_B08[1], input->rel.stick_y * 0.02f, 0.3f, 5.0f, 0.0f); + spC8 = player->unk_B08[1] - spC8; + + spC4 = player->unk_B08[0]; + Math_SmoothStepToF(&player->unk_B08[0], input->rel.stick_x * 0.02f, 0.3f, 5.0f, 0.0f); + spC4 = player->unk_B08[0] - spC4; + + if (player->unk_B08[0] > 1.0f) { + player->unk_B08[0] = 1.0f; + } + if (player->unk_B08[1] > 1.0f) { + player->unk_B08[1] = 1.0f; + } + if (player->unk_B08[0] < -1.0f) { + player->unk_B08[0] = -1.0f; + } + if (player->unk_B08[1] < -1.0f) { + player->unk_B08[1] = -1.0f; + } + + Math_ApproachF(&D_8090CD28, spC4 * 70.0f * -0.01f, 1.0f, D_8090CD30); + Math_ApproachF(&D_8090CD30, 1.0f, 1.0f, 0.1f); + Math_ApproachF(&D_8090CD2C, spC8 * 70.0f * 0.01f, 1.0f, D_8090CD34); + Math_ApproachF(&D_8090CD34, 1.0f, 1.0f, 0.1f); + Math_ApproachZeroF(&D_8090CD38, 1.0f, 0.05f); + } else { + Math_ApproachZeroF(&player->unk_B08[1], 1.0f, 0.1f); + Math_ApproachZeroF(&player->unk_B08[0], 1.0f, 0.1f); + Math_ApproachF(&D_8090CD2C, (Math_SinS(D_809171FE * 3000) * 0.025f) + -0.03f, 1.0f, 0.05f); + Math_ApproachZeroF(&D_8090CD28, 1.0f, 0.05f); + + if ((D_80917204 >= 19) && (D_80917204 <= 24)) { + Math_ApproachF(&D_8090CD38, 0.8f, 1.0f, 0.2f); + } else { + Math_ApproachF(&D_8090CD38, 0.0f, 1.0f, 0.4f); + } + } + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPDisplayList(POLY_OPA_DISP++, gFishingRodSetupDL); + + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 155, 0, 255); + + Matrix_InsertMatrix(&player->mf_CC4, MTXMODE_NEW); + + if (sLinkAge != 1) { + Matrix_InsertTranslation(0.0f, 400.0f, 0.0f, MTXMODE_APPLY); + } else { + Matrix_InsertTranslation(0.0f, 230.0f, 0.0f, MTXMODE_APPLY); + } + + if (D_8090CD14 == 5) { + Matrix_InsertYRotation_f(1.7592919f, MTXMODE_APPLY); + } else { + Matrix_InsertYRotation_f(1.288053f, MTXMODE_APPLY); + } + + Matrix_RotateStateAroundXAxis(-0.6283185f); + Matrix_InsertZRotation_f((player->unk_B08[0] * 0.5f) + 0.4712389f, MTXMODE_APPLY); + Matrix_RotateStateAroundXAxis((D_8090CD40 + 20.0f) * 0.01f * M_PI); + Matrix_Scale(0.70000005f, 0.70000005f, 0.70000005f, MTXMODE_APPLY); + + spC0 = (D_8090CD3C * (((player->unk_B08[1] - 1.0f) * -0.25f) + 0.5f)) + (D_8090CD2C + D_8090CD38); + + Matrix_InsertTranslation(0.0f, 0.0f, -1300.0f, MTXMODE_APPLY); + + for (i = 0; i < 22; i++) { + Matrix_InsertYRotation_f(sRodBendRatios[i] * D_8090CD28 * 0.5f, MTXMODE_APPLY); + Matrix_RotateStateAroundXAxis(sRodBendRatios[i] * spC0 * 0.5f); + + Matrix_StatePush(); + Matrix_Scale(sRodScales[i], sRodScales[i], 0.52f, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + if (i < 5) { + gDPLoadTextureBlock(POLY_OPA_DISP++, &gFishingRodSegmentBlackTex, G_IM_FMT_RGBA, G_IM_SIZ_16b, 16, 8, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, 3, G_TX_NOLOD, G_TX_NOLOD); + } else if ((i < 8) || ((i % 2) == 0)) { + gDPLoadTextureBlock(POLY_OPA_DISP++, &gFishingRodSegmentWhiteTex, G_IM_FMT_RGBA, G_IM_SIZ_16b, 16, 8, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, 3, G_TX_NOLOD, G_TX_NOLOD); + } else { + gDPLoadTextureBlock(POLY_OPA_DISP++, &gFishingRodSegmentStripTex, G_IM_FMT_RGBA, G_IM_SIZ_16b, 16, 8, 0, + G_TX_NOMIRROR | G_TX_WRAP, G_TX_NOMIRROR | G_TX_WRAP, 4, 3, G_TX_NOLOD, G_TX_NOLOD); + } + + gSPDisplayList(POLY_OPA_DISP++, gFishingRodSegmentDL); + + Matrix_StatePop(); + Matrix_InsertTranslation(0.0f, 0.0f, 500.0f, MTXMODE_APPLY); + + if (i == 21) { + Matrix_MultiplyVector3fByState(&sRodTipOffset, &sRodTipPos); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +static Vec3f D_8090D614 = { 0.0f, 0.0f, 0.0f }; + +#ifdef NON_MATCHING +// Stack memes, the pad on line ~2410 makes stack too big, but needed for ordering +void EnFishing_UpdateLure(EnFishing* this, GlobalContext* globalCtx) { + f32 spE4; + f32 spE0; + s16 phi_v0; + s16 spDC; + f32 spD8; + f32 spD4; + f32 spD0; + f32 phi_f16; + f32 spC8; + s16 i; + Player* player = GET_PLAYER(globalCtx); + Vec3f zeroVec = { 0.0f, 0.0f, 0.0f }; + Vec3f spA8; + Vec3f sp9C; + Vec3f sp90; + Input* input = CONTROLLER1(globalCtx); + // Vec3f sp80; + + f32 phi_f0; + // f32 sp70; + // Vec3f sp64; + // Vec3f sp58; + // s32 pad; + + D_809171FE++; + + if (D_80917200 != 0) { + D_80917200--; + } + + if (D_80917202 != 0) { + D_80917202--; + } + + if (D_80917204 != 0) { + D_80917204--; + } + + if (D_80917272 != 0) { + D_80917272--; + } + + if (D_809101CC != 0) { + D_809101CC--; + } + + if (D_8090CD24 != 0) { + D_8090CD24--; + } + + if (D_809171F4 != 0) { + D_809171F4--; + } + + if (D_80917264 != 0) { + D_80917264--; + } + + if (D_809171FC == 1) { + D_809171FC = 2; + D_809171D8 = 0; + D_809171D6 = 0; + D_80917206 = 0; + + // Age and high score check removed in MM + sSinkingLureLocation = Rand_ZeroFloat(3.999f) + 1.0f; + + D_809101C4 = 520.0f; + D_809101C0 = 195.0f; + + D_8090CD14 = 0; + D_80917206 = 0; + D_809171FE = 0; + D_80917200 = 0; + D_80917202 = 0; + D_80917204 = 0; + D_80917270 = 0; + D_80917264 = 0; + D_809101CC = 0; + + D_80917254 = D_809101D0 = D_80917258 = 0.0f; + + D_80917278 = zeroVec; + + for (i = 0; i < LINE_SEG_COUNT; i++) { + sReelLinePos[i] = zeroVec; + sReelLineRot[i] = zeroVec; + sReelLineUnk[i] = zeroVec; + } + } + + SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, &sLurePos, &D_8090D614, &sProjectedW); + + if (D_8090CD14 == 0) { + Math_ApproachF(&D_80917258, -800.0f, 1.0f, 20.0f); + } else { + Math_ApproachF(&D_80917258, 300.0f, 1.0f, 20.0f); + } + + switch (D_8090CD14) { + case 0: + D_80911F20 = 0; + + Math_ApproachF(&D_809101C0, 195.0f, 1.0f, 1.0f); + + if (player->stateFlags1 & 0x8000000) { + D_80917204 = 0; + player->unk_B28 = 0; + } + + if (D_80917204 == 0) { + if ((D_80917200 == 0) && (player->unk_B28 == 1)) { + D_80917204 = 37; + func_801477B4(globalCtx); + } + } else { + sLureRot.x = sReelLineRot[LINE_SEG_COUNT - 2].x + M_PI; + sLureRot.y = sReelLineRot[LINE_SEG_COUNT - 2].y; + + if (D_80917204 == 18) { + D_8090CD14 = 1; + sLurePos = sRodTipPos; + Matrix_InsertYRotation_f(BINANG_TO_RAD(player->actor.shape.rot.y), MTXMODE_NEW); + sp90.x = 0.0f; + sp90.y = 0.0f; + sp90.z = 25.0f; + Matrix_MultiplyVector3fByState(&sp90, &D_80917238); + D_80917238.y = 15.0f; + D_80917248.x = D_80917248.z = 0.0f; + D_80917248.y = -1.0f; + D_809101C4 = 0.0f; + D_80917202 = 5; + D_8091726C = 0.5f; + D_80917268 = Rand_ZeroFloat(1.9f); + sFishMouthOffset.y = 500.0f; + func_8019F1C0(&D_8090D614, NA_SE_IT_SWORD_SWING_HARD); + } + } + break; + + case 1: + spE0 = sLurePos.y; + + sLurePos.x += D_80917238.x; + sLurePos.y += D_80917238.y; + sLurePos.z += D_80917238.z; + + D_80917238.x += D_80917248.x; + D_80917238.y += D_80917248.y; + D_80917238.z += D_80917248.z; + + if (CHECK_BTN_ALL(input->cur.button, BTN_A) || (D_8090CD0C != 0)) { + D_80917238.x *= 0.9f; + D_80917238.z *= 0.9f; + if (D_8090CD0C == 0) { + play_sound(NA_SE_IT_FISHING_REEL_HIGH - SFX_FLAG); + } + } + + spD8 = sLurePos.x - sRodTipPos.x; + spD4 = sLurePos.y - sRodTipPos.y; + spD0 = sLurePos.z - sRodTipPos.z; + + if (D_80917202 != 0) { + sLureRot.x = sReelLineRot[LINE_SEG_COUNT - 2].x + M_PI; + sLureRot.y = sReelLineRot[LINE_SEG_COUNT - 2].y; + } else { + sLureRot.x = 0.0f; + sLureRot.y = Math_Acot2F(spD0, spD8) + M_PI; + } + + phi_f16 = sqrtf(SQ(spD8) + SQ(spD4) + SQ(spD0)); + if (phi_f16 > 1000.0f) { + phi_f16 = 1000.0f; + } + D_809101C0 = 200.0f - (phi_f16 * 200.0f * 0.001f); + + spC8 = SQ(sLurePos.x) + SQ(sLurePos.z); + if (spC8 > SQ(920.0f)) { + f32 temp; + + if ((sLurePos.y > 160.0f) || (sLurePos.x < 80.0f) || (sLurePos.x > 180.0f) || (sLurePos.z > 1350.0f) || + (sLurePos.z < 1100.0f) || (sLurePos.y < 45.0f)) { + Vec3f sp80 = this->actor.world.pos; + + this->actor.prevPos = this->actor.world.pos = sLurePos; + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 15.0f, 30.0f, 30.0f, 0x43); + this->actor.world.pos = sp80; + + if (this->actor.bgCheckFlags & 0x10) { + D_80917238.y = -0.5f; + } + if (this->actor.bgCheckFlags & 8) { + if (D_80917238.y > 0.0f) { + D_80917238.y = 0.0f; + } + D_80917238.x = D_80917238.z = 0.0f; + } + } else { + if (func_808FEF70(&sLurePos)) { + D_8090CD14 = 3; + D_809101D0 = 0.0f; + } + } + + temp = ((sqrtf(spC8) - 920.0f) * 0.11f) + WATER_SURFACE_Y(globalCtx); + // spE4 = ((sqrtf(spC8) - 920.0f) * 0.11f) + WATER_SURFACE_Y(globalCtx); + if (sLurePos.y <= temp) { + sLurePos.y = temp; + D_80917238.x = D_80917238.y = D_80917238.z = 0.0f; + D_8090CD14 = 3; + D_809101D0 = 0.0; + } else { + Math_ApproachF(&D_809101C4, 0.0f, 1.0f, 0.05f); + func_8019F1C0(&D_8090D614, + NA_SE_EN_WIZ_UNARI - SFX_FLAG); // changed from NA_SE_EN_FANTOM_FLOAT in OoT + } + } else { + f32 sp7C = WATER_SURFACE_Y(globalCtx); + f32 sp78; + // spE4 = WATER_SURFACE_Y(globalCtx); + + if (sLurePos.y <= sp7C) { + D_8090CD14 = 2; + D_809101D0 = 0.0f; + D_80917238.x = D_80917238.z = 0.0f; + + if (D_80917206 == 2) { + D_809171F2 = 0; + } else { + D_809171F2 = 10; + } + + if ((sLurePos.y <= sp7C) && (sp7C < spE0) && (sp7C == WATER_SURFACE_Y(globalCtx))) { + D_80917264 = 10; + func_8019F1C0(&D_8090D614, NA_SE_EV_BOMB_DROP_WATER); + D_80917248.y = 0.0f; + D_80917238.y *= 0.2f; + + for (i = 0; i < 50; i++) { + sp7C = Rand_ZeroFloat(1.5f) + 0.5f; + sp78 = Rand_ZeroFloat(6.28f); + + sp9C.x = __sinf(sp78) * sp7C; + sp9C.z = __cosf(sp78) * sp7C; + sp9C.y = Rand_ZeroFloat(3.0f) + 3.0f; + + spA8 = sLurePos; + spA8.x += (sp9C.x * 3.0f); + spA8.y = WATER_SURFACE_Y(globalCtx); + spA8.z += (sp9C.z * 3.0f); + EnFishing_SpawnDustSplash(NULL, globalCtx->specialEffects, &spA8, &sp9C, + Rand_ZeroFloat(0.02f) + 0.025f); + } + + spA8 = sLurePos; + spA8.y = WATER_SURFACE_Y(globalCtx); + EnFishing_SpawnRipple(NULL, globalCtx->specialEffects, &spA8, 100.0f, 800.0f, 150, 90); + } + } else { + Math_ApproachZeroF(&D_809101C4, 1.0f, 0.05f); + func_8019F1C0(&D_8090D614, + NA_SE_EN_WIZ_UNARI - SFX_FLAG); // changed from NA_SE_EN_FANTOM_FLOAT in OoT + } + } + + sReelLinePos[LINE_SEG_COUNT - 1].x = sLurePos.x; + sReelLinePos[LINE_SEG_COUNT - 1].y = sLurePos.y; + sReelLinePos[LINE_SEG_COUNT - 1].z = sLurePos.z; + + D_809101BC = 1.0f; + D_8091725C = 0.5f; + break; + + case 2: + if (sLurePos.y <= WATER_SURFACE_Y(globalCtx)) { + sLurePos.y += D_80917238.y; + + Math_ApproachZeroF(&D_80917238.y, 1.0f, 1.0f); + + if (D_80917206 != 2) { + Math_ApproachF(&sLurePos.y, WATER_SURFACE_Y(globalCtx), 0.5f, 1.0f); + } + } + + Math_ApproachF(&D_809101C4, 2.0f, 1.0f, 0.1f); + + if (D_809171F2 == 0) { + D_8090CD14 = 3; + } else { + D_809171F2--; + } + break; + + case 3: { + f32 sp70; + + D_80911F20 = 0; + + if ((D_8090CD0C != 0) && ((SQ(sLurePos.x) + SQ(sLurePos.z)) < SQ(500.0f))) { + D_8090CD10 = 1; + } + + player->unk_B28 = 2; + + if (D_809101B4 < 3.0f) { + spD0 = D_8091725C * Math_SinS(D_809171FE * 0x1060); + Math_ApproachF(&sLureRot.x, -0.5235988f + spD0, 0.3f, D_80917260); + Math_ApproachF(&D_80917260, 0.5f, 1.0f, 0.02f); + Math_ApproachZeroF(&D_8091725C, 1.0f, 0.02f); + } else { + D_80917260 = 0.0f; + } + + spDC = 0x4000; + spE4 = WATER_SURFACE_Y(globalCtx); + + spC8 = SQ(sLurePos.x) + SQ(sLurePos.z); + if (spC8 < SQ(920.0f)) { + if (sLurePos.y <= (spE4 + 4.0f)) { + sp70 = 0.0f; + + if (D_809101CC == 0) { + if (fabsf(input->rel.stick_x) > 30.0f) { + sp70 = fabsf((input->rel.stick_x - D_8090CD44) * (1.0f / 60.0f)); + } else if (fabsf(input->rel.stick_y) > 30.0f) { + sp70 = fabsf((input->rel.stick_y - D_8090CD48) * (1.0f / 60.0f)); + } + } + + if (sp70 > 1.0f) { + sp70 = 1.0f; + } + if (CHECK_BTN_ALL(input->press.button, BTN_B)) { + sp70 = 0.5f; + } + + if (D_8090CD0C != 0) { + if (sp70 > 0.3f) { + sp70 = 0.3f; + } + } + + if ((sp70 > 0.2f) && (D_809101B4 < 4.0f)) { + D_809101CC = 5; + + if (sp70 > 0.8f) { + D_80917270 = 2; + } else { + D_80917270 = 1; + } + + sp90.x = player->actor.world.pos.x - sLurePos.x; + sp90.z = player->actor.world.pos.z - sLurePos.z; + sp90.y = Math_Acot2F(sp90.z, sp90.x); + + D_809101B0 = (sp70 * D_809101BC) + sp90.y; + D_809101BC *= -1.0f; + D_809101B4 = fabsf(sp70) * 6.0f; + sLureRot.x = 0.0f; + D_8091725C = 0.5f; + D_809101C0 += (fabsf(sp70) * 7.5f); + + func_8019FAD8(&D_8090D614, NA_SE_EV_LURE_MOVE_W, (sp70 * 1.999f * 0.25f) + 0.75f); + + if (D_80917206 == 2) { + D_80917278.y = 5.0f * sp70; + sReelLinePos[LINE_SEG_COUNT - 1].y += D_80917278.y; + sLurePos.y += D_80917278.y; + } + } else if (CHECK_BTN_ALL(input->cur.button, BTN_A)) { + s32 pad; + + spDC = 0x500; + D_809101B0 = sReelLineRot[LINE_SEG_COUNT - 2].y + M_PI; + sLureRot.x = 0.0f; + D_8091725C = 0.5f; + if (D_80917206 == 2) { + D_80917278.y = 0.2f; + sReelLinePos[LINE_SEG_COUNT - 1].y += D_80917278.y; + sLurePos.y += D_80917278.y; + } + } + } else { + if (D_809101C0 > 150.0f) { + sLureRot.x = sReelLineRot[LINE_SEG_COUNT - 2].x + M_PI; + D_809101B0 = sReelLineRot[LINE_SEG_COUNT - 2].y + M_PI; + D_809101C0 += 2.0f; + } + } + } else { + spE4 = ((sqrtf(spC8) - 920.0f) * 0.11f) + WATER_SURFACE_Y(globalCtx); + if (sLurePos.y <= spE4) { + sLurePos.y = spE4; + spDC = 0x500; + D_809101B0 = sReelLineRot[LINE_SEG_COUNT - 2].y + M_PI; + sLureRot.x = 0.0f; + if (CHECK_BTN_ALL(input->press.button, BTN_B)) { + D_809101C0 += 6.0f; + func_8019F1C0(&D_8090D614, NA_SE_PL_WALK_SAND); + } + } else { + if (D_809101C0 > 150.0f) { + sLureRot.x = sReelLineRot[LINE_SEG_COUNT - 2].x + M_PI; + D_809101B0 = sReelLineRot[LINE_SEG_COUNT - 2].y + M_PI; + D_809101C0 += 2.0f; + } + } + } + + Math_ApproachZeroF(&D_809101B4, 1.0f, 0.3f); + Math_ApproachS(&D_809101B8, (D_809101B0 * 32768.0f) / M_PI, 3, spDC); + + sLureRot.y = (D_809101B8 / 32768.0f) * M_PI; + + sp90.x = 0.0f; + sp90.y = 0.0f; + sp90.z = D_809101B4; + + Matrix_InsertYRotation_f(sLureRot.y, MTXMODE_NEW); + + if (D_80917206 == 2) { + Vec3f sp64; + + Matrix_MultiplyVector3fByState(&sp90, &sp64); + D_80917278.x = sp64.x; + D_80917278.z = sp64.z; + phi_f0 = 10.0f; + } else { + Matrix_MultiplyVector3fByState(&sp90, &D_80917278); + phi_f0 = 0.0f; + } + + D_80917254 = 0.0f; + + if ((D_80917206 == 1) && CHECK_BTN_ALL(input->cur.button, BTN_A)) { + D_80917278.y = -2.0f; + + if (D_809171FE & 1) { + D_80917254 = 0.5f; + } else { + D_80917254 = -0.5f; + } + } else if (sReelLinePos[LINE_SEG_COUNT - 1].y < (WATER_SURFACE_Y(globalCtx) + phi_f0)) { + if (D_80917206 == 2) { + Vec3f sp58 = this->actor.world.pos; + this->actor.prevPos = this->actor.world.pos = sLurePos; + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 15.0f, 30.0f, 30.0f, 0x44); + this->actor.world.pos = sp58; + + D_80917278.y += -0.5f; + if (D_80917278.y < -1.0f) { + D_80917278.y = -1.0f; + } + + if (sLurePos.y < (this->actor.floorHeight + 5.0f)) { + sReelLinePos[LINE_SEG_COUNT - 1].y = sLurePos.y = this->actor.floorHeight + 5.0f; + D_80917278.y = 0.0f; + } else { + D_80917270 = 1; + } + } else { + D_80917278.y = fabsf(sReelLinePos[LINE_SEG_COUNT - 1].y - WATER_SURFACE_Y(globalCtx)) * 0.2f; + if (D_80917278.y > 1.5f) { + D_80917278.y = 1.5f; + } + } + } + + sReelLinePos[LINE_SEG_COUNT - 1].x += D_80917278.x; + sReelLinePos[LINE_SEG_COUNT - 1].y += D_80917278.y; + sReelLinePos[LINE_SEG_COUNT - 1].z += D_80917278.z; + + if (sReelLinePos[LINE_SEG_COUNT - 1].y > (spE4 + 6.0f)) { + sReelLinePos[LINE_SEG_COUNT - 1].y -= 5.0f; + } + + D_80917238.x = D_80917238.y = D_80917238.z = D_80917248.y = 0.0f; + + if (CHECK_BTN_ALL(input->cur.button, BTN_A)) { + if (CHECK_BTN_ALL(input->cur.button, BTN_R)) { + D_809101C0 += 1.5f; + play_sound(NA_SE_IT_FISHING_REEL_HIGH - SFX_FLAG); + Math_ApproachF(&D_809101D0, 1000.0f, 1.0f, 2.0f); + } else { + D_809101C0 += D_8091726C; + play_sound(NA_SE_IT_FISHING_REEL_SLOW - SFX_FLAG); + Math_ApproachF(&D_809101D0, 1000.0f, 1.0f, 0.2f); + } + + if (sReelLinePos[LINE_SEG_COUNT - 1].y > (WATER_SURFACE_Y(globalCtx) + 4.0f)) { + Math_ApproachF(&D_809101C4, 3.0f, 1.0f, 0.2f); + } else { + Math_ApproachF(&D_809101C4, 1.0f, 1.0f, 0.2f); + } + } else { + Math_ApproachF(&D_809101C4, 2.0f, 1.0f, 0.2f); + } + + Math_ApproachF(&sLurePos.x, sReelLinePos[LINE_SEG_COUNT - 1].x, 1.0f, D_809101D0); + Math_ApproachF(&sLurePos.y, sReelLinePos[LINE_SEG_COUNT - 1].y, 1.0f, D_809101D0); + Math_ApproachF(&sLurePos.z, sReelLinePos[LINE_SEG_COUNT - 1].z, 1.0f, D_809101D0); + + if (D_809101B4 > 1.0f) { + Math_ApproachF(&D_809101D0, 1000.0f, 1.0f, 1.0f); + } + + Math_ApproachF(&D_809101D0, 1000.0f, 1.0f, 0.1f); + + if (D_809101C0 >= 195.0f) { + D_809101C0 = 195.0f; + D_8090CD14 = 0; + D_809101C4 = 520.0f; + D_8090CD4C = 3; + } + + if ((sLurePos.y <= (WATER_SURFACE_Y(globalCtx) + 4.0f)) && + (sLurePos.y >= (WATER_SURFACE_Y(globalCtx) - 4.0f))) { + phi_v0 = 63; + if (CHECK_BTN_ALL(input->cur.button, BTN_A) || (D_809101B4 > 1.0f)) { + phi_v0 = 1; + } + + if ((D_809171FE & phi_v0) == 0) { + spA8 = sLurePos; + spA8.y = WATER_SURFACE_Y(globalCtx); + EnFishing_SpawnRipple(NULL, globalCtx->specialEffects, &spA8, 30.0f, 300.0f, 150, 90); + } + } + break; + } + + case 4: + if (this->unk_14F != 0) { + this->unk_14F--; + D_809101C0 += D_8091726C; + } + + if (CHECK_BTN_ALL(input->cur.button, BTN_A)) { + if ((SQ(sLurePos.x) + SQ(sLurePos.z)) > SQ(920.0f)) { + D_809101C0 += 1.0f; + } else { + D_809101C0 += D_8091726C; + } + play_sound(NA_SE_IT_FISHING_REEL_SLOW - SFX_FLAG); + } + + if ((D_809171FE & 0x1F) == 0) { + if ((D_80917274 != 0) || (D_80917206 != 2)) { + D_8090CD24 = 5; + } + } + + Math_ApproachF(&D_809101C4, 0.0f, 1.0f, 0.2f); + break; + + case 5: + D_809101C8 = 0.0005000001f; + sReelLinePos[LINE_SEG_COUNT - 1].x = sLurePos.x; + sReelLinePos[LINE_SEG_COUNT - 1].y = sLurePos.y; + sReelLinePos[LINE_SEG_COUNT - 1].z = sLurePos.z; + D_809101C4 = 2.0f; + break; + } +} +#else +static Vec3f D_8090D620 = { 0.0f, 0.0f, 0.0f }; +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/EnFishing_UpdateLure.s") #endif -extern ColliderJntSphElementInit D_8090CD58[12]; -extern ColliderJntSphInit D_8090CF08; -extern InitChainEntry D_8090D4D0[]; +s32 func_809033F0(EnFishing* this, GlobalContext* globalCtx, u8 ignorePosCheck) { + s16 i; + s16 count; + f32 scale; + Vec3f pos; + Vec3f vel; + f32 speedXZ; + f32 angle; -extern UNK_TYPE D_0600007C; -extern UNK_TYPE D_06003230; -extern UNK_TYPE D_0600453C; -extern UNK_TYPE D_060074C8; -extern UNK_TYPE D_06008678; -extern UNK_TYPE D_0600B950; -extern UNK_TYPE D_0600C220; -extern UNK_TYPE D_060113D0; -extern UNK_TYPE D_06012160; -extern UNK_TYPE D_060121F0; -extern UNK_TYPE D_06014030; -extern UNK_TYPE D_060153D0; + if ((this->actor.world.pos.y < (WATER_SURFACE_Y(globalCtx) - 10.0f)) && !ignorePosCheck) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FC6C0.s") + // Necessary to match + if (this->unk_1A4) {} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FC770.s") + if (this->unk_1A4 >= 40.0f) { + count = 40; + scale = 1.2f; + } else { + count = 30; + scale = 1.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FC790.s") + for (i = 0; i < count; i++) { + speedXZ = (Rand_ZeroFloat(1.5f) + 0.5f) * scale; + angle = Rand_ZeroFloat(6.28f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FC8B8.s") + vel.x = __sinf(angle) * speedXZ; + vel.z = __cosf(angle) * speedXZ; + vel.y = (Rand_ZeroFloat(3.0f) + 3.0f) * scale; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FC964.s") + pos = this->actor.world.pos; + pos.x += vel.x * 3.0f; + pos.y = WATER_SURFACE_Y(globalCtx); + pos.z += vel.z * 3.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FCABC.s") + EnFishing_SpawnDustSplash(&this->actor.projectedPos, globalCtx->specialEffects, &pos, &vel, + (Rand_ZeroFloat(0.02f) + 0.025f) * scale); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FCC0C.s") + pos = this->actor.world.pos; + pos.y = WATER_SURFACE_Y(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FCDBC.s") + EnFishing_SpawnRipple(&this->actor.projectedPos, globalCtx->specialEffects, &pos, 100.0f, 800.0f, 150, 90); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FCF60.s") + this->unk_149 = 30; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FD054.s") + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/EnFishing_Init.s") +void func_809036BC(EnFishing* this, GlobalContext* globalCtx) { + s16 count; + s16 i; + f32 scale; + Vec3f pos; + Vec3f vel; + f32 speedXZ; + f32 angle; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/EnFishing_Destroy.s") + // Necessary to match + if (this->unk_1A4) {} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FDCDC.s") + if (this->unk_1A4 >= 45.0f) { + count = 30; + scale = 0.5f; + } else { + count = 20; + scale = 0.3f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FE3F8.s") + for (i = 0; i < count; i++) { + speedXZ = (Rand_ZeroFloat(1.5f) + 0.5f) * scale; + angle = Rand_ZeroFloat(6.28f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FEE1C.s") + vel.x = __sinf(angle) * speedXZ; + vel.z = __cosf(angle) * speedXZ; + vel.y = Rand_ZeroFloat(2.0f) + 2.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FEF70.s") + pos = this->actor.world.pos; + pos.x += (vel.x * 3.0f); + pos.y += (vel.y * 3.0f); + pos.z += (vel.z * 3.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FF064.s") + EnFishing_SpawnDustSplash(&this->actor.projectedPos, globalCtx->specialEffects, &pos, &vel, + (Rand_ZeroFloat(0.02f) + 0.025f) * scale); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FF5E0.s") +void func_809038A4(EnFishing* this, Input* input) { + Vec3f sp34; + Vec3f sp28; + f32 sp24; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FF750.s") + sp34.x = sLurePos.x - this->actor.world.pos.x; + sp34.y = sLurePos.y - this->actor.world.pos.y; + sp34.z = sLurePos.z - this->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FFC44.s") + sp24 = SQ(sp34.x) + SQ(sp34.y) + SQ(sp34.z); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_808FFF3C.s") + if ((D_8090CD14 == 3) && (this->unk_19A == 0) && (D_8090CD0C == 0)) { + Matrix_InsertYRotation_f((-this->actor.shape.rot.y / 32768.0f) * M_PI, MTXMODE_NEW); + Matrix_MultiplyVector3fByState(&sp34, &sp28); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80900228.s") + if ((sp28.z > 0.0f) || (this->unk_1A4 < 40.0f)) { + if ((this->unk_150 == 7) && (sp24 < SQ(200.0f))) { + this->unk_150 = 4; + this->unk_1AC = sLurePos; + this->unk_1A8 = 28672.0f; + this->unk_180 = 5.0f; + } else { + if ((CHECK_BTN_ALL(input->cur.button, BTN_A) || (D_809101B4 > 1.0f)) && (sp24 < SQ(120.0f))) { + this->unk_150 = 2; + this->unk_156 = 0; + this->unk_172[0] = 0; + this->unk_172[2] = Rand_ZeroFloat(100.0f) + 100.0f; + this->unk_1A0 = sFishInits[this->actor.params - 100].unk_0C; + this->unk_1A8 = 0.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80900A04.s") + if ((this->unk_172[1] == 0) && (sp24 < SQ(70.0f))) { + this->unk_150 = 2; + this->unk_156 = 0; + this->unk_172[0] = 0; + this->unk_172[2] = Rand_ZeroFloat(100.0f) + 100.0f; + this->unk_1A0 = sFishInits[this->actor.params - 100].unk_0C; + this->unk_1A8 = 0.0f; + } + } + } + } else if ((D_8090CD14 == 4) && (D_80917274 != 0) && (sp24 < SQ(100.0f)) && (this->unk_150 >= 10)) { + this->unk_152 = 0; + this->unk_150 = 1; + this->unk_19C = 1000; + this->unk_19A = 100; + this->unk_172[1] = 50; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80901480.s") + if ((D_80917206 != 2) && (D_80917264 != 0) && (this->unk_1A4 > 60.0f) && (sp24 < SQ(30.0f)) && + (this->unk_150 >= 10)) { + this->unk_152 = 0; + this->unk_150 = 1; + this->unk_19C = 1000; + this->unk_19A = 100; + this->unk_172[1] = 50; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_809033F0.s") +void func_80903C60(EnFishing* this, u8 arg1) { + u16 sfxId; + u8 temp; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_809036BC.s") + if (this->unk_148 == 0) { + temp = this->unk_1A4; + } else { + temp = 2.0f * this->unk_1A4; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_809038A4.s") + if (arg1 == 0) { + if (temp >= 50) { + sfxId = NA_SE_EV_DIVE_INTO_WATER; + } else if (temp >= 40) { + sfxId = NA_SE_EV_BOMB_DROP_WATER; + } else { + sfxId = NA_SE_EV_BOMB_DROP_WATER; + } + } else { + if (temp >= 50) { + sfxId = NA_SE_EV_JUMP_OUT_WATER; + } else if (temp >= 40) { + sfxId = NA_SE_EV_OUT_OF_WATER; + } else { + sfxId = NA_SE_EV_OUT_OF_WATER; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80903C60.s") + Audio_PlayActorSound2(&this->actor, sfxId); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80903E20.s") +void EnFishing_HandleAquariumDialog(EnFishing* this, GlobalContext* globalCtx) { + if (sLinkAge == 1) { + if (gSaveContext.roomInf[127][2] & 0x7F) { + if (gSaveContext.roomInf[127][2] & 0x80) { + this->actor.textId = 0x40B1; + } else { + this->actor.textId = 0x4089; + } + } else { + this->actor.textId = 0x40AE; + } + } else if (gSaveContext.roomInf[127][2] & 0x7F000000) { + if (gSaveContext.roomInf[127][2] & 0x80000000) { + this->actor.textId = 0x40B1; + } else { + this->actor.textId = 0x4089; + } + } else { + this->actor.textId = 0x40AE; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/EnFishing_Update.s") + if (this->unk_1CB == 0) { + if (this->unk_1CC == 0) { + this->actor.flags |= 1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80908554.s") + if (func_800B84D0(&this->actor, globalCtx)) { + D_8090CCF8 = D_809171CC; + this->unk_1CB = 1; + } else { + func_800B863C(&this->actor, globalCtx); + } + } else { + this->unk_1CC--; + this->actor.flags &= ~1; + } + } else if (func_800B867C(&this->actor, globalCtx)) { + this->unk_1CB = 0; + this->unk_1CC = 20; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80908674.s") +#ifdef NON_MATCHING +// D_80917266 in case 5 around the large branching +void EnFishing_UpdateFish(Actor* thisx, GlobalContext* globalCtx2) { + s16 i; + s16 sp134 = 10; + f32 sp130; + f32 sp12C; + f32 sp128; + f32 sp124; + f32 multiplier; + f32 sp11C; + f32 sp118; + Vec3f sp10C; + Vec3f sp100; + s16 spFE; + s16 spFC; + s16 spFA; + s16 phi_v0; + s16 spF6; + s16 spF4; + s16 spF2; + s16 spF0; + s16 spEE; + EnFishing* this = THIS; + GlobalContext* globalCtx = globalCtx2; + Player* player = GET_PLAYER(globalCtx); + Input* input = CONTROLLER1(globalCtx); + f32 spD8; + f32 phi_f0; + f32 phi_f2; + Vec3f spC4; + Vec3f spB8; + u8 phi_v0_2; + f32 temp_f0; + f32 temp; + s32 pad; + f32 spA4; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_809086B4.s") + this->actor.uncullZoneForward = 700.0f; + this->actor.uncullZoneScale = 50.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80908734.s") + if (this->unk_148 == 0) { + sp118 = (player->actor.speedXZ * 0.15f) + 0.25f; + } else { + sp118 = (player->actor.speedXZ * 0.3f) + 0.25f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/EnFishing_Draw.s") + if ((D_80917200 != 0) || (sCameraId != MAIN_CAM) || + ((player->actor.world.pos.z > 1150.0f) && (this->unk_150 != 100))) { + this->actor.flags &= ~1; + } else { + this->actor.flags |= 1; + if (D_8090CD14 != 0) { + if (D_80917202 == 0) { + this->actor.focus.pos = sLurePos; + } else if (D_80917202 == 1) { + D_8090CD4C = 1; + D_80911F50 = 0.0f; + D_809171DC = 2; + } + } + this->actor.focus.pos = this->actor.world.pos; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_809089B8.s") + this->unk_154++; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80908A64.s") + for (i = 0; i < ARRAY_COUNT(this->unk_172); i++) { + if (this->unk_172[i] != 0) { + this->unk_172[i]--; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80908B4C.s") + if (this->unk_19C != 0) { + this->unk_19C--; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80908E08.s") + if (this->unk_19A != 0) { + this->unk_19A--; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80909234.s") + if (this->unk_198 != 0) { + this->unk_198--; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80909AD0.s") + if (this->unk_149 != 0) { + this->unk_149--; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_80909CC0.s") + Math_ApproachF(&this->unk_190, this->unk_188, 1.0f, 0.2f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_8090AB6C.s") + if (this->unk_150 == 6) { + Math_ApproachF(&this->unk_194, this->unk_18C, 0.2f, 200.0f); + } else { + phi_f0 = 1.0f; + phi_f2 = 1.0f; + if (this->actor.world.pos.y > WATER_SURFACE_Y(globalCtx)) { + phi_f0 = 1.5f; + phi_f2 = 3.0f; + } + Math_ApproachF(&this->unk_194, this->unk_18C * phi_f0, 1.0f, 500.0f * phi_f2); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_8090C884.s") + Math_ApproachS(&this->unk_168, 0, 5, 500); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_8090C8BC.s") + if (this->unk_148 == 0) { + Actor_SetScale(&this->actor, this->unk_1A4 * 15.0f * 0.00001f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/func_8090C96C.s") + this->unk_184 += this->unk_190; + + temp = __cosf(this->unk_184); + this->unk_164 = this->unk_166 + (temp * this->unk_194); + + temp = __cosf(this->unk_184 + -1.2f); + this->unk_16E = this->unk_166 + (temp * this->unk_194 * 1.6f); + } else { + Actor_SetScale(&this->actor, this->unk_1A4 * 65.0f * 0.000001f); + + this->actor.scale.x = this->actor.scale.z * 1.1f; + this->actor.scale.y = this->actor.scale.z * 1.1f; + + this->unk_184 += this->unk_190 * 0.8f; + + for (i = 0; i < 3; i++) { + temp = __cosf(this->unk_184 + (i * 2.1f)); + this->unk_1C4[i] = this->unk_166 + (temp * this->unk_194 * 2.0f); + } + + temp = __cosf(this->unk_184 + 0.4f); + this->unk_164 = (this->unk_194 * temp * 2.0f) * 0.6f; + } + + sp130 = this->unk_1AC.x - this->actor.world.pos.x; + sp12C = this->unk_1AC.y - this->actor.world.pos.y; + sp128 = this->unk_1AC.z - this->actor.world.pos.z; + + spFC = Math_FAtan2F(sp128, sp130); + sp124 = sqrtf(SQ(sp130) + SQ(sp128)); + + spFE = Math_FAtan2F(sp124, sp12C); + sp124 = sqrtf(SQ(sp130) + SQ(sp128) + SQ(sp12C)); + + if ((this->unk_198 != 0) && (this->unk_150 != 2) && (this->unk_150 != 3) && (this->unk_150 != 4)) { + if (this->unk_154 & 0x40) { + spFC += 0x4000; + } else { + spFC -= 0x4000; + } + if ((this->unk_154 + 0x20) & 0x40) { + spFE += 0x2000; + } else { + spFE -= 0x2000; + } + } + + switch (this->unk_150) { + case 100: + EnFishing_HandleAquariumDialog(this, globalCtx); + + this->actor.uncullZoneForward = 500.0f; + this->actor.uncullZoneScale = 300.0f; + + Lights_PointNoGlowSetInfo(&this->lightInfo, this->actor.world.pos.x, this->actor.world.pos.y + 20.0f, + this->actor.world.pos.z - 50.0f, 255, 255, 255, 255); + + this->unk_1A4 = D_809171CC; + sp100.y = Math_SinS(globalCtx->gameplayFrames * 300); + sp100.z = Math_SinS(globalCtx->gameplayFrames * 230) * 2.0f; + this->actor.world.pos.x = 130.0f; + this->actor.world.pos.y = 55.0f + sp100.y; + this->actor.world.pos.z = 1300.0f + sp100.z; + this->actor.shape.rot.y = -0x8000; + + if ((this->actor.projectedPos.z < 200.0f) && (this->actor.projectedPos.z > 0.0f)) { + spC4.x = randPlusMinusPoint5Scaled(5.0f) + 130.0f; + spC4.y = 40.0f; + spC4.z = randPlusMinusPoint5Scaled(5.0f) + 1280.0f; + EnFishing_SpawnBubble(NULL, globalCtx->specialEffects, &spC4, Rand_ZeroFloat(0.02f) + 0.03f, 1); + } + + Math_ApproachS(&this->unk_16A, (Math_SinS(this->unk_154 * 0x800) * 2500.0f) + 2500.0f, 2, 0x7D0); + Math_ApproachS(&this->unk_16C, Math_SinS(this->unk_154 * 0xA00) * 1500.0f, 2, 0x7D0); + + this->unk_188 = 0.3f; + this->unk_18C = 333.33334f; + return; + + case 10: + this->unk_1AC = this->actor.home.pos; + + Math_ApproachF(&this->actor.speedXZ, 2.0f, 1.0f, 0.5f); + Math_ApproachF(&this->unk_1A8, 4096.0f, 1.0f, 256.0f); + + if (sp124 < 40.0f) { + this->unk_150 = 11; + this->unk_188 = 0.4f; + this->unk_18C = 500.0f; + } + + func_809038A4(this, input); + + if (this->actor.xzDistToPlayer < (250.0f * sp118)) { + this->unk_152 = this->unk_150 = 0; + this->unk_19C = 1000; + this->unk_19A = 200; + this->unk_172[1] = 50; + } + break; + + case 11: + this->unk_1AC = this->actor.home.pos; + + Math_ApproachF(&this->actor.speedXZ, 0.0f, 1.0f, 0.05f); + Math_ApproachF(&this->unk_1A8, 0.0f, 1.0f, 256.0f); + + if (sp124 >= 40.0f) { + this->unk_150 = 10; + this->unk_188 = 1.0f; + this->unk_18C = 2000.0f; + } + func_809038A4(this, input); + + if (this->actor.xzDistToPlayer < (250.0f * sp118)) { + this->unk_152 = this->unk_150 = 0; + this->unk_19C = 1000; + this->unk_19A = 200; + this->unk_172[1] = 50; + } + + if (!func_80152498(&globalCtx->msgCtx)) { + if ((gSaveContext.time >= 0xC000) && (gSaveContext.time <= 0xC01B)) { + this->unk_150 = 7; + this->unk_172[3] = Rand_ZeroFloat(150.0f) + 200.0f; + } + if ((gSaveContext.time >= 0x3AAA) && (gSaveContext.time <= 0x3AC5)) { + this->unk_150 = 7; + this->unk_172[3] = Rand_ZeroFloat(150.0f) + 200.0f; + } + } + break; + + case 0: + Math_ApproachF(&this->actor.speedXZ, 1.0f, 1.0f, 0.05f); + Math_ApproachF(&this->unk_1A8, 0.0f, 1.0f, 256.0f); + + if (this->unk_172[0] == 0) { + if (this->unk_19C == 0) { + this->unk_150 = this->unk_152 = 10; + } else { + this->unk_150 = 1; + this->unk_172[0] = Rand_ZeroFloat(30.0f) + 10.0f; + this->unk_1AC.x = randPlusMinusPoint5Scaled(300.0f); + this->unk_1AC.y = (WATER_SURFACE_Y(globalCtx) - 50.0f) - Rand_ZeroFloat(50.0f); + this->unk_1AC.z = randPlusMinusPoint5Scaled(300.0f); + this->unk_188 = 1.0f; + this->unk_18C = 2000.0f; + } + } + + if (D_80917206 == 2) { + func_809038A4(this, input); + } else { + this->actor.flags &= ~1; + } + break; + + case 1: + if (this->unk_148 == 1) { + this->unk_150 = -1; + this->unk_19C = 20000; + this->unk_19A = 20000; + this->unk_1AC.x = 0.0f; + this->unk_1AC.y = -140.0f; + this->unk_1AC.z = 0.0f; + } else { + Math_ApproachF(&this->unk_1A8, 4096.0f, 1.0f, 256.0f); + + if ((this->actor.xzDistToPlayer < (250.0f * sp118)) || (this->unk_172[1] != 0)) { + Math_ApproachF(&this->unk_1A8, 8192.0f, 1.0f, 768.0f); + Math_ApproachF(&this->actor.speedXZ, 4.2f, 1.0f, 0.75); + this->unk_188 = 1.2f; + this->unk_18C = 4000.0f; + this->unk_172[0] = 20; + } else { + this->unk_188 = 1.0f; + this->unk_18C = 2000.0f; + Math_ApproachF(&this->actor.speedXZ, 1.5f, 1.0f, 0.1f); + } + + if ((this->unk_172[0] == 0) || (sp124 < 50.0f)) { + this->unk_150 = 0; + this->unk_172[0] = Rand_ZeroFloat(30.0f) + 3.0f; + this->unk_188 = 1.0f; + this->unk_18C = 500.0f; + } + + if (D_80917206 == 2) { + func_809038A4(this, input); + } else { + this->actor.flags &= ~1; + } + } + break; + + case -1: + Math_ApproachS(&this->unk_15E, 0, 0x14, 0x20); + + if ((this->actor.xzDistToPlayer < (250.0f * sp118)) || (this->unk_172[1] != 0)) { + Math_ApproachF(&this->actor.speedXZ, 3.0f, 1.0f, 0.75); + this->unk_188 = 1.0f; + this->unk_172[0] = 20; + this->unk_18C = 4000.0f; + Math_ApproachF(&this->unk_1A8, 4096.0f, 1.0f, 256.0f); + + if ((globalCtx->gameplayFrames % 32) == 0) { + this->unk_1AC.x = randPlusMinusPoint5Scaled(600.0f); + this->unk_1AC.z = randPlusMinusPoint5Scaled(600.0f); + this->unk_1AC.y = -120.0f; + } + } else if (sp124 > 50.0f) { + this->unk_188 = 0.8f; + this->unk_18C = 1500.0f; + Math_ApproachF(&this->actor.speedXZ, 1.0f, 1.0f, 0.1f); + Math_ApproachF(&this->unk_1A8, 2048.0f, 1.0f, 128.0f); + } else { + this->unk_188 = 0.4f; + this->unk_18C = 500.0f; + Math_ApproachZeroF(&this->actor.speedXZ, 1.0f, 0.02f); + Math_ApproachF(&this->unk_1A8, 0.0f, 1.0f, 256.0f); + } + + if (this->unk_19C == 0) { + this->unk_150 = 10; + this->unk_152 = 10; + } else if (((this->unk_19C & 0x7FF) == 0) && (this->unk_19C < 15000)) { + this->unk_150 = -2; + this->actor.world.rot.x = this->actor.shape.rot.x = 0; + this->unk_1AC.y = WATER_SURFACE_Y(globalCtx) + 10.0f; + this->unk_1AC.x = Rand_ZeroFloat(50.0f); + this->unk_1AC.z = Rand_ZeroFloat(50.0f); + } + + this->actor.flags &= ~1; + break; + + case -2: + if ((this->actor.xzDistToPlayer < (250.0f * sp118)) || (this->unk_172[1] != 0)) { + this->unk_150 = -1; + this->unk_1AC.y = -120.0f; + } else { + this->unk_188 = 0.6f; + this->unk_18C = 1000.0f; + + Math_ApproachS(&this->unk_15E, -0x1000, 0x14, 0x100); + + if (this->actor.world.pos.y < (WATER_SURFACE_Y(globalCtx) - 20.0f)) { + Math_ApproachF(&this->actor.speedXZ, 0.5f, 1.0f, 0.1f); + } else { + Math_ApproachZeroF(&this->actor.speedXZ, 1.0f, 0.01f); + + if ((this->actor.speedXZ == 0.0f) || + (this->actor.world.pos.y > (WATER_SURFACE_Y(globalCtx) - 5.0f))) { + this->unk_1AC.x = Rand_ZeroFloat(300.0f); + this->unk_1AC.z = Rand_ZeroFloat(300.0f); + this->unk_1AC.y = this->actor.floorHeight + 10.0f; + this->unk_150 = -25; + this->unk_1A8 = 0.0f; + + spB8 = this->fishMouthPos; + spB8.y = WATER_SURFACE_Y(globalCtx); + EnFishing_SpawnRipple(&this->actor.projectedPos, globalCtx->specialEffects, &spB8, 10.0f, + 300.0f, 150, 90); + EnFishing_SpawnRipple(&this->actor.projectedPos, globalCtx->specialEffects, &spB8, 30.0f, + 400.0f, 150, 90); + + Audio_PlayActorSound2(&this->actor, NA_SE_PL_CATCH_BOOMERANG); + break; + } + } + + Math_ApproachF(&this->unk_1A8, 2048.0f, 1.0f, 128.0f); + this->actor.flags &= ~1; + } + break; + + case -25: + if ((this->actor.xzDistToPlayer < (250.0f * sp118)) || (this->unk_172[1] != 0)) { + this->unk_150 = -1; + this->unk_1AC.y = -120.0f; + } else { + Math_ApproachS(&this->unk_15E, 0x1000, 0x14, 0x6A); + + if (sp124 > 40.0f) { + this->unk_188 = 0.7f; + this->unk_18C = 1200.0f; + Math_ApproachF(&this->actor.speedXZ, 0.5f, 1.0f, 0.01f); + Math_ApproachF(&this->unk_1A8, 2048.0f, 1.0f, 128.0f); + } else { + this->unk_150 = -1; + } + } + break; + + case 2: + if ((this->actor.params + D_80917268) & 1) { + sp10C.x = 10.0f; + } else { + sp10C.x = -10.0f; + } + sp10C.y = 0.0f; + sp10C.z = 0.0f; + Matrix_InsertYRotation_f(sLureRot.y, MTXMODE_NEW); + Matrix_MultiplyVector3fByState(&sp10C, &sp100); + + this->unk_1AC.x = sLurePos.x + sp100.x; + this->unk_1AC.z = sLurePos.z + sp100.z; + + if (D_80917206 == 2) { + this->unk_1AC.y = sLurePos.y; + } else if (this->unk_148 == 0) { + this->unk_1AC.y = sLurePos.y - 15.0f; + } else { + this->unk_1AC.y = sLurePos.y - 5.0f; + } + + if (this->unk_1AC.y <= this->actor.floorHeight) { + this->unk_1AC.y = this->actor.floorHeight + 3.0f; + } + + if ((D_80917206 != 2) && (this->unk_1AC.y < this->actor.world.pos.y)) { + Math_ApproachF(&this->actor.world.pos.y, this->unk_1AC.y, 0.1f, + (this->actor.world.pos.y - this->unk_1AC.y) * 0.1f); + } + + Math_ApproachF(&this->unk_1A8, 8192.0f, 1.0f, 384.0f); + if (CHECK_BTN_ALL(input->press.button, BTN_A)) { + this->unk_1A0 += 0.005f; + } + + if (D_80917270 != 0) { + if (D_80917270 == 1) { + this->unk_1A0 += 0.01f; + } else { + this->unk_1A0 += 0.05f; + } + D_80917270 = 0; + } + + if (CHECK_BTN_ALL(input->press.button, BTN_B)) { + this->unk_1A0 += 0.008f; + } + + if (sp124 < ((this->unk_1A4 * 0.5f) + 20.0f)) { + if (this->unk_156 == 0) { + this->unk_188 = 1.0f; + this->unk_18C = 500.0f; + this->unk_172[0] = Rand_ZeroFloat(10.0f) + 2.0f; + } + Math_ApproachF(&this->actor.speedXZ, -0.2f, 1.0f, 0.1f); + this->unk_156 = 1; + } else { + if (this->unk_156 != 0) { + this->unk_188 = 1.0f; + this->unk_1A8 = 0.0f; + this->unk_18C = 3000.0f; + } + Math_ApproachF(&this->actor.speedXZ, 3.0f, 1.0f, 0.15f); + this->unk_156 = 0; + } + + if (this->unk_1A4 >= 60.0f) { + multiplier = 0.3f; + } else if (this->unk_1A4 >= 45.0f) { + multiplier = 0.6f; + } else { + multiplier = 1.0f; + } + + if ((gSaveContext.time >= 0xB555) && (gSaveContext.time <= 0xCAAA)) { + multiplier *= 1.75f; + } else if ((gSaveContext.time >= 0x3555) && (gSaveContext.time <= 0x4AAA)) { + multiplier *= 1.5f; + } else if (D_809171CA != 0) { + multiplier *= 1.5f; + } else if ((u8)D_8090CCD0 != 0) { + multiplier *= 3.0f; + } + + sp11C = 0.03f * multiplier; + if (D_80917206 == 2) { + sp11C *= 5.0f; + } + + if (((this->unk_172[0] == 1) || (Rand_ZeroOne() < sp11C)) && + (Rand_ZeroOne() < (this->unk_1A0 * multiplier))) { + if (this->unk_148 == 0) { + this->unk_150 = 3; + this->unk_188 = 1.2f; + this->unk_18C = 5000.0f; + this->unk_172[0] = Rand_ZeroFloat(10.0f); + } else { + this->unk_150 = -3; + this->unk_188 = 1.0f; + this->unk_18C = 3000.0f; + this->unk_172[0] = 40; + } + if (D_80917206 == 2) { + this->unk_180 = Rand_ZeroFloat(1.5f) + 3.0f; + } else { + this->unk_180 = Rand_ZeroFloat(1.5f) + 4.5f; + } + } + + if ((D_8090CD14 != 3) || (this->unk_172[2] == 0) || + (sqrtf(SQ(this->actor.world.pos.x) + SQ(this->actor.world.pos.z)) > 800.0f)) { + this->unk_150 = this->unk_152; + this->unk_172[1] = Rand_ZeroFloat(30.0f) + 50.0f; + this->unk_172[0] = Rand_ZeroFloat(10.0f) + 5.0f; + this->unk_188 = 1.0f; + this->unk_1A8 = 0.0f; + this->unk_18C = 2000.0f; + } + + if (this->actor.xzDistToPlayer < (100.0f * sp118)) { + this->unk_152 = this->unk_150 = 0; + this->unk_19C = 1000; + this->unk_19A = 200; + this->unk_172[1] = 50; + } + break; + + case 3: + this->unk_149 = 6; + sp134 = 2; + + if (((s16)player->actor.world.pos.x + D_80917268) & 1) { + sp10C.x = 30.0f; + } else { + sp10C.x = -30.0f; + } + sp10C.y = 0.0f; + sp10C.z = 30.0f; + + Matrix_InsertYRotation_f(sLureRot.y, MTXMODE_NEW); + Matrix_MultiplyVector3fByState(&sp10C, &sp100); + + this->unk_1AC.x = sLurePos.x + sp100.x; + this->unk_1AC.z = sLurePos.z + sp100.z; + this->unk_1AC.y = sLurePos.y - 10.0f; + this->unk_1A8 = 4096.0f; + Math_ApproachF(&this->actor.speedXZ, this->unk_180 * 0.8f, 1.0f, 1.0f); + + if ((D_8090CD14 != 3) || (sLurePos.y > (WATER_SURFACE_Y(globalCtx) + 5.0f)) || + (sqrtf(SQ(sLurePos.x) + SQ(sLurePos.z)) > 800.0f)) { + this->unk_150 = this->unk_152; + this->unk_172[0] = 0; + this->unk_188 = 1.0f; + this->unk_18C = 2000.0f; + } else if ((this->unk_172[0] == 0) || (sp124 < 30.0f)) { + this->unk_150 = 4; + this->unk_1AC = sLurePos; + this->unk_1A8 = 16384.0f; + this->unk_188 = 1.2f; + this->unk_18C = 5000.0f; + this->unk_172[0] = 20; + } + break; + + case 4: + Math_ApproachF(&this->unk_1A8, 16384.0f, 1.0f, 4096.0f); + Math_ApproachS(&this->unk_168, 0x4E20, 4, 0x1388); + + this->unk_149 = 50; + sp134 = 2; + this->unk_1AC = sLurePos; + Math_ApproachF(&this->actor.speedXZ, this->unk_180, 1.0f, 1.0f); + + if ((D_8090CD14 != 3) || (this->unk_172[0] == 0) || (sLurePos.y > (WATER_SURFACE_Y(globalCtx) + 5.0f)) || + (sqrtf(SQ(sLurePos.x) + SQ(sLurePos.z)) > 800.0f)) { + + this->unk_172[0] = 0; + this->unk_150 = this->unk_152; + this->unk_188 = 1.0f; + this->unk_18C = 2000.0f; + } else if (sp124 < 10.0f) { + if (func_809033F0(this, globalCtx, false)) { + func_80903C60(this, 0); + } + + this->unk_150 = 5; + this->unk_188 = 1.2f; + this->unk_18C = 5000.0f; + this->unk_172[1] = 150; + this->unk_172[0] = 0; + this->unk_172[2] = 0; + this->unk_172[3] = 120; + + D_8090CD14 = 4; + sFishingHookedFish = this; + sFishMouthOffset.y = 500.0f - Rand_ZeroFloat(400.0f); + + if (D_80917206 == 2) { + if (this->unk_1A4 > 70.0f) { + phi_v0 = Rand_ZeroFloat(20.0f) + 10.0f; + } else if (this->unk_1A4 > 60.0f) { + phi_v0 = Rand_ZeroFloat(30.0f) + 20.0f; + } else if (this->unk_1A4 > 50.0f) { + phi_v0 = Rand_ZeroFloat(30.0f) + 30.0f; + } else { + phi_v0 = Rand_ZeroFloat(40.0f) + 40.0f; + } + D_80917272 = phi_v0; + D_809171F4 = phi_v0; + func_8013EC44(0.0f, 60, phi_v0 * 3, 10); + } else { + if (this->unk_1A4 > 70.0f) { + phi_v0 = Rand_ZeroFloat(5.0f) + 10.0f; + } else if (this->unk_1A4 > 60.0f) { + phi_v0 = Rand_ZeroFloat(5.0f) + 15.0f; + } else if (this->unk_1A4 > 50.0f) { + phi_v0 = Rand_ZeroFloat(5.0f) + 17.0f; + } else { + phi_v0 = Rand_ZeroFloat(5.0f) + 25.0f; + } + D_80917272 = phi_v0; + D_809171F4 = phi_v0; + func_8013EC44(0.0f, 180, phi_v0 * 3, 10); + } + + D_80917274 = 0; + D_80917266 = 100; + D_809171D4 = 0; + } + break; + + case -3: + this->unk_149 = 50; + this->unk_1AC = sLurePos; + Math_ApproachF(&this->actor.speedXZ, 2.0f, 1.0f, 1.0f); + + if ((D_8090CD14 != 3) || (this->unk_172[0] == 0) || (sLurePos.y > (WATER_SURFACE_Y(globalCtx) + 5.0f)) || + (sqrtf(SQ(sLurePos.x) + SQ(sLurePos.z)) > 800.0f)) { + + this->unk_172[0] = 0; + this->unk_188 = 1.0f; + this->unk_150 = this->unk_152; + this->unk_18C = 2000.0f; + } else if (sp124 < 10.0f) { + if (sLurePos.y > (WATER_SURFACE_Y(globalCtx) - 10.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_JUMP_OUT_WATER); + play_sound(NA_SE_PL_CATCH_BOOMERANG); + } + + func_809033F0(this, globalCtx, false); + this->unk_150 = 5; + this->unk_188 = 1.2f; + this->unk_18C = 5000.0f; + this->unk_172[1] = 150; + this->unk_172[0] = 0; + this->unk_172[2] = 0; + this->unk_172[3] = 120; + + D_8090CD14 = 4; + sFishingHookedFish = this; + + if (D_80917206 == 2) { + D_80917272 = 30; + D_809171F4 = 100; + func_8013EC44(0.0f, 60, 90, 10); + } else { + D_80917272 = 30; + D_809171F4 = 40; + func_8013EC44(0.0f, 180, 90, 10); + } + + D_80917274 = 0; + D_80917266 = 100; + D_809171D4 = 0; + } + break; + + case 5: + this->actor.uncullZoneForward = 1200.0f; + this->actor.uncullZoneScale = 200.0f; + + D_809171D4++; + + Math_ApproachS(&this->unk_168, 0x2AF8, 4, 0xBB8); + sFishingHookedFish = this; + Math_ApproachS(&player->actor.shape.rot.y, this->actor.yawTowardsPlayer + 0x8000, 5, 0x500); + + if (D_80917274 == 0) { + if ((D_80911F20 < 20) && ((D_809171FE & 3) == 0)) { + D_80911F20++; + } + } + + if ((D_80917272 != 0) && (D_80917274 == 0)) { + if (((input->rel.stick_y < -50) && (D_8090CD48 > -40)) || CHECK_BTN_ALL(input->press.button, BTN_A)) { + if (input->rel.stick_y < -50) { + temp_f0 = 40.0f - ((this->unk_1A4 - 30.0f) * 1.333333f); + if (temp_f0 > 0.0f) { + this->unk_14A = temp_f0; + this->unk_14C = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + this->unk_14E = 1; + } + } + + this->unk_190 = 1.7f; + this->unk_194 = 7000.0f; + D_80917274 = 1; + Audio_QueueSeqCmd(0x881A); // Changed from 0x81A in OoT + D_809171F6 = 0; + + if (this->unk_148 == 1) { + spA4 = (this->unk_1A4 * 3.0f) + 120.0f; + } else { + spA4 = (2.0f * this->unk_1A4) + 120.0f; + } + if (spA4 > 255.0f) { + spA4 = 255.0f; + } + + func_8013EC44(0.0f, spA4, 120, 5); + D_809171F4 = 40; + D_80911E28 = 10; + play_sound(NA_SE_IT_FISHING_HIT); + } + } + + if (this->actor.world.pos.y < WATER_SURFACE_Y(globalCtx)) { + if (this->unk_172[1] > 30) { + phi_v0_2 = 7; + } else { + phi_v0_2 = 0xF; + } + + if (((this->unk_154 & phi_v0_2) == 0) && (Rand_ZeroOne() < 0.75f) && (D_809171F4 == 0)) { + if (this->unk_1A4 >= 70.0f) { + spA4 = 255.0f; + } else if (this->unk_1A4 >= 60.0f) { + spA4 = 230.0f; + } else if (this->unk_1A4 >= 50.0f) { + spA4 = 200.0f; + } else if (this->unk_1A4 >= 40.0f) { + spA4 = 170.0f; + } else { + spA4 = 140.0f; + } + + if (phi_v0_2 == 0xF) { + spA4 *= 3.0f / 4.0f; + } + + func_8013EC44(0.0f, spA4, Rand_ZeroFloat(5.0f) + 10.0f, 5); + } + + if (this->unk_172[1] > 30) { + if (this->unk_172[0] == 0) { + u16 spA2; + + sp10C.x = 0.0f; + sp10C.y = 0.0f; + sp10C.z = 200.0f; + + for (spA2 = 0; spA2 < 100; spA2++) { + + Matrix_InsertYRotation_f(randPlusMinusPoint5Scaled(2.3561945f) + + (((this->actor.yawTowardsPlayer + 0x8000) / 32768.0f) * M_PI), + MTXMODE_NEW); + Matrix_MultiplyVector3fByState(&sp10C, &sp100); + + this->unk_1AC.x = this->actor.world.pos.x + sp100.x; + this->unk_1AC.z = this->actor.world.pos.z + sp100.z; + + if ((SQ(this->unk_1AC.x) + SQ(this->unk_1AC.z)) < SQ(750.0f)) { + break; + } + } + + if ((Rand_ZeroOne() < 0.1f) && (this->unk_172[3] == 0)) { + u8 phi_a1; + + if (this->unk_1A4 >= 60.0f) { + phi_a1 = 255; + } else if (this->unk_1A4 >= 50.0f) { + phi_a1 = 200; + } else { + phi_a1 = 180; + } + func_8013EC44(0.0f, phi_a1, 90, 2); + this->unk_172[0] = 20; + this->unk_172[1] = 100; + this->unk_172[2] = 20; + this->unk_172[3] = 100; + this->unk_1AC.y = 300.0f; + D_809171F4 = 0x28; + D_80917266 = Rand_ZeroFloat(30.0f) + 20.0f; + } else { + this->unk_172[0] = Rand_ZeroFloat(10.0f) + 3.0f; + this->unk_172[2] = 0; + this->unk_1AC.y = -70.0f - Rand_ZeroFloat(150.0f); + } + } + + if (this->unk_172[2] != 0) { + D_8091726C = 0.0f; + this->unk_188 = 1.6f; + this->unk_18C = 6000.0f; + Math_ApproachF(&this->actor.speedXZ, 7.5f, 1.0f, 1.0f); + Math_ApproachS(&this->unk_168, 0x4E20, 2, 0xFA0); + } else { + if ((D_80917274 == 0) && (D_80917206 == 2)) { + this->unk_188 = 1.0f; + this->unk_18C = 2000.0f; + Math_ApproachF(&this->actor.speedXZ, 3.0f, 1.0f, 0.2f); + } else { + this->unk_188 = 1.4f; + this->unk_18C = 5000.0f; + Math_ApproachF(&this->actor.speedXZ, 5.0f, 1.0f, 0.5f); + } + + if (this->unk_148 == 0) { + D_8091726C = 1.0f - (this->unk_1A4 * 0.00899f); + } else { + D_8091726C = 1.0f - (this->unk_1A4 * 0.00899f * 1.4f); + } + } + } else { + if (((this->unk_172[1] & 0xF) == 0) && CHECK_BTN_ALL(input->cur.button, BTN_A) && + (!(this->unk_1A4 >= 60.0f) || (D_809171D4 >= 2000))) { + this->unk_14A = Rand_ZeroFloat(30.0f) + 15.0f; + this->unk_14C = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; + } + + this->unk_188 = 1.0f; + this->unk_18C = 4500.0f; + + if (this->unk_148 == 0) { + D_8091726C = 1.3f - (this->unk_1A4 * 0.00899f); + } else { + D_8091726C = 1.3f - (this->unk_1A4 * 0.00899f * 1.4f); + } + + Math_ApproachF(&this->actor.speedXZ, 2.0f, 1.0f, 0.5f); + + if (this->unk_172[1] == 0) { + this->unk_14A = 0; + + if (D_809171D4 < 2000) { + this->unk_172[1] = Rand_ZeroFloat(50.0f) + 50.0f; + } else if (D_809171D4 < 3000) { + this->unk_172[1] = Rand_ZeroFloat(20.0f) + 30.0f; + } else { + this->unk_172[1] = Rand_ZeroFloat(10.0f) + 25.0f; + } + } + } + } + + if (D_809171C8 != 0) { + D_8091726C = 0.0f; + } + + if (D_80917274 || (D_80917206 != 2)) { + if (this->actor.speedXZ < 3.0f) { + if (D_809171FE & 8) { + sp100.x = -0.8f; + } else { + sp100.x = -0.75f; + } + } else if (D_809171FE & 4) { + sp100.x = -0.9f; + } else { + sp100.x = -0.85f; + } + + Math_ApproachF(&D_8090CD40, 35.0f, 0.1f, 3.5f); + Math_ApproachF(&D_8090CD3C, sp100.x, 0.3f, 0.1f); + } + + sReelLinePos[LINE_SEG_COUNT - 1] = this->fishMouthPos; + sp10C.x = sReelLinePos[LINE_SEG_COUNT - 1].x - sReelLinePos[LINE_SEG_COUNT - 2].x; + sp10C.y = sReelLinePos[LINE_SEG_COUNT - 1].y - sReelLinePos[LINE_SEG_COUNT - 2].y; + sp10C.z = sReelLinePos[LINE_SEG_COUNT - 1].z - sReelLinePos[LINE_SEG_COUNT - 2].z; + + if ((SQ(sp10C.x) + SQ(sp10C.y) + SQ(sp10C.z)) > SQ(20.0f)) { + Math_ApproachF(&this->actor.world.pos.x, sReelLinePos[LINE_SEG_COUNT - 2].x, 0.2f, + 2.0f * (this->actor.speedXZ * 1.5f)); + Math_ApproachF(&this->actor.world.pos.y, sReelLinePos[LINE_SEG_COUNT - 2].y, 0.2f, + 2.0f * (this->actor.speedXZ * 1.5f) * 5.0f * 0.1f); + Math_ApproachF(&this->actor.world.pos.z, sReelLinePos[LINE_SEG_COUNT - 2].z, 0.2f, + 2.0f * (this->actor.speedXZ * 1.5f)); + } + + if (CHECK_BTN_ALL(input->cur.button, BTN_A) || (input->rel.stick_y < -30)) { + if (D_80917266 < 100) { + D_80917266++; + } + } else { + if (D_80917266 != 0) { + D_80917266--; + } + } + + if ((D_8090CD14 < 3) || ((D_809171C8 != 0) && (D_809171D4 > 50)) || (D_809171D4 >= 6000) || + ((D_80917272 == 0) && (D_80917274 == 0)) || (D_80917266 == 0) || + (((D_809171FE & 0x7F) == 0) && (Rand_ZeroOne() < 0.05f) && (D_80917206 != 2))) { + // Assignment of OoT's D_80B7A67C here removed in MM + + if ((D_80917272 == 0) && (D_80917274 == 0)) { + // Assignment of OoT's D_80B7E086 here removed in MM + if (((sLinkAge == 1) && (gSaveContext.roomInf[127][2] & 0x400)) || + ((sLinkAge != 1) && (gSaveContext.roomInf[127][2] & 0x800))) { + // Assignment of OoT's D_80B7A67C here removed in MM, this is now an empty branch + } + } else { + // Assignment of OoT's D_80B7E086 here removed in MM + func_8013EC44(0.0f, 1, 3, 1); + Audio_QueueSeqCmd(0x100A00FF); + } + + this->unk_150 = this->unk_152 = 0; + this->unk_19C = 10000; + this->unk_19A = 500; + this->unk_172[1] = 50; + this->unk_172[0] = 0; + this->unk_188 = 1.0f; + this->unk_18C = 3000.0f; + + if (D_8090CD14 == 4) { + D_8090CD14 = 3; + } + + D_809171F6 = 50; + D_8091726C = 0.5f; + this->unk_14A = 0; + } else if (this->actor.xzDistToPlayer < 50.0f) { + this->unk_150 = 6; + this->unk_172[0] = 100; + player->unk_B28 = 3; + func_8013EC44(0.0f, 1, 3, 1); + D_809171D8++; + func_800EA0D4(globalCtx, &globalCtx->csCtx); + D_8090CD4C = 100; + D_80911F48 = 45.0f; + D_8090CD14 = 5; + this->unk_188 = 1.0f; + this->unk_18C = 500.0f; + this->unk_194 = 5000.0f; + + if (this->actor.world.pos.y <= WATER_SURFACE_Y(globalCtx)) { + func_80903C60(this, 1); + func_809033F0(this, globalCtx, true); + } + goto case_6; + } + break; + + case_6: + case 6: + Math_ApproachS(&this->unk_168, 0x2AF8, 2, 0xFA0); + Math_ApproachF(&D_80911F48, 15.0f, 0.05f, 0.75f); + + sp10C.x = D_80911F48; + if (sLinkAge != 1) { + sp10C.y = 30.0f; + sp10C.z = 55.0f; + } else { + sp10C.y = 10.0f; + sp10C.z = 50.0f; + } + Matrix_InsertYRotation_f((player->actor.shape.rot.y / 32768.0f) * M_PI, MTXMODE_NEW); + Matrix_MultiplyVector3fByState(&sp10C, &sCameraEye); + + sCameraEye.x += player->actor.world.pos.x; + sCameraEye.y += player->actor.world.pos.y; + sCameraEye.z += player->actor.world.pos.z; + + sCameraAt = player->actor.world.pos; + if (sLinkAge != 1) { + sCameraAt.y += 40.0f; + } else { + sCameraAt.y += 25.0f; + } + + if (this->unk_172[0] == 90) { + Audio_QueueSeqCmd(0x8924); // changed from 0x924 in OoT + D_8090CCFC = 40; + + if (this->unk_148 == 0) { + D_8090CCF8 = this->unk_1A4; + + if (D_8090CCF8 >= 75) { + D_809171DA = 0x409F; + } else if (D_8090CCF8 >= 50) { + D_809171DA = 0x4091; + } else { + D_809171DA = 0x4083; + } + } else { + D_8090CCF8 = 2.0f * this->unk_1A4; + D_809171DA = 0x4099; + } + + this->unk_1CD = 0; + } + + this->unk_158 = -0x4000; + this->actor.shape.rot.y = player->actor.shape.rot.y + 0x5000; + this->actor.shape.rot.x = this->actor.shape.rot.z = this->unk_15A = this->unk_15C = this->unk_166 = 0; + + sp10C.x = 4.0f; + sp10C.y = -10.0f; + sp10C.z = 5.0f; + Matrix_MultiplyVector3fByState(&sp10C, &sp100); + Math_ApproachF(&this->actor.world.pos.x, player->bodyPartsPos[15].x + sp100.x, 1.0f, 6.0f); + Math_ApproachF(&this->actor.world.pos.y, player->bodyPartsPos[15].y + sp100.y, 1.0f, 6.0f); + Math_ApproachF(&this->actor.world.pos.z, player->bodyPartsPos[15].z + sp100.z, 1.0f, 6.0f); + + D_809101C0 = 188.0f; + + if (this->unk_172[0] <= 50) { + switch (this->unk_1CD) { + case 0: + if ((func_80152498(&globalCtx->msgCtx) == 4) || !func_80152498(&globalCtx->msgCtx)) { + if (func_80147624(globalCtx)) { + func_801477B4(globalCtx); + if (globalCtx->msgCtx.choiceIndex == 0) { + if (D_8090CCF0 == 0.0f) { + D_8090CCF0 = this->unk_1A4; + D_809171D0 = this->unk_148; + D_809171D2 = D_80917206; + Actor_MarkForDeath(&this->actor); + } else if ((this->unk_148 == 0) && (D_809171D0 == 0) && + ((s16)this->unk_1A4 < (s16)D_8090CCF0)) { + this->unk_1CD = 1; + this->unk_172[0] = 0x3C; + func_801518B0(globalCtx, 0x4098, NULL); + } else { + f32 temp1 = D_8090CCF0; + s16 temp2 = D_809171D0; + D_8090CCF0 = this->unk_1A4; + D_809171D0 = this->unk_148; + D_809171D2 = D_80917206; + this->unk_1A4 = temp1; + this->unk_148 = temp2; + } + } + if (this->unk_1CD == 0) { + D_8090CD14 = 0; + } + } + } + break; + case 1: + if ((func_80152498(&globalCtx->msgCtx) == 4) || !func_80152498(&globalCtx->msgCtx)) { + if (func_80147624(globalCtx)) { + func_801477B4(globalCtx); + if (globalCtx->msgCtx.choiceIndex != 0) { + f32 temp1 = D_8090CCF0; + s16 temp2 = D_809171D0; + D_8090CCF0 = this->unk_1A4; + D_809171D2 = D_80917206; + this->unk_1A4 = temp1; + this->unk_148 = temp2; + } + D_8090CD14 = 0; + } + } + break; + } + } + + if (D_8090CD14 == 0) { + if (this->actor.update != NULL) { + this->unk_150 = this->unk_152 = 0; + this->unk_19C = 10000; + this->unk_19A = 500; + this->unk_172[1] = 50; + this->unk_172[0] = 0; + this->unk_188 = 1.0f; + this->unk_18C = 2000.0f; + SkelAnime_Free(&this->skelAnime, globalCtx); + + if (this->unk_148 == 0) { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gFishingFishSkel, &gFishingFishAnim, 0, 0, 0); + Animation_MorphToLoop(&this->skelAnime, &gFishingFishAnim, 0.0f); + } else { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gFishingLoachSkel, &gFishingLoachAnim, 0, 0, + 0); + Animation_MorphToLoop(&this->skelAnime, &gFishingLoachAnim, 0.0f); + } + } + + D_809101C4 = 520.0f; + D_809101C0 = 195.0f; + Audio_QueueSeqCmd(0x100A00FF); + D_809171F6 = 20; + D_8090CD4C = 3; + } + break; + + case 7: + this->unk_149 = 50; + sp134 = 5; + this->unk_1A8 = 12288.0f; + + if (this->actor.params < 104) { + this->unk_1AC = sGroupFishes[this->actor.params - 100].pos; + D_8090CF18 = 1; + } else if (this->actor.params < 108) { + this->unk_1AC = sGroupFishes[this->actor.params - 100 + 16].pos; + D_8090CF18 = 2; + } else { + this->unk_1AC = sGroupFishes[this->actor.params - 100 + 32].pos; + D_8090CF18 = 3; + } + + Math_ApproachF(&this->actor.speedXZ, 5.0f, 1.0f, 1.0f); + + if (sp124 < 20.0f) { + Math_ApproachS(&this->unk_168, 0x4E20, 2, 0xFA0); + + if ((this->unk_172[2] == 0) && func_809033F0(this, globalCtx, false)) { + func_80903C60(this, Rand_ZeroFloat(1.99f)); + this->unk_172[2] = Rand_ZeroFloat(20.0f) + 20.0f; + } + } + + if (this->unk_172[3] == 0) { + this->unk_150 = 10; + this->unk_152 = 10; + } else { + func_809038A4(this, input); + if (this->actor.xzDistToPlayer < (100.0f * sp118)) { + this->unk_152 = this->unk_150 = 0; + this->unk_19C = 500; + this->unk_19A = 200; + this->unk_172[1] = 50; + } + } + break; + } + + Math_ApproachS(&this->unk_16A, (Math_SinS(this->unk_154 * 0x1000) * 5000.0f) + 5000.0f, 2, 0x7D0); + + if (this->unk_150 != 6) { + if (this->actor.world.pos.y > WATER_SURFACE_Y(globalCtx)) { + this->unk_188 = 1.5f; + this->unk_18C = 5000.0f; + + Math_ApproachS(&this->unk_166, 0, 5, 0x7D0); + + spF4 = spF0 = spFA = 3; + spF2 = spEE = 0x2000; + + this->unk_172[2] = 0; + this->unk_17C -= 1.0f; + } else { + Math_ApproachZeroF(&this->unk_17C, 1.0f, 2.0f); + if ((this->unk_150 != -1) && (this->unk_150 != -2) && (this->unk_150 != -25)) { + this->unk_15E = 0; + } + + this->unk_160 = this->unk_162 = 0; + spF4 = spF0 = spFA = 4; + spF2 = spEE = 0x2000; + + spF6 = EnFishing_SmoothStepToS(&this->actor.world.rot.y, spFC, sp134, this->unk_1A8) * 3.0f; + Math_ApproachS(&this->actor.world.rot.x, spFE, sp134, this->unk_1A8 * 0.5f); + + if (spF6 > 0x1F40) { + spF6 = 0x1F40; + } else if (spF6 < -0x1F40) { + spF6 = -0x1F40; + } + + if (this->actor.speedXZ >= 3.2f) { + Math_ApproachS(&this->unk_166, spF6, 2, 0x4E20); + } else { + Math_ApproachS(&this->unk_166, spF6, 3, 0xBB8); + } + + Actor_SetVelocityXYRotation(&this->actor); + } + + Actor_ApplyMovement(&this->actor); + + this->actor.world.pos.y += (this->unk_17C * 1.5f); + + if (1) {} + + if (this->unk_14A != 0) { + this->unk_160 = this->unk_14C; + this->unk_14A--; + if (this->unk_14E != 0) { + spF0 = 5; + spEE = 0x4000; + } else { + spF0 = 10; + spEE = 0x800; + } + this->unk_15E = -0x500 - this->actor.shape.rot.x; + spF4 = 5; + spF2 = 0x4000; + } else { + this->unk_14E = 0; + } + + Math_ApproachS(&this->unk_158, this->unk_15E, spF4, spF2); + Math_ApproachS(&this->unk_15A, this->unk_160, spF0, spEE); + Math_ApproachS(&this->unk_15C, this->unk_162, spFA, 0x2000); + + if (this->actor.speedXZ <= 0.5f) { + Math_ApproachS(&this->actor.shape.rot.x, 0, 10, this->unk_170); + Math_ApproachS(&this->unk_170, 0x500, 1, 0x20); + } else { + Math_ApproachS(&this->actor.shape.rot.x, -this->actor.world.rot.x, 10, 0x1000); + this->unk_170 = 0; + } + + this->actor.shape.rot.y = this->actor.world.rot.y; + + if ((this->unk_150 != -1) && (this->unk_150 != -2) && (this->unk_150 != -25)) { + if ((this->actor.world.pos.y > WATER_SURFACE_Y(globalCtx)) && + (this->actor.prevPos.y <= WATER_SURFACE_Y(globalCtx))) { + func_809033F0(this, globalCtx, true); + func_80903C60(this, 1); + this->unk_17C = this->actor.velocity.y; + this->actor.velocity.y = 0.0f; + this->unk_162 = randPlusMinusPoint5Scaled(32768.0f); + } else if ((this->actor.world.pos.y < WATER_SURFACE_Y(globalCtx)) && + (this->actor.prevPos.y >= WATER_SURFACE_Y(globalCtx))) { + if (this->unk_17C < -5.0f) { + this->unk_17C = -5.0f; + } + this->actor.world.rot.x = -0xFA0; + func_809033F0(this, globalCtx, true); + this->unk_1CA = 20; + func_80903C60(this, 0); + } + } + + if ((this->actor.world.pos.y < WATER_SURFACE_Y(globalCtx)) && + (this->actor.world.pos.y > (WATER_SURFACE_Y(globalCtx) - 10.0f)) && !(this->unk_154 & 1) && + (this->actor.speedXZ > 0.0f)) { + Vec3f pos = this->actor.world.pos; + + pos.y = WATER_SURFACE_Y(globalCtx); + EnFishing_SpawnRipple(&this->actor.projectedPos, globalCtx->specialEffects, &pos, 80.0f, 500.0f, 150, 90); + } + + if ((this->actor.speedXZ > 0.0f) || (this->unk_150 == 5)) { + f32 velocityY = this->actor.velocity.y; + + spD8 = this->unk_1A4 * 0.1f; + + this->actor.world.pos.y -= spD8; + this->actor.prevPos.y -= spD8; + this->actor.velocity.y = -1.0f; + if (KREG(90) == 0) { // Check added in MM + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 30.0f, 100.0f, 0x45); + } + this->actor.world.pos.y += spD8; + this->actor.prevPos.y += spD8; + + this->actor.velocity.y = velocityY; + + if (this->actor.bgCheckFlags & 8) { + this->unk_198 = 20; + } + + if (this->actor.bgCheckFlags & 1) { + if (this->actor.world.pos.y > WATER_SURFACE_Y(globalCtx)) { + this->unk_17C = Rand_ZeroFloat(3.0f) + 3.0f; + this->actor.velocity.x = this->actor.world.pos.x * -0.003f; + this->actor.velocity.z = this->actor.world.pos.z * -0.003f; + + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FISH_LEAP); + func_809036BC(this, globalCtx); + + if (Rand_ZeroOne() < 0.5f) { + this->unk_162 = 0x4000; + } else { + this->unk_162 = -0x4000; + } + + if (Rand_ZeroOne() < 0.5f) { + this->unk_15E = 0; + } else { + this->unk_15E = (s16)randPlusMinusPoint5Scaled(32.0f) + 0x8000; + } + + this->unk_160 = (s16)randPlusMinusPoint5Scaled(16384.0f); + this->unk_188 = 1.0f; + this->unk_18C = 5000.0f; + this->unk_194 = 5000.0f; + } else { + this->unk_17C = 0.0f; + + if ((this->unk_150 == 5) && !(this->unk_154 & 1)) { + Vec3f pos; + + pos.x = randPlusMinusPoint5Scaled(10.0f) + this->actor.world.pos.x; + pos.z = randPlusMinusPoint5Scaled(10.0f) + this->actor.world.pos.z; + pos.y = this->actor.floorHeight + 5.0f; + EnFishing_SpawnWaterDust(&this->actor.projectedPos, globalCtx->specialEffects, &pos, + (this->unk_1A4 * 0.005f) + 0.15f); + } + } + } + } + } + + if (this->unk_1CA != 0) { + s16 i; + Vec3f pos; + f32 range = (this->unk_1A4 * 0.075f) + 10.0f; + + this->unk_1CA--; + + for (i = 0; i < 2; i++) { + pos.x = randPlusMinusPoint5Scaled(range) + this->actor.world.pos.x; + pos.y = randPlusMinusPoint5Scaled(range) + this->actor.world.pos.y; + pos.z = randPlusMinusPoint5Scaled(range) + this->actor.world.pos.z; + EnFishing_SpawnBubble(&this->actor.projectedPos, globalCtx->specialEffects, &pos, + Rand_ZeroFloat(0.035f) + 0.04f, 0); + } + } +} +#else +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/EnFishing_UpdateFish.s") +#endif + +s32 EnFishing_FishOverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnFishing* this = THIS; + + if (limbIndex == 13) { + rot->z -= this->unk_168 - 11000; + } else if ((limbIndex == 2) || (limbIndex == 3)) { + rot->y += this->unk_164; + } else if (limbIndex == 4) { + rot->y += this->unk_16E; + } else if (limbIndex == 0xE) { + rot->y -= this->unk_16A; + } else if (limbIndex == 0xF) { + rot->y += this->unk_16A; + } else if (limbIndex == 8) { + rot->y += this->unk_16C; + } else if (limbIndex == 9) { + rot->y -= this->unk_16C; + } + + return false; +} + +void EnFishing_FishPostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnFishing* this = THIS; + + if (limbIndex == 13) { + Matrix_MultiplyVector3fByState(&sFishMouthOffset, &this->fishMouthPos); + } +} + +s32 EnFishing_LoachOverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnFishing* this = THIS; + + if (limbIndex == 3) { + rot->y += this->unk_1C4[0]; + } else if (limbIndex == 4) { + rot->y += this->unk_1C4[1]; + } else if (limbIndex == 5) { + rot->y += this->unk_1C4[2]; + } + + return 0; +} + +void EnFishing_LoachPostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Vec3f sLoachMouthOffset = { 500.0f, 500.0f, 0.0f }; + EnFishing* this = THIS; + + if (limbIndex == 11) { + Matrix_MultiplyVector3fByState(&sLoachMouthOffset, &this->fishMouthPos); + } +} + +void EnFishing_DrawFish(Actor* thisx, GlobalContext* globalCtx) { + EnFishing* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + + Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_InsertYRotation_f(((this->unk_15A + this->actor.shape.rot.y) / 32768.0f) * M_PI, MTXMODE_APPLY); + Matrix_RotateStateAroundXAxis(((this->unk_158 + this->actor.shape.rot.x) / 32768.0f) * M_PI); + Matrix_InsertZRotation_f(((this->unk_15C + this->actor.shape.rot.z) / 32768.0f) * M_PI, MTXMODE_APPLY); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + + if (this->unk_148 == 0) { + Matrix_InsertYRotation_f((this->unk_164 * (M_PI / 32768)) - (M_PI / 2), MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, 0.0f, this->unk_164 * 10.0f * 0.01f, MTXMODE_APPLY); + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnFishing_FishOverrideLimbDraw, EnFishing_FishPostLimbDraw, + &this->actor); + } else { + Matrix_InsertTranslation(0.0f, 0.0f, 3000.0f, MTXMODE_APPLY); + Matrix_InsertYRotation_f(this->unk_164 * (M_PI / 32768), MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, 0.0f, -3000.0f, MTXMODE_APPLY); + Matrix_InsertYRotation_f(-(M_PI / 2), MTXMODE_APPLY); + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnFishing_LoachOverrideLimbDraw, EnFishing_LoachPostLimbDraw, + &this->actor); + } +} + +void EnFishing_HandleReedContact(FishingProp* prop, Vec3f* entityPos) { + f32 dx = prop->pos.x - entityPos->x; + f32 dz = prop->pos.z - entityPos->z; + f32 distXZ = sqrtf(SQ(dx) + SQ(dz)); + + if (distXZ <= 20.0f) { + prop->rotY = Math_Acot2F(dz, dx); + + Math_ApproachF(&prop->rotX, (20.0f - distXZ) * 0.03f, 0.2f, 0.2f); + } +} + +void EnFishing_HandleLilyPadContact(FishingProp* prop, Vec3f* entityPos, u8 fishTimer) { + f32 dx = prop->pos.x - entityPos->x; + f32 dz = prop->pos.z - entityPos->z; + f32 distXZ = sqrtf(SQ(dx) + SQ(dz)); + + if (distXZ <= 40.0f) { + Math_ApproachS(&prop->lilyPadAngle, Math_FAtan2F(dz, dx), 10, 0x300); + } + + if (fishTimer && (distXZ <= 60.0f)) { + f32 heightTarget = 1.0f; + + if (fishTimer >= 21) { + heightTarget = 1.5f; + } + + Math_ApproachF(&prop->lilyPadOffset, heightTarget, 0.1f, 0.2f); + } +} + +void EnFishing_UpdatePondProps(GlobalContext* globalCtx) { + FishingProp* prop = &sPondProps[0]; + Player* player = GET_PLAYER(globalCtx); + Actor* actor; + s16 i; + + for (i = 0; i < POND_PROP_COUNT; i++) { + if (prop->type != FS_PROP_NONE) { + prop->shouldDraw = false; + prop->timer++; + + SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, &prop->pos, &prop->projectedPos, &sProjectedW); + + if ((prop->projectedPos.z < prop->drawDistance) && + (fabsf(prop->projectedPos.x) < (100.0f + prop->projectedPos.z))) { + prop->shouldDraw = true; + } + + if ((prop->projectedPos.z < 500.0f) && (fabsf(prop->projectedPos.x) < (100.0f + prop->projectedPos.z))) { + if (prop->type == FS_PROP_REED) { + EnFishing_HandleReedContact(prop, &player->actor.world.pos); + + actor = globalCtx->actorCtx.actorList[ACTORCAT_NPC].first; + while (actor != NULL) { + if (!((actor->id == ACTOR_EN_FISHING) && (actor->params >= 100))) { + actor = actor->next; + } else { + EnFishing_HandleReedContact(prop, &actor->world.pos); + actor = actor->next; + } + } + + Math_ApproachZeroF(&prop->rotX, 0.05f, 0.05f); + } else if (prop->type == FS_PROP_LILY_PAD) { + EnFishing_HandleLilyPadContact(prop, &player->actor.world.pos, 0); + + actor = globalCtx->actorCtx.actorList[ACTORCAT_NPC].first; + while (actor != NULL) { + if (!((actor->id == ACTOR_EN_FISHING) && (actor->params >= 100))) { + actor = actor->next; + } else { + EnFishing_HandleLilyPadContact(prop, &actor->world.pos, ((EnFishing*)actor)->unk_149); + actor = actor->next; + } + } + + Math_ApproachS(&prop->lilyPadAngle, 0, 20, 80); + prop->pos.y = + (Math_SinS(prop->timer * 0x1000) * prop->lilyPadOffset) + (WATER_SURFACE_Y(globalCtx) + 2.0f); + Math_ApproachZeroF(&prop->lilyPadOffset, 0.1f, 0.02f); + } + } + } + + prop++; + } + + if (sCameraId == MAIN_CAM) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &sFishingMain->collider.base); + } +} + +void EnFishing_DrawPondProps(GlobalContext* globalCtx) { + u8 flag = 0; + FishingProp* prop = &sPondProps[0]; + s16 i; + s32 pad; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_StatePush(); + + for (i = 0; i < POND_PROP_COUNT; i++) { + if (prop->type == FS_PROP_REED) { + if (flag == 0) { + gSPDisplayList(POLY_XLU_DISP++, gFishingReedSetupDL); + flag++; + } + + if (prop->shouldDraw) { + Matrix_InsertTranslation(prop->pos.x, prop->pos.y, prop->pos.z, MTXMODE_NEW); + Matrix_Scale(prop->scale, prop->scale, prop->scale, MTXMODE_APPLY); + Matrix_InsertYRotation_f(prop->rotY, MTXMODE_APPLY); + Matrix_RotateStateAroundXAxis(prop->rotX); + Matrix_InsertYRotation_f(prop->reedAngle, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gFishingReedVtxDL); + } + } + + prop++; + } + + prop = &sPondProps[0]; + flag = 0; + for (i = 0; i < POND_PROP_COUNT; i++) { + if (prop->type == FS_PROP_WOOD_POST) { + if (flag == 0) { + gSPDisplayList(POLY_OPA_DISP++, gFishingWoodPostSetupDL); + flag++; + } + + if (prop->shouldDraw) { + Matrix_InsertTranslation(prop->pos.x, prop->pos.y, prop->pos.z, MTXMODE_NEW); + Matrix_Scale(prop->scale, prop->scale, prop->scale, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gFishingWoodPostVtxDL); + } + } + + prop++; + } + + prop = &sPondProps[0]; + flag = 0; + for (i = 0; i < POND_PROP_COUNT; i++) { + if (prop->type == FS_PROP_LILY_PAD) { + if (flag == 0) { + gSPDisplayList(POLY_XLU_DISP++, gFishingLilyPadSetupDL); + flag++; + } + + if (prop->shouldDraw) { + Matrix_InsertTranslation(prop->pos.x, prop->pos.y, prop->pos.z, MTXMODE_NEW); + Matrix_Scale(prop->scale, 1.0f, prop->scale, MTXMODE_APPLY); + Matrix_InsertYRotation_f(prop->lilyPadAngle * (M_PI / 32768), MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, 0.0f, 20.0f, MTXMODE_APPLY); + Matrix_InsertYRotation_f(prop->rotY, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gFishingLilyPadVtxDL); + } + } + + prop++; + } + + prop = &sPondProps[0]; + flag = 0; + for (i = 0; i < POND_PROP_COUNT; i++) { + if (prop->type == FS_PROP_ROCK) { + if (flag == 0) { + gSPDisplayList(POLY_OPA_DISP++, gFishingRockSetupDL); + flag++; + } + + if (prop->shouldDraw) { + Matrix_InsertTranslation(prop->pos.x, prop->pos.y, prop->pos.z, MTXMODE_NEW); + Matrix_Scale(prop->scale, prop->scale, prop->scale, MTXMODE_APPLY); + Matrix_InsertYRotation_f(prop->rotY, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gFishingRockVtxDL); + } + } + + prop++; + } + + Matrix_StatePop(); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnFishing_UpdateGroupFishes(GlobalContext* globalCtx) { + s16 groupContactFlags = 0; + Player* player = GET_PLAYER(globalCtx); + FishingGroupFish* fish = &sGroupFishes[0]; + f32 dy; + f32 dx; + f32 dist; + f32 dz; + f32 offset; + s16 groupIndex; + s16 groupFlag; + f32 spD8; + s16 spD6; + s16 spD4; + s16 target; + s16 i; + Vec3f basePos[3]; + Vec3f ripplePos; + Vec3f* refPos; + f32 temp1; + f32 temp2; + + if ((D_80917264 != 0) || (D_8090CD14 == 4)) { + refPos = &sLurePos; + } else { + refPos = &player->actor.world.pos; + } + + basePos[0].x = __sinf(sFishGroupAngle1) * 720.0f; + basePos[0].y = -35.0f; + basePos[0].z = __cosf(sFishGroupAngle1) * 720.0f; + + temp1 = refPos->x - basePos[0].x; + temp2 = refPos->z - basePos[0].z; + + if ((SQ(temp1) + SQ(temp2)) < SQ(50.0f)) { + sFishGroupAngle1 += 0.3f; + groupContactFlags |= 1; + } else if (D_8090CF18 != 0) { + sFishGroupAngle1 += 0.05f; + basePos[0].y = WATER_SURFACE_Y(globalCtx) - 5.0f; + } else { + Math_ApproachF(&sFishGroupAngle1, 0.7f, 1.0f, 0.001f); + } + + basePos[1].x = __sinf(sFishGroupAngle2) * 720.0f; + basePos[1].y = -35.0f; + basePos[1].z = __cosf(sFishGroupAngle2) * 720.0f; + + temp1 = refPos->x - basePos[1].x; + temp2 = refPos->z - basePos[1].z; + + if ((SQ(temp1) + SQ(temp2)) < SQ(50.0f)) { + sFishGroupAngle2 -= 0.3f; + groupContactFlags |= 2; + } else if (D_8090CF18 != 0) { + sFishGroupAngle2 -= 0.05f; + basePos[1].y = WATER_SURFACE_Y(globalCtx) - 5.0f; + } else { + Math_ApproachF(&sFishGroupAngle2, 2.3f, 1.0f, 0.001f); + } + + basePos[2].x = __sinf(sFishGroupAngle3) * 720.0f; + basePos[2].y = -35.0f; + basePos[2].z = __cosf(sFishGroupAngle3) * 720.0f; + + temp1 = refPos->x - basePos[2].x; + temp2 = refPos->z - basePos[2].z; + + if ((SQ(temp1) + SQ(temp2)) < SQ(50.0f)) { + sFishGroupAngle3 -= 0.3f; + groupContactFlags |= 4; + } else if (D_8090CF18 != 0) { + sFishGroupAngle3 -= 0.05f; + basePos[2].y = WATER_SURFACE_Y(globalCtx) - 5.0f; + } else { + Math_ApproachF(&sFishGroupAngle3, 4.6f, 1.0f, 0.001f); + } + + if (sLinkAge == 1) { + spD8 = 0.8f; + } else { + spD8 = 1.0f; + } + + for (i = 0; i < GROUP_FISH_COUNT; i++) { + if (fish->type != FS_GROUP_FISH_NONE) { + fish->timer++; + + SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, &fish->pos, &fish->projectedPos, &sProjectedW); + + if ((fish->projectedPos.z < 400.0f) && (fabsf(fish->projectedPos.x) < (100.0f + fish->projectedPos.z))) { + fish->shouldDraw = true; + } else { + fish->shouldDraw = false; + } + + if (i <= 20) { + groupIndex = 0; + groupFlag = 1; + } else if (i <= 40) { + groupIndex = 1; + groupFlag = 2; + } else { + groupIndex = 2; + groupFlag = 4; + } + + dx = fish->unk_10.x - fish->pos.x; + dy = fish->unk_10.y - fish->pos.y; + dz = fish->unk_10.z - fish->pos.z; + spD4 = Math_FAtan2F(dz, dx); + dist = sqrtf(SQ(dx) + SQ(dz)); + spD6 = Math_FAtan2F(dist, dy); + + if ((dist < 10.0f) || (((fish->timer % 32) == 0) && (Rand_ZeroOne() > 0.5f))) { + fish->unk_10.y = basePos[groupIndex].y + randPlusMinusPoint5Scaled(10.0f); + + if (D_8090CF18 != 0) { + fish->unk_10.x = basePos[groupIndex].x + randPlusMinusPoint5Scaled(200.0f); + fish->unk_10.z = basePos[groupIndex].z + randPlusMinusPoint5Scaled(200.0f); + } else { + fish->unk_10.x = basePos[groupIndex].x + randPlusMinusPoint5Scaled(100.0f); + fish->unk_10.z = basePos[groupIndex].z + randPlusMinusPoint5Scaled(100.0f); + } + + ripplePos = fish->pos; + ripplePos.y = WATER_SURFACE_Y(globalCtx); + EnFishing_SpawnRipple(&fish->projectedPos, globalCtx->specialEffects, &ripplePos, 20.0f, + Rand_ZeroFloat(50.0f) + 100.0f, 150, 90); + + if (fish->unk_28 < 1.5f) { + fish->unk_28 = 1.5f; + } + + fish->unk_34 = 1.5f; + fish->unk_38 = 1.0f; + } + + target = EnFishing_SmoothStepToS(&fish->unk_3E, spD4, 5, 0x4000) * 3.0f; + if (target > 0x1F40) { + target = 0x1F40; + } else if (target < -0x1F40) { + target = -0x1F40; + } + + Math_ApproachS(&fish->unk_42, target, 3, 0x1388); + + offset = fish->unk_42 * -0.0001f; + Math_ApproachS(&fish->unk_3C, spD6, 5, 0x4000); + + if (groupContactFlags & groupFlag) { + fish->unk_38 = 1.0f; + fish->unk_28 = 6.0f; + fish->unk_34 = 2.0f; + } + + if (D_8090CF18 != 0) { + fish->unk_38 = 1.0f; + fish->unk_28 = 4.0f; + fish->unk_34 = 2.0f; + } + + Math_ApproachF(&fish->unk_28, 0.75f, 1.0f, 0.05f); + + temp1 = fish->unk_28 * spD8; + temp2 = Math_CosS(fish->unk_3C) * temp1; + + fish->pos.x += temp2 * Math_SinS(fish->unk_3E); + fish->pos.y += temp1 * Math_SinS(fish->unk_3C); + fish->pos.z += temp2 * Math_CosS(fish->unk_3E); + + if (fish->shouldDraw) { + Math_ApproachF(&fish->unk_34, 1.0f, 1.0f, 0.1f); + Math_ApproachF(&fish->unk_38, 0.4f, 1.0f, 0.04f); + fish->unk_30 += fish->unk_34; + fish->unk_2C = (__cosf(fish->unk_30) * fish->unk_38) + offset; + } + } + + fish++; + } + + D_8090CF18 = 0; +} + +void EnFishing_DrawGroupFishes(GlobalContext* globalCtx) { + u8 flag = 0; + FishingGroupFish* fish = &sGroupFishes[0]; + f32 scale; + s16 i; + s32 pad; + + if (sLinkAge == 1) { + scale = 0.003325f; + } else { + scale = 0.00475f; + } + + OPEN_DISPS(globalCtx->state.gfxCtx); + + for (i = 0; i < GROUP_FISH_COUNT; i++) { + if (fish->type != FS_GROUP_FISH_NONE) { + if (flag == 0) { + gSPDisplayList(POLY_OPA_DISP++, gFishingGroupFishSetupDL); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 155, 155, 155, 255); + flag++; + } + + if (fish->shouldDraw) { + Matrix_InsertTranslation(fish->pos.x, fish->pos.y, fish->pos.z, MTXMODE_NEW); + Matrix_InsertYRotation_f(((f32)fish->unk_3E * M_PI) / 32768.0f, MTXMODE_APPLY); + Matrix_RotateStateAroundXAxis((-(f32)fish->unk_3C * M_PI) / 32768.0f); + Matrix_Scale(fish->unk_2C * scale, scale, scale, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gFishingGroupFishVtxDL); + } + } + fish++; + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +static u16 D_8090D638[] = { 0x4096, 0x408D, 0x408E, 0x408F, 0x4094, 0x4095 }; + +void EnFishing_HandleOwnerDialog(EnFishing* this, GlobalContext* globalCtx) { + switch (this->unk_154) { + case 0: + if (D_809171FC == 0) { + if (sLinkAge != 1) { + if ((gSaveContext.roomInf[127][2] & 0x100) && !(gSaveContext.roomInf[127][2] & 0x200)) { + this->actor.textId = 0x4093; + } else { + this->actor.textId = 0x407B; + } + } else { + this->actor.textId = 0x407B; + } + } else if (D_8090CD0C == 0) { + this->actor.textId = 0x4084; + } else { + this->actor.textId = 0x4097; + } + + if (func_800B84D0(&this->actor, globalCtx)) { + if (D_809171FC == 0) { + this->unk_154 = 1; + if (sLinkAge != 1) { + gSaveContext.roomInf[127][2] |= 0x200; + } else { + gSaveContext.roomInf[127][2] |= 0x100; + } + } else { + this->unk_154 = 10; + } + } else { + func_800B8614(&this->actor, globalCtx, 100.0f); + } + break; + + case 1: + if ((func_80152498(&globalCtx->msgCtx) == 4) && func_80147624(globalCtx)) { + func_801477B4(globalCtx); + + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + if (gSaveContext.rupees >= 20) { + func_801159EC(-20); + if (func_8013EE04() == 0) { + this->actor.textId = 0x407C; + } else { + this->actor.textId = 0x407D; + } + func_80151938(globalCtx, this->actor.textId); + this->unk_154 = 2; + } else { + func_80151938(globalCtx, 0x407E); + this->unk_154 = 3; + } + break; + case 1: + func_80151938(globalCtx, 0x2D); + this->unk_154 = 3; + break; + } + } + break; + + case 2: + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + func_801477B4(globalCtx); + func_80151938(globalCtx, 0x407F); + this->unk_154 = 4; + } + break; + + case 3: + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + func_801477B4(globalCtx); + this->unk_154 = 0; + } + if (func_80152498(&globalCtx->msgCtx) == 6) { + this->unk_154 = 0; + } + break; + + case 4: + if ((func_80152498(&globalCtx->msgCtx) == 4) && func_80147624(globalCtx)) { + func_801477B4(globalCtx); + + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + D_8090CCF8 = D_809171CC; + func_80151938(globalCtx, 0x4080); + this->unk_154 = 5; + break; + case 1: + func_80151938(globalCtx, 0x407F); + break; + } + } + break; + + case 5: + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + func_801477B4(globalCtx); + + globalCtx->interfaceCtx.unk_27E = 1; + globalCtx->startPlayerFishing(globalCtx); + D_809171FC = 1; + D_8090CD04 = 20; + this->unk_154 = 0; + + if ((gSaveContext.roomInf[127][2] & 0xFF0000) < 0xFF0000) { + gSaveContext.roomInf[127][2] += 0x10000; + } + } + break; + + case 10: + if (D_8090CD0C != 0) { + if ((func_80152498(&globalCtx->msgCtx) == 4) && func_80147624(globalCtx)) { + func_801477B4(globalCtx); + + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_80151938(globalCtx, 0x40B2); + D_8090CD08 = 1; + D_8090CD0C = 0; + this->unk_154 = 20; + break; + case 1: + this->unk_154 = 0; + break; + } + } + } else { + if ((func_80152498(&globalCtx->msgCtx) == 4) && func_80147624(globalCtx)) { + func_801477B4(globalCtx); + + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + if (D_8090CCF0 == 0.0f) { + this->actor.textId = 0x408C; + this->unk_154 = 20; + } else if (D_809171D0 == 0) { + D_8090CCF8 = D_8090CCF0; + if ((s16)D_809171CC < (s16)D_8090CCF0) { + if (D_809171D2 == 2) { + this->actor.textId = 0x40B0; + } else { + this->actor.textId = 0x4086; + } + this->unk_154 = 11; + } else { + this->actor.textId = 0x408B; + this->unk_154 = 20; + } + } else { + this->actor.textId = 0x409B; + this->unk_154 = 11; + } + func_80151938(globalCtx, this->actor.textId); + break; + case 1: + if (D_8090CD00 > 36000) { + D_8090CD00 = 30000; + func_80151938(globalCtx, 0x4088); + } else { + if (D_809171CA == 0) { + if (D_809171D6 == 0) { + D_809171D6++; + } + } + + if ((D_80917206 == 2) && (D_8090D638[D_809171D6] == 0x408D)) { + func_80151938(globalCtx, 0x40AF); + } else { + func_80151938(globalCtx, D_8090D638[D_809171D6]); + } + + D_809171D6++; + + if (sLinkAge != 1) { + if (D_809171D6 >= 6) { + D_809171D6 = 0; + } + } else { + if (D_809171D6 >= 4) { + D_809171D6 = 0; + } + } + } + this->unk_154 = 0; + break; + case 2: + if (D_809171D8 == 0) { + func_80151938(globalCtx, 0x4085); + } else if (sLinkAge == 1) { + func_80151938(globalCtx, 0x4092); + } + this->unk_154 = 22; + break; + } + } + } + break; + + case 11: + if (((func_80152498(&globalCtx->msgCtx) == 5) || !func_80152498(&globalCtx->msgCtx)) && + func_80147624(globalCtx)) { + s32 getItemId; + + func_801477B4(globalCtx); + + if (D_809171D0 == 0) { + D_809171CC = D_8090CCF0; + D_8090CCF0 = 0.0f; + + if (sLinkAge == 1) { + f32 temp; + + gSaveContext.roomInf[127][2] &= 0xFFFFFF00; + gSaveContext.roomInf[127][2] |= ((s16)D_809171CC & 0x7F); + + temp = (gSaveContext.roomInf[127][2] & 0x7F000000) >> 0x18; + if (temp < D_809171CC) { + gSaveContext.roomInf[127][2] &= 0xFFFFFF; + gSaveContext.roomInf[127][2] |= ((s16)D_809171CC & 0x7F) << 0x18; + + if (D_809171D2 == 2) { + gSaveContext.roomInf[127][2] |= 0x80000000; + } + } + + if (D_809171D2 == 2) { + gSaveContext.roomInf[127][2] |= 0x80; + this->unk_154 = 0; + break; + } + } else { + gSaveContext.roomInf[127][2] &= 0xFFFFFF; + gSaveContext.roomInf[127][2] |= ((s16)D_809171CC & 0x7F) << 0x18; + + if (D_809171D2 == 2) { + gSaveContext.roomInf[127][2] |= 0x80000000; + this->unk_154 = 0; + break; + } + } + + if (D_809171CC >= 60.0f) { + getItemId = GI_RUPEE_PURPLE; + } else if (D_809171CC >= 50.0f) { + getItemId = GI_RUPEE_10; + } else if (D_809171CC >= 40.0f) { + getItemId = GI_RUPEE_BLUE; + } else { + getItemId = GI_RUPEE_GREEN; + } + + if (sLinkAge == 1) { + if ((D_809171CC >= 50.0f) && !(gSaveContext.roomInf[127][2] & 0x400)) { + gSaveContext.roomInf[127][2] |= 0x400; + getItemId = GI_HEART_PIECE; + sSinkingLureLocation = Rand_ZeroFloat(3.999f) + 1.0f; + } + } else { + if ((D_809171CC >= 60.0f) && !(gSaveContext.roomInf[127][2] & 0x800)) { + gSaveContext.roomInf[127][2] |= 0x800; + getItemId = GI_SCALE_GOLD; + sSinkingLureLocation = Rand_ZeroFloat(3.999f) + 1.0f; + } + } + } else { + getItemId = GI_RUPEE_PURPLE; + D_8090CCF0 = 0.0f; + } + + this->actor.parent = NULL; + func_800B8A1C(&this->actor, globalCtx, getItemId, 2000.0f, 1000.0f); + this->unk_154 = 23; + } + break; + + case 20: + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + func_801477B4(globalCtx); + this->unk_154 = 0; + } + break; + + case 21: + if ((func_80152498(&globalCtx->msgCtx) == 4) && func_80147624(globalCtx)) { + func_801477B4(globalCtx); + + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + this->unk_154 = 0; + break; + case 1: + if (D_809171D8 == 0) { + func_80151938(globalCtx, 0x4085); + } else if (sLinkAge == 1) { + func_80151938(globalCtx, 0x4092); + } + this->unk_154 = 22; + break; + } + } + break; + + case 22: + if (!func_80152498(&globalCtx->msgCtx)) { + this->unk_154 = 0; + if (D_8090CD0C != 0) { + D_8090CD08 = 1; + D_8090CD0C = 0; + } + D_809171FC = 0; + globalCtx->interfaceCtx.unk_27E = 0; + } + break; + + case 23: + D_8090CCF4 = false; + if (Actor_HasParent(&this->actor, globalCtx)) { + this->unk_154 = 24; + } else { + func_800B8A1C(&this->actor, globalCtx, GI_SCALE_GOLD, 2000.0f, 1000.0f); + } + break; + + case 24: + D_8090CCF4 = false; + if ((func_80152498(&globalCtx->msgCtx) == 6) && func_80147624(globalCtx)) { + if (D_809171D0 == 0) { + this->unk_154 = 0; + } else { + func_801518B0(globalCtx, 0x409C, NULL); + this->unk_154 = 20; + } + } + break; + } +} + +static s16 D_8090D644[] = { 0, 1, 2, 2, 1 }; + +static Vec3f sStreamSoundPos = { 670.0f, 0.0f, -600.0f }; + +static Vec3s sSinkingLureLocationPos[] = { + { -364, -30, -269 }, + { 1129, 3, -855 }, + { -480, 0, -1055 }, + { 553, -48, -508 }, +}; + +#ifdef NON_MATCHING +// Register flip around target near the end of the function +void EnFishing_UpdateOwner(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnFishing* this = THIS; + Vec3f sp114; + Vec3f sp108; + Vec3f spFC; + s16 headRotTarget; + s16 playerShadowAlpha; + f32 target; + f32 camAtFraction; + f32 lureDistXZ; + s32 pad; + Player* player = GET_PLAYER(globalCtx); + Input* input = CONTROLLER1(globalCtx); + Camera* camera; + + playerShadowAlpha = player->actor.shape.shadowAlpha; + + if ((SQ(player->actor.world.pos.x) + SQ(player->actor.world.pos.z)) < SQ(920.0f)) { + Math_ApproachS(&playerShadowAlpha, 0, 1, 40); + } else { + Math_ApproachS(&playerShadowAlpha, 200, 1, 40); + } + + player->actor.shape.shadowAlpha = playerShadowAlpha; + + SkelAnime_Update(&this->skelAnime); + + if ((D_8090CD04 != 0) || func_80152498(&globalCtx->msgCtx)) { + this->actor.flags &= ~1; + } else { + this->actor.flags |= 0x21; + } + + if ((this->actor.xzDistToPlayer < 120.0f) || func_80152498(&globalCtx->msgCtx)) { + headRotTarget = this->actor.shape.rot.y - this->actor.yawTowardsPlayer; + } else { + headRotTarget = 0; + } + + if (headRotTarget > 0x2710) { + headRotTarget = 0x2710; + } else if (headRotTarget < -0x2710) { + headRotTarget = -0x2710; + } + + Math_ApproachS(&this->unk_15C, headRotTarget, 3, 0x1388); + + if (((globalCtx->gameplayFrames % 32) == 0) && (Rand_ZeroOne() < 0.3f)) { + this->unk_15A = 4; + } + + this->unk_158 = D_8090D644[this->unk_15A]; + + if (this->unk_15A != 0) { + this->unk_15A--; + } + + if (D_8090CD04 != 0) { + D_8090CD04--; + } + + if ((D_8090CD0C == 0) && (D_80917206 != 2) && (D_8090CD14 > 0) && (D_8090CD08 == 1) && (D_8090CD04 == 0)) { + f32 dx = sOwnerHeadPos.x - sLurePos.x; + f32 dy = sOwnerHeadPos.y - sLurePos.y; + f32 dz = sOwnerHeadPos.z - sLurePos.z; + + if ((sqrtf(SQ(dx) + SQ(dy) + SQ(dz)) < 25.0f)) { + D_8090CD08 = 0; + D_8090CD0C = 1; + func_801518B0(globalCtx, 0x4087, NULL); + } + } + + if (D_8090CD08 == 0) { + gSaveContext.roomInf[127][2] |= 0x1000; + } else if (D_8090CD08 == 1) { + gSaveContext.roomInf[127][2] &= ~0x1000; + } + + if (D_8090CCFC != 0) { + D_8090CCFC--; + if (D_8090CCFC == 0) { + func_801518B0(globalCtx, D_809171DA, NULL); + } + } + + EnFishing_HandleOwnerDialog(this, globalCtx); + + D_809101C8 = 0.0015f; + D_8090CD00++; + + if ((D_809171FC != 0) && D_8090CCF4) { + EnFishing_UpdateLure(this, globalCtx); + } + + EnFishing_UpdateEffects(globalCtx->specialEffects, globalCtx); + EnFishing_UpdatePondProps(globalCtx); + EnFishing_UpdateGroupFishes(globalCtx); + + if ((D_809171FC != 0) && (D_8090CD4C == 0) && (player->actor.world.pos.z > 1360.0f) && + (fabsf(player->actor.world.pos.x) < 25.0f)) { + player->actor.world.pos.z = 1360.0f; + player->actor.speedXZ = 0.0f; + + if (D_8090CD50 == 0) { + D_8090CD4C = 10; + } + } + + if ((sSinkingLureLocation != 0) && + (fabsf(player->actor.world.pos.x - sSinkingLureLocationPos[sSinkingLureLocation - 1].x) < 25.0f) && + (fabsf(player->actor.world.pos.y - sSinkingLureLocationPos[sSinkingLureLocation - 1].y) < 10.0f) && + (fabsf(player->actor.world.pos.z - sSinkingLureLocationPos[sSinkingLureLocation - 1].z) < 25.0f)) { + sSinkingLureLocation = 0; + D_8090CD4C = 20; + func_8013EC44(0.0f, 150, 10, 10); + play_sound(NA_SE_SY_TRE_BOX_APPEAR); + Audio_QueueSeqCmd(0x101400FF); + } + + if (D_8090CD50 != 0) { + D_8090CD50--; + } + + switch (D_8090CD4C) { + case 0: + break; + + case 1: + sCameraId = func_801694DC(globalCtx); + func_80169590(globalCtx, MAIN_CAM, 1); + func_80169590(globalCtx, sCameraId, 7); + camera = Play_GetCamera(globalCtx, MAIN_CAM); + sCameraEye.x = camera->eye.x; + sCameraEye.y = camera->eye.y; + sCameraEye.z = camera->eye.z; + sCameraAt.x = camera->at.x; + sCameraAt.y = camera->at.y; + sCameraAt.z = camera->at.z; + D_8090CD4C = 2; + Interface_ChangeAlpha(12); + D_80911F4C = 0.0f; + // fallthrough + + case 2: + ShrinkWindow_SetLetterboxTarget(0x1B); + + spFC.x = sLurePos.x - player->actor.world.pos.x; + spFC.z = sLurePos.z - player->actor.world.pos.z; + lureDistXZ = sqrtf(SQ(spFC.x) + SQ(spFC.z)); + Matrix_InsertYRotation_f(Math_Acot2F(spFC.z, spFC.x), MTXMODE_NEW); + + sp114.x = 0.0f; + sp114.y = 0.0f; + sp114.z = 100.0f; + Matrix_MultiplyVector3fByState(&sp114, &spFC); + + if (D_8090CD14 == 1) { + camAtFraction = 0.2f; + } else { + camAtFraction = 0.1f; + } + + Math_ApproachF(&sCameraAt.x, sLurePos.x, camAtFraction, fabsf(spFC.x) * D_80911F4C); + Math_ApproachF(&sCameraAt.y, sLurePos.y, camAtFraction, 50.0f * D_80911F4C); + Math_ApproachF(&sCameraAt.z, sLurePos.z, camAtFraction, fabsf(spFC.z) * D_80911F4C); + + sp114.x = 0.0f - D_80911F50; + if (sLinkAge != 1) { + sp114.y = 80.0f; + } else { + sp114.y = 55.0f; + } + sp114.z = -80.0f; + + Matrix_MultiplyVector3fByState(&sp114, &sp108); + sp108.x += player->actor.world.pos.x; + sp108.y += player->actor.world.pos.y; + sp108.z += player->actor.world.pos.z; + + Math_ApproachF(&D_80911F50, 30.0f, 0.1f, 0.4f); + + if (CHECK_BTN_ALL(input->press.button, BTN_Z)) { + if ((D_809171DC >= 0) && (D_80917272 == 0)) { + D_809171DC++; + + if (D_809171DC >= 4) { + D_809171DC = 0; + } + + if ((D_809171DC == 0) || (D_809171DC == 3)) { + play_sound(NA_SE_SY_CAMERA_ZOOM_DOWN); + } else { + play_sound(NA_SE_SY_CAMERA_ZOOM_UP); + } + } + } + + if (D_8090CD14 >= 3) { + if (lureDistXZ < 110.0f) { + D_809171DC = -1; + } else if ((lureDistXZ > 300.0f) && (D_809171DC < 0)) { + D_809171DC = 0; + } + } + + if (D_809171DC > 0) { + f32 dist; + f32 offset; + f32 factor; + + dist = sqrtf(SQ(spFC.x) + SQ(spFC.z)) * 0.001f; + if (dist > 1.0f) { + dist = 1.0f; + } + if (D_809171DC == 2) { + offset = 0.3f; + } else { + offset = 0.1f; + } + factor = 0.4f + offset + (dist * 0.4f); + + sp108.x += (sLurePos.x - sp108.x) * factor; + sp108.y += ((sLurePos.y - sp108.y) * factor) + 20.0f; + sp108.z += (sLurePos.z - sp108.z) * factor; + D_809101C8 = 0.0005000001f; + } + + sp114.x = 0.0f; + sp114.y = 0.0f; + sp114.z = 100.0f; + Matrix_MultiplyVector3fByState(&sp114, &spFC); + + Math_ApproachF(&sCameraEye.x, sp108.x, 0.3f, fabsf(spFC.x) * D_80911F4C); + Math_ApproachF(&sCameraEye.y, sp108.y, 0.3f, 20.0f * D_80911F4C); + Math_ApproachF(&sCameraEye.z, sp108.z, 0.3f, fabsf(spFC.z) * D_80911F4C); + break; + + case 3: { + Camera* camera = Play_GetCamera(globalCtx, MAIN_CAM); + + camera->eye = sCameraEye; + camera->eyeNext = sCameraEye; + camera->at = sCameraAt; + } + func_80169AFC(globalCtx, sCameraId, 0); + func_800EA0EC(globalCtx, &globalCtx->csCtx); + D_8090CD4C = 0; + sCameraId = MAIN_CAM; + func_800F6834(globalCtx, 0); + globalCtx->envCtx.unk_8C.fogNear = 0; + player->unk_B28 = -5; + D_80917200 = 5; + break; + + case 10: + func_800EA0D4(globalCtx, &globalCtx->csCtx); + sCameraId = func_801694DC(globalCtx); + func_80169590(globalCtx, MAIN_CAM, 1); + func_80169590(globalCtx, sCameraId, 7); + func_800B7298(globalCtx, &this->actor, 4); + camera = Play_GetCamera(globalCtx, MAIN_CAM); + sCameraEye.x = camera->eye.x; + sCameraEye.y = camera->eye.y; + sCameraEye.z = camera->eye.z; + sCameraAt.x = camera->at.x; + sCameraAt.y = camera->at.y; + sCameraAt.z = camera->at.z; + func_801518B0(globalCtx, 0x409E, NULL); + D_8090CD4C = 11; + func_8013EC44(0.0f, 150, 10, 10); + // fallthrough + + case 11: + player->actor.world.pos.z = 1360.0f; + player->actor.speedXZ = 0.0f; + + if (!func_80152498(&globalCtx->msgCtx)) { + camera = Play_GetCamera(globalCtx, MAIN_CAM); + + camera->eye = sCameraEye; + camera->eyeNext = sCameraEye; + camera->at = sCameraAt; + func_80169AFC(globalCtx, sCameraId, 0); + func_800EA0EC(globalCtx, &globalCtx->csCtx); + func_800B7298(globalCtx, &this->actor, 6); + D_8090CD4C = 0; + sCameraId = MAIN_CAM; + D_8090CD50 = 30; + func_800F6834(globalCtx, 0); + globalCtx->envCtx.unk_8C.fogNear = 0; + } + break; + + case 20: + func_800EA0D4(globalCtx, &globalCtx->csCtx); + sCameraId = func_801694DC(globalCtx); + func_80169590(globalCtx, MAIN_CAM, 1); + func_80169590(globalCtx, sCameraId, 7); + func_800B7298(globalCtx, &this->actor, 4); + camera = Play_GetCamera(globalCtx, MAIN_CAM); + sCameraEye.x = camera->eye.x; + sCameraEye.y = camera->eye.y; + sCameraEye.z = camera->eye.z; + sCameraAt.x = camera->at.x; + sCameraAt.y = camera->at.y; + sCameraAt.z = camera->at.z; + func_801518B0(globalCtx, 0x409A, NULL); + D_8090CD4C = 21; + D_80911F48 = 45.0f; + D_8090CD50 = 10; + // fallthrough + + case 21: + if ((D_8090CD50 == 0) && func_80147624(globalCtx)) { + D_8090CD4C = 22; + D_8090CD50 = 40; + // func_800B7298 call removed in MM + D_80911F64 = 0.0f; + } + break; + + case 22: + if (D_8090CD50 == 30) { + Audio_QueueSeqCmd(0x8922); // changed from 0x922 to 0x8922 in MM + } + + D_8090CD54 = 1; + + Math_ApproachF(&D_80911F64, 71.0f, 0.5f, 3.0f); + Matrix_InsertYRotation_f(BINANG_TO_RAD(player->actor.shape.rot.y), MTXMODE_NEW); + + sp114.x = Math_SinS(globalCtx->gameplayFrames * 0x1000); + sp114.y = D_80911F64; + sp114.z = -5.0f; + if (sLinkAge == 1) { + sp114.y -= 20.0f; + } + + Matrix_MultiplyVector3fByState(&sp114, &sp108); + + sSinkingLureBasePos.x = player->actor.world.pos.x + sp108.x; + sSinkingLureBasePos.y = player->actor.world.pos.y + sp108.y; + sSinkingLureBasePos.z = player->actor.world.pos.z + sp108.z; + + Math_ApproachF(&D_80911F48, 15.0f, 0.1f, 0.75f); + + sp114.x = D_80911F48 - 15.0f; + + if (sLinkAge != 1) { + sp114.y = 60.0f; + sp114.z = -30.0f; + } else { + sp114.y = 40.0f; + sp114.z = -35.0f; + } + + Matrix_MultiplyVector3fByState(&sp114, &sCameraEye); + sCameraEye.x += player->actor.world.pos.x; + sCameraEye.y += player->actor.world.pos.y; + sCameraEye.z += player->actor.world.pos.z; + + sCameraAt = player->actor.world.pos; + if (sLinkAge != 1) { + sCameraAt.y += 62.0f; + } else { + sCameraAt.y += 40.0f; + } + + if (D_8090CD50 == 0) { + if ((func_80152498(&globalCtx->msgCtx) == 4) || !func_80152498(&globalCtx->msgCtx)) { + if (func_80147624(globalCtx)) { + Camera* camera = Play_GetCamera(globalCtx, MAIN_CAM); + + func_801477B4(globalCtx); + if (globalCtx->msgCtx.choiceIndex == 0) { + D_80917206 = 2; + D_809171D6 = 0; + } + + camera->eye = sCameraEye; + camera->eyeNext = sCameraEye; + camera->at = sCameraAt; + func_80169AFC(globalCtx, sCameraId, 0); + func_800EA0EC(globalCtx, &globalCtx->csCtx); + func_800B7298(globalCtx, &this->actor, 6); // arg2 changed from 7 to 6 in MM + D_8090CD4C = 0; + sCameraId = MAIN_CAM; + player->unk_B28 = -5; + D_80917200 = 5; + D_8090CD54 = 0; + D_809171F6 = 20; + func_800F6834(globalCtx, 0); + globalCtx->envCtx.unk_8C.fogNear = 0; + } + } + } + break; + + case 100: + break; + } + + if (sCameraId != MAIN_CAM) { + Play_CameraSetAtEye(globalCtx, sCameraId, &sCameraAt, &sCameraEye); + Math_ApproachF(&D_80911F4C, 1.0f, 1.0f, 0.02f); + + if (sCameraEye.y <= (WATER_SURFACE_Y(globalCtx) + 1.0f)) { + func_800F6834(globalCtx, 1); + if (D_809171CA != 0) { + globalCtx->envCtx.unk_8C.fogNear = -0xB2; + } else { + globalCtx->envCtx.unk_8C.fogNear = -0x2E; + } + } else { + func_800F6834(globalCtx, 0); + globalCtx->envCtx.unk_8C.fogNear = 0; + } + } + + if ((player->actor.floorHeight < (WATER_SURFACE_Y(globalCtx) - 3.0f)) && + (player->actor.world.pos.y < (player->actor.floorHeight + 3.0f)) && (player->actor.speedXZ > 1.0f) && + ((globalCtx->gameplayFrames % 2) == 0)) { + Vec3f pos; + + pos.x = randPlusMinusPoint5Scaled(20.0f) + player->actor.world.pos.x; + pos.z = randPlusMinusPoint5Scaled(20.0f) + player->actor.world.pos.z; + pos.y = player->actor.floorHeight + 5.0f; + EnFishing_SpawnWaterDust(NULL, globalCtx->specialEffects, &pos, 0.5f); + } + + if ((player->actor.floorHeight < WATER_SURFACE_Y(globalCtx)) && + (player->actor.floorHeight > (WATER_SURFACE_Y(globalCtx) - 10.0f)) && (player->actor.speedXZ >= 4.0f) && + ((globalCtx->gameplayFrames % 4) == 0)) { + s16 i; + + for (i = 0; i < 10; i++) { + Vec3f pos; + Vec3f vel; + f32 speedXZ; + f32 angle; + + speedXZ = Rand_ZeroFloat(1.5f) + 1.5f; + angle = Rand_ZeroFloat(6.28f); + + vel.x = __sinf(angle) * speedXZ; + vel.z = __cosf(angle) * speedXZ; + vel.y = Rand_ZeroFloat(3.0f) + 2.0f; + + pos = player->actor.world.pos; + pos.x += 2.0f * vel.x; + pos.y = WATER_SURFACE_Y(globalCtx); + pos.z += 2.0f * vel.z; + EnFishing_SpawnDustSplash(NULL, globalCtx->specialEffects, &pos, &vel, + Rand_ZeroFloat(0.01f) + 0.020000001f); + } + } + + if (D_809171CB >= 2) { + D_809171CB--; + } + + if ((D_809171CB == 1) && !func_80152498(&globalCtx->msgCtx) && ((D_8090CD00 & 0xFFF) == 0xFFF)) { + D_809171CB = 200; + + if (Rand_ZeroOne() < 0.5f) { + D_8090CCD4 = Rand_ZeroFloat(10.0f) + 5.0f; + globalCtx->envCtx.unk_E1 = 1; + } else { + D_8090CCD4 = 0; + globalCtx->envCtx.unk_E1 = 2; + } + } + + Math_ApproachF(&D_8090CCD0, D_8090CCD4, 1.0f, 0.05f); + + if (D_8090CCD0 > 0.0f) { + target = (D_8090CCD0 * 0.03f) + 0.8f; + if (target > 1.2f) { + target = 1.2f; + } + Math_ApproachF(&D_8090CCE8, target, 1.0f, 0.01f); + } + + target = (10.0f - D_8090CCD0) * 150.1f; + if (target < 0.0f) { + target = 0.0f; + } + Math_ApproachF(&D_8090CCDC.z, target, 1.0f, 5.0f); + + if (D_8090CCDC.z < 1500.0f) { + func_8019FAD8(&D_8090CCDC, NA_SE_EV_RAIN - SFX_FLAG, D_8090CCE8); + } + + if (D_8090CCD4 != 0) { + Math_ApproachF(&D_8090CCD8, -200.0f, 1.0f, 2.0f); + } else { + Math_ApproachZeroF(&D_8090CCD8, 1.0f, 2.0f); + } + + globalCtx->envCtx.unk_8C.diffuseColor1[0] = globalCtx->envCtx.unk_8C.diffuseColor1[1] = + globalCtx->envCtx.unk_8C.diffuseColor1[2] = D_8090CCD8; + + if ((u8)D_8090CCD0 > 0) { + s32 pad; + Camera* camera = Play_GetCamera(globalCtx, MAIN_CAM); + s16 i; + s32 pad1; + Vec3f pos; + Vec3f rot; + Vec3f projectedPos; + s32 pad2; + + rot.x = 1.6707964f; + rot.y = 1.0f; + rot.z = (func_800DFC68(camera) * -(M_PI / 32768)) + rot.y; + + for (i = 0; i < (u8)D_8090CCD0; i++) { + pos.x = randPlusMinusPoint5Scaled(700.0f) + globalCtx->view.eye.x; + pos.y = (Rand_ZeroFloat(100.0f) + 150.0f) - 170.0f; + pos.z = randPlusMinusPoint5Scaled(700.0f) + globalCtx->view.eye.z; + + if (pos.z < 1160.0f) { + SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, &pos, &projectedPos, &sProjectedW); + + if (projectedPos.z < 0.0f) { + i--; + } else { + EnFishing_SpawnRainDrop(globalCtx->specialEffects, &pos, &rot); + } + } + } + } + + SkinMatrix_Vec3fMtxFMultXYZW(&globalCtx->viewProjectionMtxF, &sStreamSoundPos, &sStreamSoundProjectedPos, + &sProjectedW); + + func_8019F1C0(&sStreamSoundProjectedPos, NA_SE_EV_WATER_WALL - SFX_FLAG); + + if (gSaveContext.language == 0) { // Added in MM + gSaveContext.minigameScore = D_8090CCF8; + } else { + gSaveContext.minigameScore = (SQ((f32)D_8090CCF8) * 0.0036f) + 0.5f; + } +} +#else +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fishing/EnFishing_UpdateOwner.s") +#endif + +s32 EnFishing_OwnerOverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnFishing* this = THIS; + + if (limbIndex == 8) { // Head + rot->x -= this->unk_15C; + } + + return false; +} + +void EnFishing_OwnerPostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + if (limbIndex == 8) { // Head + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_MultiplyVector3fByState(&sZeroVec, &sOwnerHeadPos); + + if (D_8090CD08 == 1) { + gSPDisplayList(POLY_OPA_DISP++, gFishingOwnerHatDL); + } else if (D_8090CD08 == 2) { + gSPDisplayList(POLY_OPA_DISP++, gFishingOwnerHairDL); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +static UNK_TYPE sFishingOwnerEyeTexs[] = { + &gFishingOwnerEyeOpenTex, + &gFishingOwnerEyeHalfTex, + &gFishingOwnerEyeClosedTex, +}; + +void EnFishing_DrawOwner(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnFishing* this = THIS; + Input* input = CONTROLLER1(globalCtx); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + + if ((this->actor.projectedPos.z < 1500.0f) && + (fabsf(this->actor.projectedPos.x) < (100.0f + this->actor.projectedPos.z))) { + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(sFishingOwnerEyeTexs[this->unk_158])); + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnFishing_OwnerOverrideLimbDraw, EnFishing_OwnerPostLimbDraw, + &this->actor); + } + + EnFishing_DrawPondProps(globalCtx); + EnFishing_DrawEffects(globalCtx->specialEffects, globalCtx); + EnFishing_DrawGroupFishes(globalCtx); + EnFishing_DrawStreamSplash(globalCtx); + + if (D_809171F6 != 0) { + D_809171F6--; + + if (D_809171F6 == 0) { + if (sLinkAge != 1) { + Audio_QueueSeqCmd(0x8019); // Changed from 0x19 in OoT + } else { + Audio_QueueSeqCmd(0x8027); // Changed from 0x27 in OoT + } + + if (sLinkAge != 1) { + Audio_QueueSeqCmd(0x8019); // Changed from 0x19 in OoT + } else { + Audio_QueueSeqCmd(0x8027); // Changed from 0x27 in OoT + } + } + } + + if ((D_809171FC != 0) && D_8090CCF4) { + EnFishing_DrawRod(globalCtx); + EnFishing_UpdateLinePos(sReelLinePos); + EnFishing_UpdateLine(globalCtx, &sRodTipPos, sReelLinePos, sReelLineRot, sReelLineUnk); + EnFishing_DrawLureAndLine(globalCtx, sReelLinePos, sReelLineRot); + + D_8090CD44 = input->rel.stick_x; + D_8090CD48 = input->rel.stick_y; + } + + D_8090CCF4 = true; + + Matrix_InsertTranslation(130.0f, 40.0f, 1300.0f, MTXMODE_NEW); + Matrix_Scale(0.08f, 0.12f, 0.14f, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + gSPDisplayList(POLY_OPA_DISP++, gFishingAquariumBottomDL); + gSPDisplayList(POLY_XLU_DISP++, gFishingAquariumContainerDL); + + if ((D_809171FC != 0) && (D_80917206 == 2)) { + EnFishing_DrawSinkingLure(globalCtx); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Fishing/z_en_fishing.h b/src/overlays/actors/ovl_En_Fishing/z_en_fishing.h index d954b4cf8..3cd594b38 100644 --- a/src/overlays/actors/ovl_En_Fishing/z_en_fishing.h +++ b/src/overlays/actors/ovl_En_Fishing/z_en_fishing.h @@ -9,7 +9,56 @@ typedef void (*EnFishingActionFunc)(struct EnFishing*, GlobalContext*); typedef struct EnFishing { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x404]; + /* 0x0144 */ UNK_TYPE1 unk_144[0x004]; + /* 0x0148 */ u8 unk_148; + /* 0x0149 */ u8 unk_149; + /* 0x014A */ u8 unk_14A; + /* 0x014C */ s16 unk_14C; + /* 0x014E */ u8 unk_14E; + /* 0x014F */ u8 unk_14F; + /* 0x0150 */ s16 unk_150; + /* 0x0152 */ s16 unk_152; + /* 0x0154 */ s16 unk_154; + /* 0x0156 */ s16 unk_156; + /* 0x0158 */ s16 unk_158; + /* 0x015A */ s16 unk_15A; + /* 0x015C */ s16 unk_15C; + /* 0x015E */ s16 unk_15E; + /* 0x0160 */ s16 unk_160; + /* 0x0162 */ s16 unk_162; + /* 0x0164 */ s16 unk_164; + /* 0x0166 */ s16 unk_166; + /* 0x0168 */ s16 unk_168; + /* 0x016A */ s16 unk_16A; + /* 0x016C */ s16 unk_16C; + /* 0x016E */ s16 unk_16E; + /* 0x0170 */ s16 unk_170; + /* 0x0172 */ s16 unk_172[4]; + /* 0x017C */ f32 unk_17C; + /* 0x0180 */ f32 unk_180; + /* 0x0184 */ f32 unk_184; + /* 0x0188 */ f32 unk_188; + /* 0x018C */ f32 unk_18C; + /* 0x0190 */ f32 unk_190; + /* 0x0194 */ f32 unk_194; + /* 0x0198 */ s16 unk_198; + /* 0x019A */ s16 unk_19A; + /* 0x019C */ s16 unk_19C; + /* 0x01A0 */ f32 unk_1A0; + /* 0x01A4 */ f32 unk_1A4; + /* 0x01A8 */ f32 unk_1A8; + /* 0x01AC */ Vec3f unk_1AC; + /* 0x01B8 */ Vec3f fishMouthPos; + /* 0x01C4 */ s16 unk_1C4[3]; + /* 0x01CA */ u8 unk_1CA; + /* 0x01CB */ u8 unk_1CB; + /* 0x01CC */ u8 unk_1CC; + /* 0x01CD */ u8 unk_1CD; + /* 0x01D0 */ SkelAnime skelAnime; + /* 0x0214 */ LightNode* lightNode; + /* 0x0218 */ LightInfo lightInfo; + /* 0x0228 */ ColliderJntSph collider; + /* 0x0248 */ ColliderJntSphElement colliderElements[12]; } EnFishing; // size = 0x548 extern const ActorInit En_Fishing_InitVars; diff --git a/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c b/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c index a1818b095..f8b88f50a 100644 --- a/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c +++ b/src/overlays/actors/ovl_En_Floormas/z_en_floormas.c @@ -461,10 +461,10 @@ void func_808D14DC(EnFloormas* this, GlobalContext* globalCtx) { sp28.x = Math_SinS(this->actor.shape.rot.y + 0x6000) * 7.0f; sp28.z = Math_CosS(this->actor.shape.rot.y + 0x6000) * 7.0f; - func_800B1210(globalCtx, &sp34, &sp28, &D_801D15B0, 0x1C2, 0x64); + func_800B1210(globalCtx, &sp34, &sp28, &gZeroVec3f, 0x1C2, 0x64); sp28.x = Math_SinS(this->actor.shape.rot.y - 0x6000) * 7.0f; sp28.z = Math_CosS(this->actor.shape.rot.y - 0x6000) * 7.0f; - func_800B1210(globalCtx, &sp34, &sp28, &D_801D15B0, 0x1C2, 0x64); + func_800B1210(globalCtx, &sp34, &sp28, &gZeroVec3f, 0x1C2, 0x64); func_800B9010(&this->actor, NA_SE_EN_FLOORMASTER_SLIDING - SFX_FLAG); } @@ -682,7 +682,7 @@ void func_808D1ED4(EnFloormas* this, GlobalContext* globalCtx) { sp34.x = this->actor.world.pos.x; sp34.y = this->actor.world.pos.y + 15.0f; sp34.z = this->actor.world.pos.z; - func_800B3030(globalCtx, &sp34, &D_801D15B0, &D_801D15B0, 150, -10, 2); + func_800B3030(globalCtx, &sp34, &gZeroVec3f, &gZeroVec3f, 150, -10, 2); Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 11, NA_SE_EN_EXTINCT); this->actionFunc = func_808D1F7C; } diff --git a/src/overlays/actors/ovl_En_Fr/z_en_fr.c b/src/overlays/actors/ovl_En_Fr/z_en_fr.c index fb8749a11..fb5b56451 100644 --- a/src/overlays/actors/ovl_En_Fr/z_en_fr.c +++ b/src/overlays/actors/ovl_En_Fr/z_en_fr.c @@ -14,7 +14,6 @@ void EnFr_Init(Actor* thisx, GlobalContext* globalCtx); void EnFr_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnFr_Update(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit En_Fr_InitVars = { ACTOR_EN_FR, ACTORCAT_ITEMACTION, @@ -27,10 +26,27 @@ const ActorInit En_Fr_InitVars = { (ActorFunc)NULL, }; -#endif +void EnFr_Init(Actor* thisx, GlobalContext* globalCtx) { + EnFr* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fr/EnFr_Init.s") + if (Flags_GetSwitch(globalCtx, ENFR_GET_SWITCHFLAG(&this->actor))) { + Actor_MarkForDeath(&this->actor); + } else { + this->actor.targetMode = ENFR_GET_TARGETMODE(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fr/EnFr_Destroy.s") +void EnFr_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fr/EnFr_Update.s") +void EnFr_Update(Actor* thisx, GlobalContext* globalCtx) { + EnFr* this = THIS; + + if (Flags_GetSwitch(globalCtx, ENFR_GET_SWITCHFLAG(&this->actor))) { + Actor_MarkForDeath(&this->actor); + } else if (this->actor.xyzDistToPlayerSq < SQ(IREG(29))) { + this->actor.flags &= ~0x40000000; + } else { + this->actor.flags |= 0x40000000; + } +} diff --git a/src/overlays/actors/ovl_En_Fr/z_en_fr.h b/src/overlays/actors/ovl_En_Fr/z_en_fr.h index ffc250d39..f0de1936d 100644 --- a/src/overlays/actors/ovl_En_Fr/z_en_fr.h +++ b/src/overlays/actors/ovl_En_Fr/z_en_fr.h @@ -5,6 +5,9 @@ struct EnFr; +#define ENFR_GET_SWITCHFLAG(thisx) ((thisx)->params & 0x7F) +#define ENFR_GET_TARGETMODE(thisx) (((thisx)->params >> 7) & 0xF) + typedef struct EnFr { /* 0x000 */ Actor actor; } EnFr; // size = 0x144 diff --git a/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c b/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c index b25f19222..bf159f7de 100644 --- a/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c +++ b/src/overlays/actors/ovl_En_Fsn/z_en_fsn.c @@ -130,7 +130,7 @@ u16 EnFsn_GetWelcome(GlobalContext* globalCtx) { case PLAYER_MASK_GORON: case PLAYER_MASK_ZORA: return 0x29FD; - case PLAYER_MASK_KAFEI: + case PLAYER_MASK_KAFEIS_MASK: return 0x2364; default: return 0x29FE; diff --git a/src/overlays/actors/ovl_En_Fu/z_en_fu.c b/src/overlays/actors/ovl_En_Fu/z_en_fu.c index 558e1cf99..7dcf097d7 100644 --- a/src/overlays/actors/ovl_En_Fu/z_en_fu.c +++ b/src/overlays/actors/ovl_En_Fu/z_en_fu.c @@ -1463,7 +1463,7 @@ void func_80964950(GlobalContext* globalCtx, EnFuUnkStruct* ptr, s32 len) { flag = true; } Matrix_InsertTranslation(ptr->unk_08.x, ptr->unk_08.y, ptr->unk_08.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(ptr->unk_00, ptr->unk_00, ptr->unk_00, MTXMODE_APPLY); gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(&D_0405E6F0)); diff --git a/src/overlays/actors/ovl_En_Fz/z_en_fz.c b/src/overlays/actors/ovl_En_Fz/z_en_fz.c index e48b3d169..e07abfbe9 100644 --- a/src/overlays/actors/ovl_En_Fz/z_en_fz.c +++ b/src/overlays/actors/ovl_En_Fz/z_en_fz.c @@ -5,6 +5,9 @@ */ #include "z_en_fz.h" +#include "overlays/actors/ovl_En_Wiz/z_en_wiz.h" +#include "objects/object_fz/object_fz.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x00000015 @@ -15,7 +18,37 @@ void EnFz_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnFz_Update(Actor* thisx, GlobalContext* globalCtx); void EnFz_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80932784(EnFz* this, GlobalContext* globalCtx); +void func_80932AE8(EnFz* this); +void func_80932AF4(EnFz* this); +void func_80932BD4(EnFz* this); +void func_809330D4(EnFz* this); +void func_80933104(EnFz* this, GlobalContext* globalCtx); +void func_80933184(EnFz* this); +void func_809331F8(EnFz* this, GlobalContext* globalCtx); +void func_80933248(EnFz* this); +void func_80933274(EnFz* this, GlobalContext* globalCtx); +void func_80933324(EnFz* this); +void func_80933368(EnFz* this, GlobalContext* globalCtx); +void func_809333A4(EnFz* this); +void func_809333D8(EnFz* this, GlobalContext* globalCtx); +void func_80933414(EnFz* this); +void func_80933444(EnFz* this, GlobalContext* globalCtx); +void func_80933480(EnFz* this, GlobalContext* globalCtx); +void func_809334B8(EnFz* this, GlobalContext* globalCtx); +void func_809336C0(EnFz* this, GlobalContext* globalCtx); +void func_80933760(EnFz* this, GlobalContext* globalCtx); +void func_80933790(EnFz* this); +void func_809337D4(EnFz* this, GlobalContext* globalCtx); +void func_8093389C(EnFz* this); +void func_809338E0(EnFz* this, GlobalContext* globalCtx); +void func_80933AF4(EnFz* this); +void func_80933B38(EnFz* this, GlobalContext* globalCtx); +void func_80934018(EnFz* this, Vec3f* a, Vec3f* b, Vec3f* c, f32 arg4); +void func_809340BC(EnFz* this, Vec3f* a, Vec3f* b, Vec3f* c, f32 arg4, f32 arg5, s16 arg6, u8 arg7); +void func_80934178(EnFz* this, GlobalContext* globalCtx); +void func_80934464(EnFz* this, GlobalContext* globalCtx); + const ActorInit En_Fz_InitVars = { ACTOR_EN_FZ, ACTORCAT_ENEMY, @@ -28,29 +61,66 @@ const ActorInit En_Fz_InitVars = { (ActorFunc)EnFz_Draw, }; -// static ColliderCylinderInitType1 sCylinderInit = { -static ColliderCylinderInitType1 D_809346F8 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFEFDD, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, +static s16 D_809346F0[] = { 0, 0x2000, 0x4000, 0 }; + +static ColliderCylinderInitType1 sCylinderInit1 = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFEFDD, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 30, 80, 0, { 0, 0, 0 } }, }; -// static ColliderCylinderInitType1 sCylinderInit = { -static ColliderCylinderInitType1 D_80934724 = { - { COLTYPE_METAL, AT_NONE, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_NONE, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0x00001022, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInitType1 sCylinderInit2 = { + { + COLTYPE_METAL, + AT_NONE, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_NONE, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0x00001022, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 35, 80, 0, { 0, 0, 0 } }, }; -// static ColliderCylinderInitType1 sCylinderInit = { -static ColliderCylinderInitType1 D_80934750 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_NONE, OC1_NONE, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x20000000, 0x02, 0x04 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_NONE, }, +static ColliderCylinderInitType1 sCylinderInit3 = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ENEMY, + AC_NONE, + OC1_NONE, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x20000000, 0x02, 0x04 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_NONE, + }, { 20, 30, -15, { 0, 0, 0 } }, }; -// static DamageTable sDamageTable = { -static DamageTable D_8093477C = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(0, 0xD), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -85,96 +155,870 @@ static DamageTable D_8093477C = { /* Powder Keg */ DMG_ENTRY(1, 0xF), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_8093479C[] = { +static InitChainEntry sInitChain[] = { ICHAIN_S8(hintId, 59, ICHAIN_CONTINUE), ICHAIN_U8(targetMode, 2, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 1400, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 30, ICHAIN_STOP), }; -#endif +void EnFz_Init(Actor* thisx, GlobalContext* globalCtx) { + EnFz* this = THIS; -extern ColliderCylinderInit D_809346F8; -extern ColliderCylinderInit D_80934724; -extern ColliderCylinderInit D_80934750; -extern DamageTable D_8093477C; -extern InitChainEntry D_8093479C[]; + Actor_ProcessInitChain(&this->actor, sInitChain); + this->actor.colChkInfo.damageTable = &sDamageTable; + this->actor.colChkInfo.health = 3; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/EnFz_Init.s") + Collider_InitCylinder(globalCtx, &this->collider1); + Collider_SetCylinderType1(globalCtx, &this->collider1, &this->actor, &sCylinderInit1); + Collider_InitCylinder(globalCtx, &this->collider2); + Collider_SetCylinderType1(globalCtx, &this->collider2, &this->actor, &sCylinderInit2); + Collider_InitCylinder(globalCtx, &this->collider3); + Collider_SetCylinderType1(globalCtx, &this->collider3, &this->actor, &sCylinderInit3); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/EnFz_Destroy.s") + Actor_SetScale(&this->actor, 0.008f); + this->actor.gravity = 0.0f; + this->actor.velocity.y = 0.0f; + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->actor.flags &= ~1; + this->unk_BC8 = 0; + this->unk_BCF = 0; + this->unk_BCC = 1; + this->unk_BCD = 0; + this->unk_BCE = 0; + this->unk_BD7 = 1; + this->unk_BD8 = 0; + this->actor.speedXZ = 0.0f; + this->actor.uncullZoneScale = 400.0f; + this->unk_BAC = this->actor.world.pos.y; + this->unk_BB4 = this->actor.world.pos.y; + this->unk_BA8 = this->actor.world.pos.x; + this->unk_BB0 = this->actor.world.pos.z; + this->actor.velocity.y = this->actor.gravity; + this->unk_BB8 = 135.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80932784.s") + if (ENFZ_GET_8000(&this->actor)) { + this->unk_BC0 = 0; + this->actor.scale.y = 0.0f; + func_80933184(this); + } else { + this->unk_BC0 = 255; + if (this->actor.shape.rot.z == 0) { + this->unk_BC6 = (s32)Rand_ZeroFloat(64.0f) + 192; + } else { + if (this->actor.shape.rot.z < 0) { + this->actor.shape.rot.z = 1; + } else if (this->actor.shape.rot.z > 0x10) { + this->actor.shape.rot.z = 0x10; + } + this->actor.shape.rot.z += -1; + this->unk_BC6 = this->actor.shape.rot.z * 0x10; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_809328A4.s") + this->actor.shape.rot.z = 0; + if (ENFZ_GET_4000(&this->actor)) { + this->unk_BC0 = 0; + this->actor.scale.y = 0.0f; + func_80933184(this); + } else if (ENFZ_GET_F(&this->actor) == ENFZ_F_3) { + func_80933AF4(this); + } else { + func_8093389C(this); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_809328F4.s") + this->unk_BA4 = 0; + this->unk_BA0 = 0.0f; + this->unk_B9C = 0.0f; + func_80932784(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80932AE8.s") +void EnFz_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnFz* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80932AF4.s") + Collider_DestroyCylinder(globalCtx, &this->collider1); + Collider_DestroyCylinder(globalCtx, &this->collider2); + Collider_DestroyCylinder(globalCtx, &this->collider3); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80932BD4.s") + if ((this->actor.parent != NULL) && (this->unk_BC4 == 0) && (this->actor.parent->id == ACTOR_EN_WIZ) && + (this->actor.parent->update != NULL) && (((EnWiz*)this->actor.parent)->unk_448 != 0)) { + EnWiz* wiz = (EnWiz*)this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80932C98.s") + wiz->unk_448 = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80933014.s") +void func_80932784(EnFz* this, GlobalContext* globalCtx) { + Vec3f sp5C; + Vec3f sp50; + Vec3f sp44; + s32 sp40; + CollisionPoly* sp3C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_809330D4.s") + sp5C.x = this->actor.world.pos.x; + sp5C.y = this->actor.world.pos.y + 20.0f; + sp5C.z = this->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80933104.s") + Matrix_InsertTranslation(sp5C.x, sp5C.y, sp5C.z, MTXMODE_NEW); + Matrix_InsertRotation(this->actor.shape.rot.x, this->actor.shape.rot.y, this->actor.shape.rot.z, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80933184.s") + sp44.x = sp44.y = 0.0f; + sp44.z = 440.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_809331F8.s") + Matrix_MultiplyVector3fByState(&sp44, &this->unk_22C); + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &sp5C, &this->unk_22C, &sp50, &sp3C, 1, 0, 0, 1, &sp40)) { + Math_Vec3f_Copy(&this->unk_22C, &sp50); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80933248.s") + sp5C.x = this->actor.world.pos.x - this->unk_22C.x; + sp5C.z = this->actor.world.pos.z - this->unk_22C.z; + this->unk_238 = SQ(sp5C.x) + SQ(sp5C.z); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80933274.s") +s32 func_809328A4(EnFz* this, Vec3f* arg1) { + f32 temp_f0 = this->actor.world.pos.x - arg1->x; + f32 temp_f2 = this->actor.world.pos.z - arg1->z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80933324.s") + if (this->unk_238 <= (SQ(temp_f0) + SQ(temp_f2))) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80933368.s") +void func_809328F4(EnFz* this, GlobalContext* globalCtx, Vec3f* arg2, s32 arg3, f32 arg4) { + s32 i; + Vec3f spA8; + Vec3f sp9C; + Vec3f sp90; + Color_RGBA8 sp8C; + Color_RGBA8 sp88; + f32 temp_f24; + s32 temp_s1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_809333A4.s") + sp90.x = sp90.z = 0.0f; + sp90.y = -1.0f; + sp8C.r = 155; + sp8C.g = 255; + sp8C.b = 255; + sp8C.a = 255; + sp88.r = 200; + sp88.g = 200; + sp88.b = 200; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_809333D8.s") + for (i = 0; i < arg3; i++) { + temp_f24 = randPlusMinusPoint5Scaled(0.3f) + 0.6f; + temp_s1 = (s32)randPlusMinusPoint5Scaled(5.0f) + 12; + spA8.x = randPlusMinusPoint5Scaled(arg4) + arg2->x; + spA8.y = Rand_ZeroFloat(arg4) + arg2->y; + spA8.z = randPlusMinusPoint5Scaled(arg4) + arg2->z; + sp9C.x = randPlusMinusPoint5Scaled(10.0f); + sp9C.y = Rand_ZeroFloat(10.0f) + 2.0f; + sp9C.z = randPlusMinusPoint5Scaled(10.0f); + EffectSsEnIce_Spawn(globalCtx, &spA8, temp_f24, &sp9C, &sp90, &sp8C, &sp88, temp_s1); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80933414.s") + CollisionCheck_SpawnShieldParticles(globalCtx, arg2); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80933444.s") +void func_80932AE8(EnFz* this) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80933480.s") +void func_80932AF4(EnFz* this) { + Vec3f sp44; + Vec3f sp38; + Vec3f sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_809334B8.s") + if (!(this->unk_BC6 & 0xF)) { + sp44.x = randPlusMinusPoint5Scaled(40.0f) + this->actor.world.pos.x; + sp44.y = randPlusMinusPoint5Scaled(40.0f) + this->actor.world.pos.y + 30.0f; + sp44.z = randPlusMinusPoint5Scaled(40.0f) + this->actor.world.pos.z; + sp2C.x = sp2C.z = 0.0f; + sp2C.y = 0.1f; + sp38.x = sp38.y = sp38.z = 0.0f; + func_80934018(this, &sp44, &sp38, &sp2C, Rand_ZeroFloat(7.5f) + 15.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_809336C0.s") +void func_80932BD4(EnFz* this) { + Vec3f sp44; + Vec3f sp38; + Vec3f sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80933760.s") + if (!(this->unk_BC6 & 3)) { + sp44.x = randPlusMinusPoint5Scaled(40.0f) + this->actor.world.pos.x; + sp44.y = this->unk_BB4; + sp44.z = randPlusMinusPoint5Scaled(40.0f) + this->actor.world.pos.z; + sp2C.x = sp2C.z = 0.0f; + sp2C.y = 0.1f; + sp38.x = sp38.y = sp38.z = 0.0f; + func_80934018(this, &sp44, &sp38, &sp2C, Rand_ZeroFloat(7.5f) + 15.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80933790.s") +void func_80932C98(EnFz* this, GlobalContext* globalCtx) { + Vec3f sp3C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_809337D4.s") + if (this->unk_BCD != 0) { + if ((this->actor.bgCheckFlags & 8) || !func_800BC4EC(&this->actor, globalCtx, 60.0f, this->actor.world.rot.y)) { + this->actor.bgCheckFlags &= ~0x8; + this->unk_BCD = 0; + this->unk_BBC = 0.0f; + this->actor.speedXZ = 0.0f; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_8093389C.s") + if (this->actor.parent != NULL) { + if ((this->unk_BC4 != 5) && (this->actor.parent->id == ACTOR_EN_WIZ)) { + Actor* parent = this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_809338E0.s") + if ((parent->update == NULL) || (parent->colChkInfo.health <= 0)) { + this->actor.colChkInfo.health = 0; + this->unk_BC4 = 5; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_FREEZAD_DEAD); + Audio_PlayActorSound2(&this->actor, NA_SE_EV_ICE_BROKEN); + sp3C.x = this->actor.world.pos.x; + sp3C.y = this->actor.world.pos.y; + sp3C.z = this->actor.world.pos.z; + func_809328F4(this, globalCtx, &sp3C, 30, 10.0f); + func_809336C0(this, globalCtx); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80933AF4.s") + if ((this->actor.colChkInfo.health != 0) && (this->unk_BC4 == 1)) { + this->actor.colChkInfo.health = 0; + this->unk_BC4 = 5; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_FREEZAD_DEAD); + Audio_PlayActorSound2(&this->actor, NA_SE_EV_ICE_BROKEN); + sp3C.x = this->actor.world.pos.x; + sp3C.y = this->actor.world.pos.y; + sp3C.z = this->actor.world.pos.z; + func_809328F4(this, globalCtx, &sp3C, 30, 10.0f); + func_809336C0(this, globalCtx); + return; + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80933B38.s") + if (this->unk_BCE != 0) { + if (ENFZ_GET_8000(&this->actor) && (this->collider1.base.atFlags & AC_HIT)) { + this->unk_BCD = 0; + this->unk_BBC = 0.0f; + this->collider1.base.acFlags &= ~AC_HIT; + this->actor.speedXZ = 0.0f; + this->unk_BCA = 10; + func_809330D4(this); + } else if (this->collider2.base.acFlags & AC_BOUNCED) { + this->collider2.base.acFlags &= ~AC_BOUNCED; + this->collider1.base.acFlags &= ~AC_HIT; + } else if (this->collider1.base.acFlags & AC_HIT) { + this->collider1.base.acFlags &= ~AC_HIT; + switch (this->actor.colChkInfo.damageEffect) { + case 4: + this->unk_BA4 = 0x28; + this->unk_B9C = 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80933B48.s") + case 15: + Actor_ApplyDamage(&this->actor); + func_800BCB70(&this->actor, 0x4000, 0xFF, 0x2000, 8); + if (this->actor.colChkInfo.health != 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_FREEZAD_DAMAGE); + sp3C.x = this->actor.world.pos.x; + sp3C.y = this->actor.world.pos.y; + sp3C.z = this->actor.world.pos.z; + func_809328F4(this, globalCtx, &sp3C, 10, 0.0f); + this->unk_BCF++; + break; + } + Audio_PlayActorSound2(&this->actor, NA_SE_EN_FREEZAD_DEAD); + Audio_PlayActorSound2(&this->actor, NA_SE_EV_ICE_BROKEN); + sp3C.x = this->actor.world.pos.x; + sp3C.y = this->actor.world.pos.y; + sp3C.z = this->actor.world.pos.z; + func_809328F4(this, globalCtx, &sp3C, 30, 10.0f); + func_809336C0(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/EnFz_Update.s") + case 2: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_FREEZAD_DEAD); + func_80933790(this); + break; + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/EnFz_Draw.s") +void func_80933014(EnFz* this) { + s16 temp_a1 = this->actor.yawTowardsPlayer; + s32 temp_a2 = ENFZ_GET_3000(&this->actor); + s16 temp; + s16 temp2; + s32 temp_v1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80934018.s") + if (!ENFZ_GET_8000(&this->actor)) { + temp_v1 = this->actor.home.rot.y; + if (temp_a2 != 3) { + temp2 = temp_a1 - temp_v1; + if (D_809346F0[temp_a2] < ABS_ALT(temp2)) { + temp = (temp2 > 0) ? D_809346F0[temp_a2] : -D_809346F0[temp_a2]; + temp_a1 = this->actor.home.rot.y + temp; + } + } + } + Math_SmoothStepToS(&this->actor.shape.rot.y, temp_a1, 10, 2000, 0); + this->actor.world.rot.y = this->actor.shape.rot.y; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_809340BC.s") +void func_809330D4(EnFz* this) { + this->unk_BD6 = 2; + this->unk_BCE = 0; + this->actor.flags &= ~1; + this->actionFunc = func_80933104; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80934178.s") +void func_80933104(EnFz* this, GlobalContext* globalCtx) { + this->unk_BC0 -= 16; + if (this->unk_BC0 > 255) { + this->unk_BC0 = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Fz/func_80934464.s") + if (Math_SmoothStepToF(&this->actor.scale.y, 0, 1.0f, 0.0005f, 0.0f) == 0.0f) { + func_80933184(this); + } +} + +void func_80933184(EnFz* this) { + this->unk_BD6 = 0; + this->unk_BD2 = 0; + this->unk_BD0 = 0; + this->unk_BCA = 100; + + this->actor.world.pos.x = this->unk_BA8; + this->actor.world.pos.y = this->unk_BAC; + this->actor.world.pos.z = this->unk_BB0; + + if (ENFZ_GET_4000(&this->actor)) { + this->unk_BD6 = 2; + this->unk_BCA = 10; + this->unk_BD2 = 4000; + this->actionFunc = func_80933274; + } else { + this->actionFunc = func_809331F8; + } +} + +void func_809331F8(EnFz* this, GlobalContext* globalCtx) { + if ((this->unk_BCA == 0) && (this->actor.xzDistToPlayer < 400.0f)) { + func_80933248(this); + } +} + +void func_80933248(EnFz* this) { + this->unk_BD6 = 2; + this->unk_BCA = 20; + this->unk_BD2 = 4000; + this->actionFunc = func_80933274; +} + +void func_80933274(EnFz* this, GlobalContext* globalCtx) { + if (this->unk_BCA == 0) { + + this->unk_BC0 += 8; + if (this->unk_BC0 > 255) { + this->unk_BC0 = 255; + } + + if (Math_SmoothStepToF(&this->actor.scale.y, 0.008f, 1.0f, 0.0005f, 0.0f) == 0.0f) { + if (ENFZ_GET_4000(&this->actor)) { + func_8093389C(this); + } else { + func_80933324(this); + } + } + } +} + +void func_80933324(EnFz* this) { + this->unk_BD6 = 1; + this->unk_BCA = 40; + this->unk_BCC = 1; + this->unk_BCE = 1; + this->actor.flags |= 1; + this->actor.gravity = -1.0f; + this->actionFunc = func_80933368; +} + +void func_80933368(EnFz* this, GlobalContext* globalCtx) { + func_80933014(this); + if (this->unk_BCA == 0) { + func_809333A4(this); + } +} + +void func_809333A4(EnFz* this) { + this->unk_BD6 = 1; + this->unk_BCD = 1; + this->unk_BCA = 100; + this->unk_BBC = 4.0f; + this->actionFunc = func_809333D8; +} + +void func_809333D8(EnFz* this, GlobalContext* globalCtx) { + if ((this->unk_BCA == 0) || (this->unk_BCD == 0)) { + func_80933414(this); + } +} + +void func_80933414(EnFz* this) { + this->unk_BD6 = 1; + this->unk_BBC = 0.0f; + this->actor.speedXZ = 0.0f; + this->unk_BCA = 40; + this->actionFunc = func_80933444; +} + +void func_80933444(EnFz* this, GlobalContext* globalCtx) { + func_80933014(this); + if (this->unk_BCA == 0) { + func_80933480(this, globalCtx); + } +} + +void func_80933480(EnFz* this, GlobalContext* globalCtx) { + this->unk_BD6 = 1; + this->unk_BCA = 80; + this->actionFunc = func_809334B8; + func_80932784(this, globalCtx); +} + +void func_809334B8(EnFz* this, GlobalContext* globalCtx) { + Vec3f sp64; + Vec3f sp58; + Vec3f sp4C; + Vec3f sp40; + u8 sp3F; + s16 sp3C; + + if (this->unk_BCA == 0) { + func_809330D4(this); + return; + } + + if (this->unk_BCA > 10) { + sp3F = 0; + sp3C = 150; + func_800B9010(&this->actor, NA_SE_EN_FREEZAD_BREATH - SFX_FLAG); + if ((this->unk_BCA - 10) < 16) { + sp3C = (this->unk_BCA * 10) - 100; + } + + sp40.x = sp40.z = 0.0f; + sp40.y = 0.6f; + + sp58.x = this->actor.world.pos.x; + sp58.y = this->actor.world.pos.y + 20.0f; + sp58.z = this->actor.world.pos.z; + + Matrix_RotateY(this->actor.shape.rot.y, 0); + + sp64.x = 0.0f; + sp64.y = -2.0f; + sp64.z = ((ENFZ_GET_F(&this->actor) == ENFZ_F_1) ? 10.0f + : (ENFZ_GET_F(&this->actor) == ENFZ_F_2) ? 20.0f + : 0.0f) + + 20; + + Matrix_MultiplyVector3fByState(&sp64, &sp4C); + + if ((this->unk_BCA & 7) == 0) { + sp3F = 1; + } + + func_809340BC(this, &sp58, &sp4C, &sp40, 2.0f, 25.0f, sp3C, sp3F); + + sp58.x += sp4C.x * 0.5f; + sp58.y += sp4C.y * 0.5f; + sp58.z += sp4C.z * 0.5f; + + func_809340BC(this, &sp58, &sp4C, &sp40, 2.0f, 25.0f, sp3C, 0); + } +} + +void func_809336C0(EnFz* this, GlobalContext* globalCtx) { + this->unk_BD6 = 0; + this->unk_BBC = 0.0f; + this->actor.gravity = 0.0f; + this->actor.velocity.y = 0.0f; + this->actor.speedXZ = 0.0f; + this->unk_BCC = 1; + this->unk_BCE = 0; + this->unk_BD8 = 1; + this->actor.flags &= ~1; + this->unk_BD7 = 0; + this->unk_BCA = 60; + func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, ACTORCAT_PROP); + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0xA0); + this->actionFunc = func_80933760; +} + +void func_80933760(EnFz* this, GlobalContext* globalCtx) { + if (this->unk_BCA == 0) { + Actor_MarkForDeath(&this->actor); + } +} + +void func_80933790(EnFz* this) { + this->unk_BD6 = 3; + this->unk_BCE = 0; + this->unk_BD8 = 1; + this->actor.flags &= ~1; + this->actor.speedXZ = 0.0f; + this->unk_BBC = 0.0f; + this->actionFunc = func_809337D4; +} + +void func_809337D4(EnFz* this, GlobalContext* globalCtx) { + Math_StepToF(&this->actor.scale.y, 0.0006f, 0.0006f); + + if (this->actor.scale.y < 0.006f) { + this->actor.scale.x += 0.001f; + this->actor.scale.z += 0.001f; + } + + if (this->actor.scale.y < 0.004f) { + this->unk_BC0 -= 20; + if (this->unk_BC0 > 255) { + this->unk_BC0 = 0; + } + } + + if (this->unk_BC0 == 0) { + func_809336C0(this, globalCtx); + } +} + +void func_8093389C(EnFz* this) { + this->unk_BD6 = 1; + this->unk_BCA = 40; + this->unk_BCC = 1; + this->unk_BCE = 1; + this->actor.flags |= 1; + this->actor.gravity = -1.0f; + this->actionFunc = func_809338E0; +} + +void func_809338E0(EnFz* this, GlobalContext* globalCtx) { + Vec3f sp64; + Vec3f sp58; + Vec3f sp4C; + Vec3f sp40; + u8 sp3F; + s16 sp3C; + + if (this->unk_BC6 & (0x80 | 0x40)) { + func_80933014(this); + func_80932784(this, globalCtx); + return; + } + + sp3F = 0; + sp3C = 150; + func_800B9010(&this->actor, NA_SE_EN_FREEZAD_BREATH - SFX_FLAG); + + if ((this->unk_BC6 & 0x3F) >= 0x30) { + sp3C = 630 - ((this->unk_BC6 & 0x3F) * 10); + } + + sp40.x = sp40.z = 0.0f; + sp40.y = 0.6f; + + sp58.x = this->actor.world.pos.x; + sp58.y = this->actor.world.pos.y + 20.0f; + sp58.z = this->actor.world.pos.z; + + Matrix_RotateY(this->actor.shape.rot.y, 0); + + sp64.x = 0.0f; + sp64.y = -2.0f; + sp64.z = ((ENFZ_GET_F(&this->actor) == ENFZ_F_1) ? 10.0f + : (ENFZ_GET_F(&this->actor) == ENFZ_F_2) ? 20.0f + : 0.0f) + + 20; + + Matrix_MultiplyVector3fByState(&sp64, &sp4C); + + if (!(this->unk_BC6 & 7)) { + sp3F = 1; + } + + func_809340BC(this, &sp58, &sp4C, &sp40, 2.0f, 25.0f, sp3C, sp3F); + sp58.x += sp4C.x * 0.5f; + sp58.y += sp4C.y * 0.5f; + sp58.z += sp4C.z * 0.5f; + func_809340BC(this, &sp58, &sp4C, &sp40, 2.0f, 25.0f, sp3C, 0); +} + +void func_80933AF4(EnFz* this) { + this->unk_BD6 = 1; + this->unk_BCA = 40; + this->unk_BCC = 1; + this->unk_BCE = 1; + this->actor.flags |= 1; + this->actor.gravity = -1.0f; + this->actionFunc = func_80933B38; +} + +void func_80933B38(EnFz* this, GlobalContext* globalCtx) { +} + +void func_80933B48(EnFz* this, GlobalContext* globalCtx) { + if (this->unk_BA4 != 0) { + if (this->unk_BA4 > 0) { + this->unk_BA4--; + } + + if (this->unk_BA4 < 20) { + Math_SmoothStepToF(&this->unk_BA0, 0.0f, 0.5f, 0.03f, 0.0f); + this->unk_B9C = this->unk_BA4 * 0.05f; + } else { + Math_SmoothStepToF(&this->unk_BA0, 0.5f, 0.1f, 0.02f, 0.0f); + } + } +} + +void EnFz_Update(Actor* thisx, GlobalContext* globalCtx) { + static EnFzUnkFunc D_809347AC[] = { func_80932AE8, func_80932AF4, func_80932BD4, func_80932BD4 }; + s32 pad; + EnFz* this = THIS; + + this->unk_BC6++; + if (this->unk_BC8 != 0) { + this->unk_BC8--; + } + + if (this->unk_BCA != 0) { + this->unk_BCA--; + } + + if (this->unk_BD9 != 0) { + this->unk_BD9--; + } + + Actor_SetHeight(&this->actor, 50.0f); + func_80932C98(this, globalCtx); + + this->actionFunc(this, globalCtx); + + if (this->unk_BD8 == 0) { + Collider_UpdateCylinder(&this->actor, &this->collider1); + Collider_UpdateCylinder(&this->actor, &this->collider2); + if (this->unk_BCE != 0) { + if (this->actor.colorFilterTimer == 0) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + } + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + } + } + + Math_StepToF(&this->actor.speedXZ, this->unk_BBC, 0.2f); + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + if (this->unk_BCC != 0) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 20.0f, 5); + } + + D_809347AC[this->unk_BD6](this); + func_80933B48(this, globalCtx); + func_80934178(this, globalCtx); +} + +void EnFz_Draw(Actor* thisx, GlobalContext* globalCtx) { + static Gfx* D_809347BC[] = { object_fz_DL_001130, object_fz_DL_0021A0, object_fz_DL_002CA0 }; + s32 pad; + EnFz* this = THIS; + s32 sp9C = 3 - this->actor.colChkInfo.health; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (this->actor.colChkInfo.health == 0) { + sp9C = 2; + } + + if (this->unk_BD7 != 0) { + func_800B8118(&this->actor, globalCtx, 0); + func_8012C2DC(globalCtx->state.gfxCtx); + + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, globalCtx->state.frames % 128, 0x20, 0x20, 1, 0, + (globalCtx->state.frames * 2) % 128, 0x20, 0x20)); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetCombineLERP(POLY_XLU_DISP++, TEXEL1, PRIMITIVE, PRIM_LOD_FRAC, TEXEL0, TEXEL1, TEXEL0, PRIMITIVE, TEXEL0, + PRIMITIVE, ENVIRONMENT, COMBINED, ENVIRONMENT, COMBINED, 0, ENVIRONMENT, 0); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 155, 255, 255, 255); + gDPSetEnvColor(POLY_XLU_DISP++, 200, 200, 200, this->unk_BC0); + gSPDisplayList(POLY_XLU_DISP++, D_809347BC[sp9C]); + } + + func_80934464(this, globalCtx); + + if (this->unk_BA4 > 0) { + s32 pad2[6]; + Vec3f sp58; + Vec3f sp4C; + s32 pad3; + + sp4C = this->actor.world.pos; + sp58 = this->actor.world.pos; + sp4C.y += 20.0f; + sp58.y += 40.0f; + func_800BE680(globalCtx, NULL, &sp4C, 2, this->unk_BA0 * 4.0f, 0.5f, this->unk_B9C, 20); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80934018(EnFz* this, Vec3f* a, Vec3f* b, Vec3f* c, f32 arg4) { + s16 i; + EnFzStruct* ptr = &this->unk_23C[0]; + + for (i = 0; i < ARRAY_COUNT(this->unk_23C); i++, ptr++) { + if (ptr->unk_00 == 0) { + ptr->unk_00 = 1; + ptr->unk_04 = *a; + ptr->unk_10 = *b; + ptr->unk_1C = *c; + ptr->unk_2E = 0; + ptr->unk_30 = arg4 / 1000.0f; + ptr->unk_2C = 0; + ptr->unk_01 = 0; + break; + } + } +} + +void func_809340BC(EnFz* this, Vec3f* a, Vec3f* b, Vec3f* c, f32 arg4, f32 arg5, s16 arg6, u8 arg7) { + s16 i; + EnFzStruct* ptr = &this->unk_23C[0]; + + for (i = 0; i < ARRAY_COUNT(this->unk_23C); i++, ptr++) { + if (ptr->unk_00 == 0) { + ptr->unk_00 = 2; + ptr->unk_04 = *a; + ptr->unk_10 = *b; + ptr->unk_1C = *c; + ptr->unk_2E = 0; + ptr->unk_30 = arg4 / 1000.0f; + ptr->unk_34 = arg5 / 1000.0f; + ptr->unk_2C = arg6; + ptr->unk_01 = 0; + ptr->unk_38 = arg7; + break; + } + } +} + +void func_80934178(EnFz* this, GlobalContext* globalCtx) { + s16 i; + EnFzStruct* ptr = this->unk_23C; + Vec3f sp64; + + for (i = 0; i < ARRAY_COUNT(this->unk_23C); i++, ptr++) { + if (ptr->unk_00 != 0) { + ptr->unk_04.x += ptr->unk_10.x; + ptr->unk_04.y += ptr->unk_10.y; + ptr->unk_04.z += ptr->unk_10.z; + + ptr->unk_01++; + + ptr->unk_10.x += ptr->unk_1C.x; + ptr->unk_10.y += ptr->unk_1C.y; + ptr->unk_10.z += ptr->unk_1C.z; + + if (ptr->unk_00 == 1) { + if (ptr->unk_2E == 0) { + ptr->unk_2C += 10; + if (ptr->unk_2C >= 100) { + ptr->unk_2E++; + } + } else { + ptr->unk_2C -= 3; + if (ptr->unk_2C <= 0) { + ptr->unk_2C = 0; + ptr->unk_00 = 0; + } + } + } else if (ptr->unk_00 == 2) { + Math_ApproachF(&ptr->unk_30, ptr->unk_34, 0.1f, ptr->unk_34 / 10.0f); + if (ptr->unk_2E == 0) { + if (ptr->unk_01 >= 7) { + ptr->unk_2E++; + } + } else { + ptr->unk_10.x *= 0.75f; + ptr->unk_1C.y = 2.0f; + ptr->unk_10.z *= 0.75f; + ptr->unk_2C -= 17; + if (ptr->unk_2C <= 0) { + ptr->unk_2C = 0; + ptr->unk_00 = 0; + } + } + + if ((this->unk_BD9 == 0) && (ptr->unk_2C > 100) && (ptr->unk_38 != 0)) { + this->collider3.dim.pos.x = ptr->unk_04.x; + this->collider3.dim.pos.y = ptr->unk_04.y; + this->collider3.dim.pos.z = ptr->unk_04.z; + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider3.base); + } + + sp64.x = ptr->unk_04.x; + sp64.y = ptr->unk_04.y + 10.0f; + sp64.z = ptr->unk_04.z; + + if ((ptr->unk_2E != 2) && func_809328A4(this, &sp64)) { + ptr->unk_2E = 2; + ptr->unk_10.x = 0.0f; + ptr->unk_10.z = 0.0f; + } + } + } + } +} + +void func_80934464(EnFz* this, GlobalContext* globalCtx) { + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + s16 i; + u8 flag = 0; + EnFzStruct* ptr = this->unk_23C; + + OPEN_DISPS(gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + gDPSetColorDither(POLY_XLU_DISP++, G_CD_BAYER); + gDPSetAlphaDither(POLY_XLU_DISP++, G_AD_PATTERN); + + for (i = 0; i < ARRAY_COUNT(this->unk_23C); i++, ptr++) { + if (ptr->unk_00 > 0) { + gDPPipeSync(POLY_XLU_DISP++); + + if (flag == 0) { + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_051180); + flag++; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 225, 235, ptr->unk_2C); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, (ptr->unk_01 + (i * 3)) * 3, + (ptr->unk_01 + (i * 3)) * 15, 0x20, 0x40, 1, 0, 0, 0x20, 0x20)); + + Matrix_InsertTranslation(ptr->unk_04.x, ptr->unk_04.y, ptr->unk_04.z, MTXMODE_NEW); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + Matrix_Scale(ptr->unk_30, ptr->unk_30, 1.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_051238); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Fz/z_en_fz.h b/src/overlays/actors/ovl_En_Fz/z_en_fz.h index 7eb989cf3..5e76eadf9 100644 --- a/src/overlays/actors/ovl_En_Fz/z_en_fz.h +++ b/src/overlays/actors/ovl_En_Fz/z_en_fz.h @@ -5,10 +5,70 @@ struct EnFz; +typedef void (*EnFzActionFunc)(struct EnFz*, GlobalContext*); +typedef void (*EnFzUnkFunc)(struct EnFz*); + +#define ENFZ_GET_F(thisx) ((thisx)->params & 0xF) +#define ENFZ_GET_3000(thisx) (((thisx)->params & 0x3000) >> 0xC) +#define ENFZ_GET_4000(thisx) ((thisx)->params & 0x4000) +#define ENFZ_GET_8000(thisx) ((thisx)->params & 0x8000) + +enum { + /* 0 */ ENFZ_F_0, + /* 1 */ ENFZ_F_1, + /* 2 */ ENFZ_F_2, + /* 3 */ ENFZ_F_3, +}; + +typedef struct { + /* 0x00 */ u8 unk_00; + /* 0x01 */ u8 unk_01; + /* 0x04 */ Vec3f unk_04; + /* 0x10 */ Vec3f unk_10; + /* 0x1C */ Vec3f unk_1C; + /* 0x28 */ UNK_TYPE1 unk_28[0x4]; + /* 0x2C */ s16 unk_2C; + /* 0x2E */ s16 unk_2E; + /* 0x30 */ f32 unk_30; + /* 0x34 */ f32 unk_34; + /* 0x38 */ u8 unk_38; +} EnFzStruct; // size = 0x3C + typedef struct EnFz { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0xA98]; -} EnFz; // size = 0xBDC + /* 0x144 */ EnFzActionFunc actionFunc; + /* 0x148 */ ColliderCylinder collider1; + /* 0x194 */ ColliderCylinder collider2; + /* 0x1E0 */ ColliderCylinder collider3; + /* 0x22C */ Vec3f unk_22C; + /* 0x238 */ f32 unk_238; + /* 0x23C */ EnFzStruct unk_23C[40]; + /* 0xB9C */ f32 unk_B9C; + /* 0xBA0 */ f32 unk_BA0; + /* 0xBA4 */ s16 unk_BA4; + /* 0xBA8 */ f32 unk_BA8; + /* 0xBAC */ f32 unk_BAC; + /* 0xBB0 */ f32 unk_BB0; + /* 0xBB4 */ f32 unk_BB4; + /* 0xBB8 */ f32 unk_BB8; + /* 0xBBC */ f32 unk_BBC; + /* 0xBC0 */ u32 unk_BC0; + /* 0xBC4 */ s16 unk_BC4; + /* 0xBC6 */ s16 unk_BC6; + /* 0xBC8 */ s16 unk_BC8; + /* 0xBCA */ s16 unk_BCA; + /* 0xBCC */ u8 unk_BCC; + /* 0xBCD */ u8 unk_BCD; + /* 0xBCE */ u8 unk_BCE; + /* 0xBCF */ u8 unk_BCF; + /* 0xBD0 */ s16 unk_BD0; + /* 0xBD2 */ s16 unk_BD2; + /* 0xBD4 */ UNK_TYPE1 unkBD4[2]; + /* 0xBD6 */ u8 unk_BD6; + /* 0xBD7 */ u8 unk_BD7; + /* 0xBD8 */ u8 unk_BD8; + /* 0xBD9 */ u8 unk_BD9; +} EnFz; /* size = 0xBDC */ extern const ActorInit En_Fz_InitVars; diff --git a/src/overlays/actors/ovl_En_Gamelupy/z_en_gamelupy.c b/src/overlays/actors/ovl_En_Gamelupy/z_en_gamelupy.c index 590949028..a27c5bdc4 100644 --- a/src/overlays/actors/ovl_En_Gamelupy/z_en_gamelupy.c +++ b/src/overlays/actors/ovl_En_Gamelupy/z_en_gamelupy.c @@ -1,7 +1,7 @@ /* * File: z_en_gamelupy.c * Overlay: ovl_En_Gamelupy - * Description: Deku Scrub Playground - Large Green Rupee + * Description: Deku Scrub Playground Rupees */ #include "z_en_gamelupy.h" diff --git a/src/overlays/actors/ovl_En_Gb2/z_en_gb2.c b/src/overlays/actors/ovl_En_Gb2/z_en_gb2.c index 6d78480e7..15a1db429 100644 --- a/src/overlays/actors/ovl_En_Gb2/z_en_gb2.c +++ b/src/overlays/actors/ovl_En_Gb2/z_en_gb2.c @@ -5,6 +5,7 @@ */ #include "z_en_gb2.h" +#include "objects/object_ps/object_ps.h" #define FLAGS 0x00000039 @@ -15,6 +16,7 @@ void EnGb2_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnGb2_Update(Actor* thisx, GlobalContext* globalCtx); void EnGb2_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80B0FBF0(EnGb2* this, GlobalContext* globalCtx); void func_80B0FEBC(EnGb2* this, GlobalContext* globalCtx); void func_80B0FFA8(EnGb2* this, GlobalContext* globalCtx); void func_80B10240(EnGb2* this, GlobalContext* globalCtx); @@ -29,11 +31,11 @@ void func_80B10B5C(EnGb2* this, GlobalContext* globalCtx); void func_80B10DAC(EnGb2* this, GlobalContext* globalCtx); void func_80B10E98(EnGb2* this, GlobalContext* globalCtx); void func_80B11048(EnGb2* this, GlobalContext* globalCtx); +void func_80B110F8(EnGb2* this, GlobalContext* globalCtx); void func_80B111AC(EnGb2* this, GlobalContext* globalCtx); void func_80B11268(EnGb2* this, GlobalContext* globalCtx); void func_80B11344(EnGb2* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Gb2_InitVars = { ACTOR_EN_GB2, ACTORCAT_NPC, @@ -46,98 +48,984 @@ const ActorInit En_Gb2_InitVars = { (ActorFunc)EnGb2_Draw, }; -// static ColliderCylinderInitType1 sCylinderInit = { -static ColliderCylinderInitType1 D_80B11A40 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +typedef struct { + /* 0x00 */ s16 unk_00; + /* 0x04 */ Vec3f unk_04; + /* 0x10 */ s16 unk_10; +} EnGbStruct; // size = 0x14 + +static EnGbStruct D_80B119B0[] = { + { ACTOR_EN_PO_SISTERS, { 0.0f, 0.0f, 0.0f }, 0x300 }, + { ACTOR_EN_PO_SISTERS, { 100.0f, 0.0f, 0.0f }, 0x200 }, + { ACTOR_EN_PO_SISTERS, { -100.0f, 0.0f, 0.0f }, 0x100 }, + { ACTOR_EN_PO_SISTERS, { 0.0f, 0.0f, 0.0f }, 0 }, +}; + +static f32 D_80B11A00[][4] = { + { 0.0f, -13.0f, 549.0f, 0.0f }, + { -242.0f, -13.0f, 390.0f, -90.0f }, + { 0.0f, -13.0f, 148.0f, 180.0f }, + { 244.0f, -13.0f, 390.0f, 90.0f }, +}; + +static ColliderCylinderInitType1 sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 40, 75, 0, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B11AC4[] = { +void func_80B0F5E0(EnGb2* this, GlobalContext* globalCtx) { + this->collider.dim.pos.x = this->actor.world.pos.x; + this->collider.dim.pos.y = this->actor.world.pos.y; + this->collider.dim.pos.z = this->actor.world.pos.z; + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +s32 func_80B0F660(EnGb2* this, GlobalContext* globalCtx) { + Actor* temp_v0; + Actor* phi_s0 = NULL; + + while (true) { + temp_v0 = SubS_FindActor(globalCtx, phi_s0, ACTORCAT_NPC, ACTOR_EN_GB2); + if (temp_v0 == NULL) { + break; + } + + if ((EnGb2*)temp_v0 != this) { + return true; + } + + temp_v0 = temp_v0->next; + if (temp_v0 == NULL) { + break; + } + phi_s0 = temp_v0; + }; + + return false; +} + +void func_80B0F6DC(EnGb2* this) { + if (!(gSaveContext.weekEventReg[54] & 0x20)) { + gSaveContext.weekEventReg[54] |= 0x20; + this->unk_26E = 0x14D0; + } else { + this->unk_26E = 0x14D1; + } + this->unk_288 = 30; + this->actionFunc = func_80B0FEBC; +} + +void func_80B0F728(EnGb2* this, GlobalContext* globalCtx) { + if (gSaveContext.eventInf[4] & 0x10) { + func_80B0FBF0(this, globalCtx); + this->unk_26E = 0x14E1; + if (gSaveContext.eventInf[4] & 0x80) { + this->unk_288 = 10; + } else { + this->unk_288 = 30; + } + } else if (gSaveContext.eventInf[4] & 0x20) { + func_80B0FBF0(this, globalCtx); + this->unk_26E = 0x14E0; + this->unk_26C |= 2; + } else { + this->unk_26E = 0x14DC; + } + + gSaveContext.eventInf[4] &= (u8)~0x10; + gSaveContext.eventInf[4] &= (u8)~0x20; + gSaveContext.eventInf[4] &= (u8)~0x40; + this->actionFunc = func_80B10584; +} + +u16 func_80B0F7FC(EnGb2* this) { + switch (this->unk_26E) { + case 0x14D0: + return 0x14D1; + + case 0x14D1: + if (gSaveContext.eventInf[4] & 0x80) { + return 0x14E4; + } + + if (gSaveContext.health > 48) { + return 0x14D2; + } + + this->unk_26C |= 2; + return 0x14D3; + + case 0x14E4: + if (gSaveContext.health > 48) { + return 0x14D2; + } + + this->unk_26C |= 2; + return 0x14D3; + + case 0x14D2: + if (gSaveContext.eventInf[4] & 0x80) { + return 0x14E5; + } + return 0x14D4; + + case 0x14D4: + case 0x14E5: + return 0x14D5; + + case 0x14D8: + return 0x14D9; + + case 0x14D9: + return 0x14DA; + } + return 0; +} + +u16 func_80B0F8F8(EnGb2* this) { + switch (this->unk_26E) { + case 0x14DC: + this->unk_26C |= 2; + return 0x14DD; + + case 0x14DD: + return 0x14DE; + + case 0x14DE: + this->unk_26C |= 2; + gSaveContext.weekEventReg[54] |= 0x80; + return 0x14DF; + + case 0x14E1: + return 0x14E2; + } + return 0; +} + +u16 func_80B0F97C(EnGb2* this) { + switch (this->unk_26E) { + case 0x14F5: + return 0x14F6; + + case 0x14F6: + return 0x14F7; + + case 0x14F7: + gSaveContext.weekEventReg[76] |= 0x80; + this->unk_26C |= 2; + return 0x14F8; + + case 0x14F9: + return 0x14FA; + + case 0x14FA: + this->unk_26C |= 2; + return 0x14FB; + } + return 0; +} + +void func_80B0FA04(EnGb2* this) { + this->unk_282[0] = this->actor.cutscene; + this->unk_282[1] = ActorCutscene_GetAdditionalCutscene(this->unk_282[0]); + this->unk_282[2] = ActorCutscene_GetAdditionalCutscene(this->unk_282[1]); +} + +s32 func_80B0FA48(EnGb2* this, GlobalContext* globalCtx) { + switch (Player_GetMask(globalCtx)) { + case PLAYER_MASK_GIBDO: + this->unk_26C |= 4; + this->unk_26E = 0x14E6; + return false; + + case PLAYER_MASK_GARO: + this->unk_26C |= 8; + this->unk_26E = 0x14E6; + return false; + + case PLAYER_MASK_CAPTAIN: + if (!(gSaveContext.weekEventReg[80] & 0x40)) { + this->unk_26E = 0x14EB; + return false; + } + this->unk_26E = 0x14EE; + return true; + } + + if (!(gSaveContext.weekEventReg[80] & 0x20)) { + this->unk_26E = 0x14EF; + return false; + } else { + this->unk_26E = 0x14F4; + return true; + } +} + +u16 func_80B0FB24(EnGb2* this) { + switch (this->unk_26E) { + case 0x14E6: + if (this->unk_26C & 4) { + return 0x14E7; + } + + if (this->unk_26C & 8) { + return 0x14E9; + } + + case 0x14E7: + this->unk_26C |= 2; + return 0x14E8; + + case 0x14E9: + this->unk_26C |= 2; + return 0x14EA; + + case 0x14EB: + return 0x14EC; + + case 0x14EC: + this->unk_26C |= 2; + return 0x14ED; + + case 0x14EF: + return 0x14F0; + + case 0x14F0: + return 0x14F1; + + case 0x14F1: + return 0x14F2; + + case 0x14F2: + this->unk_26C |= 2; + return 0x14F3; + } + return 0; +} + +void func_80B0FBF0(EnGb2* this, GlobalContext* globalCtx) { + Vec3f sp90[4] = { + { 120.0f, 0.0f, 800.0f }, + { -120.0f, 0.0f, 750.0f }, + { 60.0f, 0.0f, 750.0f }, + { -60.0f, 0.0f, 800.0f }, + }; + Vec3s sp78[] = { + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + { 0, 0, 0 }, + }; + s32 sp68[] = { + 0x1000, + 0x1100, + 0x1200, + 0x1300, + }; + s16 i; + s16 end = ARRAY_COUNT(sp90); + + for (i = 0; i < end; i++) { + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_PO_SISTERS, sp90[i].x, sp90[i].y, + sp90[i].z, sp78[i].x, sp78[i].y, sp78[i].z, sp68[i]); + } +} + +void func_80B0FD8C(EnGb2* this, GlobalContext* globalCtx) { + this->unk_280++; + this->unk_268 = this->actor.child; + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_PO_SISTERS, + D_80B119B0[this->unk_280].unk_04.x, D_80B119B0[this->unk_280].unk_04.y, + D_80B119B0[this->unk_280].unk_04.z, 0, 0, 0, D_80B119B0[this->unk_280].unk_10); +} + +void func_80B0FE18(GlobalContext* globalCtx) { + func_800FD750(0x38); + globalCtx->nextEntranceIndex = 0x9C10; + globalCtx->unk_1887F = 0x40; + gSaveContext.nextTransition = 0x40; + globalCtx->sceneLoadFlag = 0x14; +} + +void func_80B0FE7C(GlobalContext* globalCtx) { + globalCtx->nextEntranceIndex = 0x9C20; + globalCtx->unk_1887F = 0x40; + gSaveContext.nextTransition = 0x40; + globalCtx->sceneLoadFlag = 0x14; +} + +void func_80B0FEBC(EnGb2* this, GlobalContext* globalCtx) { + if ((globalCtx->msgCtx.unk1202A == 3) && (globalCtx->msgCtx.unk1202E == 7)) { + globalCtx->msgCtx.unk1202A = 4; + gSaveContext.eventInf[4] |= 0x80; + this->unk_26E = 0x14D1; + this->unk_288 = 10; + } + + if (func_800B84D0(&this->actor, globalCtx)) { + func_801518B0(globalCtx, this->unk_26E, &this->actor); + this->actionFunc = func_80B0FFA8; + } else if ((this->actor.xzDistToPlayer < 300.0f) || this->actor.isTargeted) { + func_800B863C(&this->actor, globalCtx); + } +} + +void func_80B0FFA8(EnGb2* this, GlobalContext* globalCtx) { + u8 temp_v0 = func_80152498(&globalCtx->msgCtx); + + if (temp_v0 == 5) { + if (func_80147624(globalCtx)) { + if (this->unk_26C & 2) { + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_26E = 0x14D1; + this->unk_288 = 30; + gSaveContext.eventInf[4] &= (u8)~0x80; + this->unk_26C &= ~2; + this->actionFunc = func_80B0FEBC; + } else { + this->unk_26E = func_80B0F7FC(this); + func_801518B0(globalCtx, this->unk_26E, &this->actor); + } + } + } else if ((temp_v0 == 4) && func_80147624(globalCtx)) { + if (this->unk_26E == 0x14D5) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + if (gSaveContext.rupees < this->unk_288) { + play_sound(NA_SE_SY_ERROR); + this->unk_26E = 0x14D7; + this->unk_26C |= 2; + func_801518B0(globalCtx, this->unk_26E, &this->actor); + } else { + func_8019F208(); + this->unk_26E = 0x14D8; + func_801518B0(globalCtx, this->unk_26E, &this->actor); + } + break; + + case 1: + func_8019F230(); + this->unk_26E = 0x14D6; + this->unk_26C |= 2; + func_801518B0(globalCtx, this->unk_26E, &this->actor); + break; + } + } else if (this->unk_26E == 0x14DA) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_8019F208(); + func_801159EC(-this->unk_288); + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + func_800B7298(globalCtx, NULL, 7); + this->actionFunc = func_80B11344; + break; + + case 1: + func_8019F230(); + this->unk_26E = 0x14DB; + this->unk_26C |= 2; + func_801518B0(globalCtx, this->unk_26E, &this->actor); + break; + } + } + } +} + +void func_80B10240(EnGb2* this, GlobalContext* globalCtx) { + this->unk_27C = D_80B119B0[this->unk_280].unk_00; + this->unk_27E = D_80B119B0[this->unk_280].unk_10; + this->unk_282[0] = this->actor.cutscene; + this->unk_268 = NULL; + if (ActorCutscene_GetCanPlayNext(this->unk_282[0])) { + ActorCutscene_Start(this->unk_282[0], &this->actor); + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, this->unk_27C, + D_80B119B0[this->unk_280].unk_04.x, D_80B119B0[this->unk_280].unk_04.y, + D_80B119B0[this->unk_280].unk_04.z, 0, 0, 0, this->unk_27E); + if (this->unk_280 == 0) { + func_8010E9F0(1, 180); + } + this->actionFunc = func_80B10344; + } else { + ActorCutscene_SetIntentToPlay(this->unk_282[0]); + } +} + +void func_80B10344(EnGb2* this, GlobalContext* globalCtx) { + if (this->unk_280 == 1) { + func_80B0FD8C(this, globalCtx); + } + + if (this->unk_280 == 2) { + if ((this->unk_268 != NULL) && (this->unk_268->update == NULL)) { + this->unk_268 = NULL; + this->unk_26C |= 0x400; + } + } + + if ((this->actor.child != NULL) && (this->actor.child->update == NULL)) { + this->actor.child = NULL; + this->unk_26C |= 0x200; + } + + if (this->unk_26C & 0x200) { + if (this->unk_280 == 3) { + this->unk_26C &= ~0x200; + gSaveContext.unk_3DD0[1] = 5; + func_800FE498(); + gSaveContext.eventInf[4] |= 0x40; + func_80B0FE7C(globalCtx); + } else if (this->unk_280 == 2) { + if (this->unk_26C & 0x400) { + this->unk_280++; + this->unk_26C &= ~0x200; + this->unk_26C &= ~0x400; + this->actionFunc = func_80B10240; + } + } else { + this->unk_280++; + this->unk_26C &= ~0x200; + this->actionFunc = func_80B10240; + } + } + + if (gSaveContext.health < 49) { + gSaveContext.unk_3DD0[1] = 5; + gSaveContext.eventInf[4] |= 0x40; + gSaveContext.eventInf[4] |= 0x20; + + if ((this->unk_268 != NULL) && (this->unk_268->update == NULL)) { + this->unk_268 = NULL; + } + + if ((this->actor.child != NULL) && (this->actor.child->update == NULL)) { + this->actor.child = NULL; + } + + func_80B0FE7C(globalCtx); + } else if (gSaveContext.unk_3DE0[1] == 0) { + gSaveContext.unk_3DD0[1] = 5; + gSaveContext.eventInf[4] |= 0x40; + gSaveContext.eventInf[4] |= 0x10; + + if ((this->unk_268 != NULL) && (this->unk_268->update == NULL)) { + this->unk_268 = NULL; + } + + if ((this->actor.child != NULL) && (this->actor.child->update == NULL)) { + this->actor.child = NULL; + } + + func_80B0FE7C(globalCtx); + } +} + +void func_80B10584(EnGb2* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + func_801518B0(globalCtx, this->unk_26E, &this->actor); + this->actor.flags &= ~0x10000; + this->actionFunc = func_80B10634; + } else if (this->actor.xzDistToPlayer < 300.0f) { + this->actor.flags |= 0x10000; + func_800B8614(&this->actor, globalCtx, 300.0f); + } +} + +void func_80B10634(EnGb2* this, GlobalContext* globalCtx) { + u8 temp_v0 = func_80152498(&globalCtx->msgCtx); + + if (temp_v0 == 5) { + if (func_80147624(globalCtx)) { + if (this->unk_26C & 2) { + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_26C &= ~2; + if (this->unk_26E == 0x14DD) { + this->unk_26E = 0x14DE; + this->actionFunc = func_80B10924; + } else if (this->unk_26E == 0x14DF) { + this->actionFunc = func_80B10A48; + } else { + this->unk_26E = 0x14D1; + this->unk_288 = 30; + gSaveContext.eventInf[4] &= (u8)~0x80; + this->actionFunc = func_80B0FEBC; + } + } else { + this->unk_26E = func_80B0F8F8(this); + func_801518B0(globalCtx, this->unk_26E, &this->actor); + } + } + } else if ((temp_v0 == 4) && func_80147624(globalCtx)) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + if (gSaveContext.rupees < this->unk_288) { + play_sound(NA_SE_SY_ERROR); + this->unk_26E = 0x14D7; + this->unk_26C |= 2; + func_801518B0(globalCtx, this->unk_26E, &this->actor); + } else { + func_8019F208(); + func_801159EC(-this->unk_288); + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + func_800B7298(globalCtx, NULL, 7); + this->actionFunc = func_80B11344; + } + break; + + case 1: + func_8019F230(); + this->unk_26E = 0x14E3; + this->unk_26C |= 2; + func_801518B0(globalCtx, this->unk_26E, &this->actor); + break; + } + } +} + +void func_80B10868(EnGb2* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCurrentIndex() != this->unk_282[2]) { + if (ActorCutscene_GetCanPlayNext(this->unk_282[this->unk_290])) { + this->actionFunc = func_80B10A48; + ActorCutscene_StartAndSetFlag(this->unk_282[this->unk_290], &this->actor); + } else { + ActorCutscene_SetIntentToPlay(this->unk_282[this->unk_290]); + } + } else { + this->unk_290 = 1; + ActorCutscene_SetIntentToPlay(this->unk_282[this->unk_290]); + } +} + +void func_80B10924(EnGb2* this, GlobalContext* globalCtx) { + s32 sp24; + + if (gSaveContext.weekEventReg[54] & 0x40) { + sp24 = 5; + } else { + sp24 = 12; + } + + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + if (sp24 == 12) { + gSaveContext.weekEventReg[54] |= 0x40; + } else { + func_801159EC(50); + } + this->actionFunc = func_80B109DC; + } else { + func_800B8A1C(&this->actor, globalCtx, sp24, 300.0f, 300.0f); + } +} + +void func_80B109DC(EnGb2* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + func_801518B0(globalCtx, this->unk_26E, &this->actor); + this->actionFunc = func_80B10634; + } else { + func_800B85E0(&this->actor, globalCtx, 300.0f, -1); + } +} + +void func_80B10A48(EnGb2* this, GlobalContext* globalCtx) { + this->unk_28A -= 5; + if (this->unk_28A < 5) { + this->unk_28A = 0; + + switch (ENGB2_GET_7(&this->actor)) { + case ENGB2_7_0: + Actor_MarkForDeath(&this->actor); + break; + + case ENGB2_7_1: + ActorCutscene_Stop(this->unk_282[this->unk_290]); + Actor_MarkForDeath(&this->actor); + break; + + case ENGB2_7_2: + ActorCutscene_Stop(this->unk_282[this->unk_290]); + if (this->unk_26E == 0x14FB) { + Actor_SetSwitchFlag(globalCtx, ENGB2_GET_7F8(&this->actor)); + Actor_MarkForDeath(&this->actor); + } else { + this->actor.draw = NULL; + this->unk_26C |= 0x100; + this->actor.flags &= ~1; + this->actionFunc = func_80B111AC; + } + break; + } + } +} + +void func_80B10B5C(EnGb2* this, GlobalContext* globalCtx) { + s32 mask = Player_GetMask(globalCtx); + + if (this->unk_28C != mask) { + this->unk_28C = Player_GetMask(globalCtx); + this->unk_26C &= ~0x80; + this->unk_26C &= ~0x20; + this->unk_26C &= ~0x40; + } + + if (func_80B0FA48(this, globalCtx)) { + this->unk_26C &= ~0x20; + if (func_800B84D0(&this->actor, globalCtx) && (this->unk_26C & 0x40)) { + if ((this->unk_26E == 0x14EE) || (this->unk_26E == 0x14F4)) { + this->unk_26C |= 2; + } + func_801518B0(globalCtx, this->unk_26E, &this->actor); + this->unk_290 = 1; + this->unk_26C &= ~0x40; + this->actionFunc = func_80B10DAC; + } else if ((this->actor.xzDistToPlayer < 300.0f) && this->actor.isTargeted) { + this->unk_26C |= 0x40; + func_800B8614(&this->actor, globalCtx, 300.0f); + } + } else { + this->unk_26C &= ~0x40; + if (func_800B84D0(&this->actor, globalCtx) && (this->unk_26C & 0x20)) { + this->actor.flags &= ~0x10000; + func_801518B0(globalCtx, this->unk_26E, &this->actor); + if (this->unk_26E == 0x14EB) { + gSaveContext.weekEventReg[80] |= 0x40; + } else if (this->unk_26E == 0x14EF) { + gSaveContext.weekEventReg[80] |= 0x20; + } + this->unk_26C &= ~0x20; + this->unk_290 = 0; + this->unk_26C |= 0x80; + this->actionFunc = func_80B10DAC; + } else if (this->actor.xzDistToPlayer < 300.0f) { + if (!(this->unk_26C & 0x80)) { + this->actor.flags |= 0x10000; + this->unk_26C |= 0x20; + func_800B8614(&this->actor, globalCtx, 300.0f); + } + } + } +} + +void func_80B10DAC(EnGb2* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->unk_282[this->unk_290])) { + if (ENGB2_GET_7(&this->actor) == ENGB2_7_1) { + if (this->unk_290 != 2) { + this->actionFunc = func_80B10E98; + } else { + Actor_SetSwitchFlag(globalCtx, ENGB2_GET_7F8(&this->actor)); + this->actionFunc = func_80B10868; + } + } else { + this->actionFunc = func_80B110F8; + } + ActorCutscene_StartAndSetFlag(this->unk_282[this->unk_290], &this->actor); + } else { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + } + ActorCutscene_SetIntentToPlay(this->unk_282[this->unk_290]); + } +} + +void func_80B10E98(EnGb2* this, GlobalContext* globalCtx) { + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + if (this->unk_26C & 2) { + this->unk_26C &= ~2; + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + if ((this->unk_26E != 0x14E8) && (this->unk_26E != 0x14EA)) { + ActorCutscene_Stop(this->unk_282[this->unk_290]); + this->actionFunc = func_80B10B5C; + } else if (Flags_GetSwitch(globalCtx, ENGB2_GET_7F8(&this->actor))) { + this->actionFunc = func_80B10A48; + } else { + ActorCutscene_Stop(this->unk_282[this->unk_290]); + this->unk_290 = 2; + ActorCutscene_SetIntentToPlay(this->unk_282[this->unk_290]); + this->actionFunc = func_80B10DAC; + } + } else { + s32 temp; + + this->unk_26E = func_80B0FB24(this); + func_801518B0(globalCtx, this->unk_26E, &this->actor); + temp = this->unk_26E; + if ((temp == 0x14E7) || (temp == 0x14E9) || (temp == 0x14EC) || (temp == 0x14F0)) { + ActorCutscene_Stop(this->unk_282[this->unk_290]); + this->unk_290 = 1; + ActorCutscene_SetIntentToPlay(this->unk_282[this->unk_290]); + this->actionFunc = func_80B10DAC; + } + } + } +} + +void func_80B11048(EnGb2* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + this->actor.flags &= ~0x10000; + func_801518B0(globalCtx, this->unk_26E, &this->actor); + this->actionFunc = func_80B10DAC; + } else if (this->actor.xzDistToPlayer < 300.0f) { + this->actor.flags |= 0x10000; + func_800B8614(&this->actor, globalCtx, 200.0f); + } +} + +void func_80B110F8(EnGb2* this, GlobalContext* globalCtx) { + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + if (this->unk_26C & 2) { + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_26C &= ~2; + this->actionFunc = func_80B10A48; + } else { + this->unk_26E = func_80B0F97C(this); + func_801518B0(globalCtx, this->unk_26E, &this->actor); + } + } +} + +void func_80B111AC(EnGb2* this, GlobalContext* globalCtx) { + s32 index; + + if (globalCtx->roomCtx.currRoom.num == 1) { + return; + } + + switch (globalCtx->roomCtx.currRoom.num) { + case 2: + index = 1; + break; + + case 3: + case 4: + index = 2; + break; + + case 5: + index = 3; + break; + + default: + index = 0; + } + + this->actor.world.pos.x = D_80B11A00[index][0]; + this->actor.world.pos.y = D_80B11A00[index][1]; + this->actor.world.pos.z = D_80B11A00[index][2]; + this->actor.world.rot.y = D_80B11A00[index][3] * 182.04445f; + this->actor.shape.rot.y = this->actor.world.rot.y; + this->actionFunc = func_80B11268; +} + +void func_80B11268(EnGb2* this, GlobalContext* globalCtx) { + if (globalCtx->roomCtx.currRoom.num == 1) { + this->unk_290 = 0; + this->unk_282[0] = this->actor.cutscene; + if (Actor_GetRoomCleared(globalCtx, 2) && Actor_GetRoomCleared(globalCtx, 3) && + Actor_GetRoomCleared(globalCtx, 4) && Actor_GetRoomCleared(globalCtx, 5)) { + this->unk_28A = 0xFF; + this->unk_26C &= ~0x100; + this->actor.flags |= 1; + this->actor.draw = EnGb2_Draw; + this->unk_26E = 0x14F9; + this->actionFunc = func_80B11048; + } else { + this->actionFunc = func_80B111AC; + } + } +} + +void func_80B11344(EnGb2* this, GlobalContext* globalCtx) { + if (gSaveContext.rupeeAccumulator == 0) { + func_80B0FE18(globalCtx); + } +} + +static InitChainEntry sInitChain[] = { ICHAIN_U8(targetMode, 4, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 2200, ICHAIN_STOP), }; -#endif +void EnGb2_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnGb2* this = THIS; -extern ColliderCylinderInit D_80B11A40; -extern InitChainEntry D_80B11AC4[]; + if (func_80B0F660(this, globalCtx)) { + Actor_MarkForDeath(&this->actor); + return; + } -extern UNK_TYPE D_0600049C; + this->actor.room = -1; + Actor_ProcessInitChain(&this->actor, sInitChain); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_ps_Skel_007230, &object_ps_Anim_00049C, this->jointTable, + this->morphTable, 12); + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 35.0f); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinderType1(globalCtx, &this->collider, &this->actor, &sCylinderInit); + Actor_SetScale(&this->actor, 0.01f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0F5E0.s") + switch (ENGB2_GET_7(&this->actor)) { + case ENGB2_7_0: + if (gSaveContext.weekEventReg[54] & 0x80) { + Actor_MarkForDeath(&this->actor); + } else if (gSaveContext.weekEventReg[52] & 0x20) { + Actor_MarkForDeath(&this->actor); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0F660.s") + if (gSaveContext.entranceIndex == 0x9C10) { + func_800FE484(); + this->actionFunc = func_80B10240; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0F6DC.s") + this->unk_28A = 255; + this->actor.flags |= 0x10; + this->actor.flags |= 0x2000000; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0F728.s") + if (gSaveContext.eventInf[4] & 0x40) { + func_80B0F728(this, globalCtx); + } else { + func_80B0FBF0(this, globalCtx); + func_80B0F6DC(this); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0F7FC.s") + case ENGB2_7_1: + if ((globalCtx->curSpawn == 1) || (gSaveContext.weekEventReg[80] & 0x80)) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0F8F8.s") + if (Flags_GetSwitch(globalCtx, ENGB2_GET_7F8(thisx))) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0F97C.s") + this->unk_28A = 255; + func_80B0FA04(this); + this->unk_28C = Player_GetMask(globalCtx); + this->actionFunc = func_80B10B5C; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0FA04.s") + case ENGB2_7_2: + this->unk_290 = 0; + this->unk_282[0] = this->actor.cutscene; + if (Flags_GetSwitch(globalCtx, ENGB2_GET_7F8(thisx))) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0FA48.s") + if (Actor_GetRoomCleared(globalCtx, 2) && Actor_GetRoomCleared(globalCtx, 3) && + Actor_GetRoomCleared(globalCtx, 4) && Actor_GetRoomCleared(globalCtx, 5)) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0FB24.s") + if (gSaveContext.weekEventReg[76] & 0x80) { + this->actor.draw = NULL; + this->unk_26C |= 0x100; + this->actor.flags &= ~1; + this->actionFunc = func_80B111AC; + } else { + this->unk_28A = 255; + this->unk_26E = 0x14F5; + this->actionFunc = func_80B11048; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0FBF0.s") + default: + Actor_MarkForDeath(&this->actor); + return; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0FD8C.s") +void EnGb2_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnGb2* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0FE18.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0FE7C.s") +void EnGb2_Update(Actor* thisx, GlobalContext* globalCtx) { + EnGb2* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0FEBC.s") + SkelAnime_Update(&this->skelAnime); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B0FFA8.s") + this->actionFunc(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B10240.s") + if (!(this->unk_26C & 0x100)) { + func_80B0F5E0(this, globalCtx); + } + func_800E9250(globalCtx, &this->actor, &this->unk_270, &this->unk_276, this->actor.focus.pos); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B10344.s") +s32 EnGb2_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, + Gfx** gfx) { + EnGb2* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B10584.s") + if (limbIndex == 7) { + limbIndex = limbIndex; + Matrix_RotateY(this->unk_270.y, MTXMODE_APPLY); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B10634.s") + if (limbIndex == 1) { + *dList = NULL; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B10868.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B10924.s") +void EnGb2_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { + EnGb2* this = THIS; + Vec3f sp18 = { 2400.0f, 0.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B109DC.s") + if (limbIndex == 7) { + Matrix_MultiplyVector3fByState(&sp18, &this->actor.focus.pos); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B10A48.s") +void EnGb2_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnGb2* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B10B5C.s") + OPEN_DISPS(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B10DAC.s") + if (this->unk_28A == 255) { + func_8012C28C(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B10E98.s") + gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 255); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B11048.s") + Scene_SetRenderModeXlu(globalCtx, 0, 1); + POLY_OPA_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnGb2_OverrideLimbDraw, EnGb2_PostLimbDraw, + &this->actor, POLY_OPA_DISP); + } else { + func_8012C2DC(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B110F8.s") + gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, this->unk_28A); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B111AC.s") + Scene_SetRenderModeXlu(globalCtx, 1, 2); + POLY_XLU_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnGb2_OverrideLimbDraw, EnGb2_PostLimbDraw, + &this->actor, POLY_XLU_DISP); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B11268.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B11344.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/EnGb2_Init.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/EnGb2_Destroy.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/EnGb2_Update.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B1179C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/func_80B117FC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gb2/EnGb2_Draw.s") + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Gb2/z_en_gb2.h b/src/overlays/actors/ovl_En_Gb2/z_en_gb2.h index 17274b82f..c054c4ed2 100644 --- a/src/overlays/actors/ovl_En_Gb2/z_en_gb2.h +++ b/src/overlays/actors/ovl_En_Gb2/z_en_gb2.h @@ -7,11 +7,35 @@ struct EnGb2; typedef void (*EnGb2ActionFunc)(struct EnGb2*, GlobalContext*); +#define ENGB2_GET_7(thisx) ((thisx)->params & 7) +#define ENGB2_GET_7F8(thisx) (((thisx)->params & 0x7F8) >> 3) + +enum { + /* 0 */ ENGB2_7_0, + /* 1 */ ENGB2_7_1, + /* 2 */ ENGB2_7_2, +}; + typedef struct EnGb2 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xD4]; - /* 0x0218 */ EnGb2ActionFunc actionFunc; - /* 0x021C */ char unk_21C[0x78]; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[12]; + /* 0x1D0 */ Vec3s morphTable[12]; + /* 0x218 */ EnGb2ActionFunc actionFunc; + /* 0x21C */ ColliderCylinder collider; + /* 0x268 */ Actor* unk_268; + /* 0x26C */ u16 unk_26C; + /* 0x26E */ u16 unk_26E; + /* 0x270 */ Vec3s unk_270; + /* 0x276 */ Vec3s unk_276; + /* 0x27C */ s16 unk_27C; + /* 0x27E */ s16 unk_27E; + /* 0x280 */ s16 unk_280; + /* 0x282 */ s16 unk_282[3]; + /* 0x288 */ s16 unk_288; + /* 0x28A */ u8 unk_28A; + /* 0x28C */ s32 unk_28C; + /* 0x290 */ s16 unk_290; } EnGb2; // size = 0x294 extern const ActorInit En_Gb2_InitVars; diff --git a/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c b/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c index 8125c9c33..2f3209e97 100644 --- a/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c +++ b/src/overlays/actors/ovl_En_Ge1/z_en_ge1.c @@ -1,7 +1,7 @@ /* * File: z_en_ge1.c * Overlay: ovl_En_Ge1 - * Description: + * Description: White-clad Gerudo Pirate */ #include "z_en_ge1.h" diff --git a/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c b/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c index 6e3b7ac6b..d511788ab 100644 --- a/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c +++ b/src/overlays/actors/ovl_En_Ge2/z_en_ge2.c @@ -1,7 +1,7 @@ /* * File: z_en_ge2.c * Overlay: ovl_En_Ge2 - * Description: Patrolling Pirate + * Description: Purple-clad Gerudo Pirate */ #include "z_en_ge2.h" diff --git a/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c b/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c index 9e891f708..7c0bcd71f 100644 --- a/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c +++ b/src/overlays/actors/ovl_En_Ge3/z_en_ge3.c @@ -1,7 +1,7 @@ /* * File: z_en_ge3.c * Overlay: ovl_En_Ge3 - * Description: + * Description: Aviel */ #include "z_en_ge3.h" diff --git a/src/overlays/actors/ovl_En_Geg/z_en_geg.c b/src/overlays/actors/ovl_En_Geg/z_en_geg.c index 260f3d74e..e31d3d50a 100644 --- a/src/overlays/actors/ovl_En_Geg/z_en_geg.c +++ b/src/overlays/actors/ovl_En_Geg/z_en_geg.c @@ -5,6 +5,11 @@ */ #include "z_en_geg.h" +#include "overlays/actors/ovl_En_Bom/z_en_bom.h" +#include "objects/object_oF1d_map/object_oF1d_map.h" +#include "objects/object_taisou/object_taisou.h" +#include "objects/object_hakugin_demo/object_hakugin_demo.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x00000019 @@ -31,7 +36,6 @@ void func_80BB32AC(EnGeg* this, GlobalContext* globalCtx); void func_80BB3318(EnGeg* this, GlobalContext* globalCtx); void func_80BB347C(EnGeg* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Geg_InitVars = { ACTOR_EN_GEG, ACTORCAT_NPC, @@ -44,25 +48,49 @@ const ActorInit En_Geg_InitVars = { (ActorFunc)EnGeg_Draw, }; -// static ColliderSphereInit sSphereInit = { -static ColliderSphereInit D_80BB3E70 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_SPHERE, }, - { ELEMTYPE_UNK0, { 0x20000000, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderSphereInit sSphereInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_SPHERE, + }, + { + ELEMTYPE_UNK0, + { 0x20000000, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 0 }, 100 }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BB3E9C = { - { COLTYPE_HIT1, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK1, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_HIT1, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK1, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 0, 0, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80BB3EC8 = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -// static DamageTable sDamageTable = { -static DamageTable D_80BB3ED4 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(1, 0x0), /* Deku Stick */ DMG_ENTRY(1, 0x0), /* Horse trample */ DMG_ENTRY(1, 0x0), @@ -97,87 +125,953 @@ static DamageTable D_80BB3ED4 = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -#endif +static ActorAnimationEntryS sAnimations[] = { + { &object_oF1d_map_Anim_011D98, 1.0f, 0, -1, 0, 0 }, { &object_oF1d_map_Anim_011D98, 1.0f, 0, -1, 0, -4 }, + { &object_oF1d_map_Anim_012DE0, 2.0f, 0, -1, 2, 0 }, { &object_oF1d_map_Anim_012DE0, 2.0f, 0, -1, 2, -4 }, + { &object_oF1d_map_Anim_012DE0, -2.0f, 0, -1, 2, -4 }, { &object_oF1d_map_Anim_003E28, 1.0f, 0, -1, 0, 0 }, + { &object_oF1d_map_Anim_003E28, 1.0f, 0, -1, 0, -4 }, { &object_oF1d_map_Anim_0039D8, 1.0f, 0, -1, 2, -4 }, + { &object_taisou_Anim_0016C8, 1.0f, 0, -1, 0, 0 }, { &object_taisou_Anim_004DD4, 1.0f, 0, -1, 0, 0 }, + { &object_taisou_Anim_00283C, 1.0f, 0, -1, 0, 0 }, { &object_taisou_Anim_007764, 1.0f, 0, -1, 0, 0 }, + { &object_taisou_Anim_005EE0, 1.0f, 0, -1, 0, 0 }, { &object_taisou_Anim_002C48, 1.0f, 0, -1, 0, 0 }, + { &object_taisou_Anim_0031D8, 1.0f, 0, -1, 0, 0 }, { &object_taisou_Anim_005790, 1.0f, 0, -1, 0, 0 }, + { &object_oF1d_map_Anim_003650, 1.0f, 0, -1, 0, 0 }, { &object_hakugin_demo_Anim_002704, 1.0f, 0, -1, 2, 0 }, + { &object_hakugin_demo_Anim_003378, 1.0f, 0, -1, 0, -4 }, { &object_oF1d_map_Anim_0135E8, 1.0f, 0, -1, 2, 0 }, + { &object_oF1d_map_Anim_014CE0, 1.0f, 0, -1, 0, 0 }, +}; -extern ColliderSphereInit D_80BB3E70; -extern ColliderCylinderInit D_80BB3E9C; -extern CollisionCheckInfoInit2 D_80BB3EC8; -extern DamageTable D_80BB3ED4; +u16 func_80BB16D0(EnGeg* this) { + switch (this->unk_496) { + case 0xD5E: + return 0xD5F; + case 0xD5F: + return 0xD60; + case 0xD60: + return 0xD61; + case 0xD62: + return 0xD63; + case 0xD64: + return 0xD65; + case 0xD66: + return 0xD67; + case 0xD67: + return 0xD68; + case 0xD68: + return 0xD69; + case 0xD6A: + return 0xD6B; + case 0xD6B: + return 0xD6C; + case 0xD6C: + return 0xD6D; + case 0xD6E: + return 0xD6F; + case 0xD70: + return 0xD71; + case 0xD71: + return 0xD72; + case 0xD73: + return 0xD74; + case 0xD74: + return 0xD75; + case 0xD89: + return 0xD8A; + } + return 0; +} -extern UNK_TYPE D_06004DB0; -extern UNK_TYPE D_060091A8; -extern UNK_TYPE D_06012DE0; +void func_80BB178C(EnGeg* this, GlobalContext* globalCtx) { + Vec3f sp34 = this->actor.world.pos; + Collider* collider; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB16D0.s") + if (this->unk_230 & 1) { + this->colliderSphere.dim.worldSphere.center.x = sp34.x; + this->colliderSphere.dim.worldSphere.center.y = sp34.y; + this->colliderSphere.dim.worldSphere.center.y += (s16)this->actor.shape.yOffset; + this->colliderSphere.dim.worldSphere.center.z = sp34.z; + this->colliderSphere.dim.modelSphere.radius = 20; + this->colliderSphere.dim.worldSphere.radius = + this->colliderSphere.dim.modelSphere.radius * this->colliderSphere.dim.scale; + collider = &this->colliderSphere.base; + } else { + f32 radius = 24.0f; + f32 height = 62.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB178C.s") + this->colliderCylinder.dim.pos.x = sp34.x; + this->colliderCylinder.dim.pos.y = sp34.y; + this->colliderCylinder.dim.pos.z = sp34.z; + this->colliderCylinder.dim.radius = radius; + this->colliderCylinder.dim.height = height; + collider = &this->colliderCylinder.base; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB18FC.s") + if (collider != NULL) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, collider); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 5); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB19C0.s") +s32 func_80BB18FC(EnGeg* this, Actor* actor) { + if (actor->bgCheckFlags & 1) { + f32 sp24 = Math_Vec3f_DistXZ(&this->actor.world.pos, &actor->world.pos); + f32 sp20 = Math_Vec3f_DiffY(&this->actor.world.pos, &actor->world.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB1B14.s") + if ((sp24 < 150.0f) && (fabsf(sp20) < 5.0f)) { + this->unk_230 |= 0x20; + actor->speedXZ = 0.0f; + actor->velocity.y = 0.0f; + this->actor.child = actor; + actor->parent = &this->actor; + return true; + } + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB1C1C.s") +Vec3f* func_80BB19C0(Vec3f* arg0, EnGeg* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f sp40; + Vec3f sp34; + s16 sp32 = player->actor.world.rot.y + 0x4000; + s16 sp30; + f32 sp2C; + f32 sp28; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB1C8C.s") + sp40.x = (Math_SinS(sp32) * 50.0f) + player->actor.world.pos.x; + sp40.y = player->actor.world.pos.y; + sp40.z = (Math_CosS(sp32) * 50.0f) + player->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB1D04.s") + sp2C = Math_Vec3f_DistXZ(&this->actor.world.pos, &sp40); + sp30 = player->actor.world.rot.y - 0x4000; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB1D64.s") + sp34.x = (Math_SinS(sp30) * 50.0f) + player->actor.world.pos.x; + sp34.y = player->actor.world.pos.y; + sp34.z = (Math_CosS(sp30) * 50.0f) + player->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB1FCC.s") + if (Math_Vec3f_DistXZ(&this->actor.world.pos, &sp34) < sp2C) { + // clang-format off + *arg0 = sp40; return arg0; + // clang-format on + } else { + *arg0 = sp34; + } + return arg0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB2020.s") +u8 func_80BB1B14(EnGeg* this, GlobalContext* globalCtx) { + Actor* explosive; + Actor* mm = SubS_FindActor(globalCtx, NULL, ACTORCAT_ITEMACTION, ACTOR_EN_MM); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB2088.s") + if (mm != NULL) { + this->unk_4B0 = Math_Vec3f_Yaw(&this->actor.world.pos, &mm->world.pos); + if (func_80BB18FC(this, mm)) { + return 1; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB217C.s") + explosive = globalCtx->actorCtx.actorList[ACTORCAT_EXPLOSIVES].first; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB221C.s") + while (explosive != NULL) { + if ((explosive->id == ACTOR_EN_BOM) && func_80BB18FC(this, explosive)) { + this->unk_4B0 = Math_Vec3f_Yaw(&this->actor.world.pos, &explosive->world.pos); + if (this->unk_230 & 0x200) { + return 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB2520.s") + if (((EnBom*)explosive)->unk_1F9 == 0) { + return 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB26EC.s") + return 3; + } + explosive = explosive->next; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB27D4.s") + this->unk_230 &= ~0x200; + return 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB2944.s") +void func_80BB1C1C(EnGeg* this) { + u16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB2A54.s") + this->unk_49C[0] = this->actor.cutscene; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB2B1C.s") + for (i = 1; i < ARRAY_COUNT(this->unk_49C); i++) { + this->unk_49C[i] = ActorCutscene_GetAdditionalCutscene(this->unk_49C[i - 1]); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB2E00.s") +void func_80BB1C8C(EnGeg* this) { + if (DECR(this->unk_240) == 0) { + this->unk_23E++; + if (this->unk_23E >= 3) { + this->unk_240 = Rand_S16Offset(30, 30); + this->unk_23E = 0; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB2F7C.s") +void func_80BB1D04(EnGeg* this) { + f32 temp; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB30B4.s") + if (this->unk_230 & 1) { + temp = this->actor.shape.yOffset; + } else { + temp = 58.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB31B8.s") + this->actor.focus.pos.x = this->actor.world.pos.x; + this->actor.focus.pos.y = temp + this->actor.world.pos.y; + this->actor.focus.pos.z = this->actor.world.pos.z; + this->actor.focus.rot.x = this->actor.world.rot.x; + this->actor.focus.rot.y = this->actor.world.rot.y; + this->actor.focus.rot.z = this->actor.world.rot.z; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB32AC.s") +s32 func_80BB1D64(EnGeg* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f sp40; + Vec3f sp34; + s16 yaw = (this->actor.yawTowardsPlayer - this->unk_46E) - this->actor.shape.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB3318.s") + Math_SmoothStepToS(&this->unk_46A, yaw, 4, 0x2AA8, 1); + this->unk_46A = CLAMP(this->unk_46A, -0x1FFE, 0x1FFE); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB347C.s") + yaw = (this->actor.yawTowardsPlayer - this->unk_46A) - this->actor.shape.rot.y; + Math_SmoothStepToS(&this->unk_46E, yaw, 4, 0x2AA8, 1); + this->unk_46E = CLAMP(this->unk_46E, -0x1C70, 0x1C70); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/EnGeg_Init.s") + if (this->unk_230 & 0x20) { + sp40 = player->actor.world.pos; + } else { + sp40 = player->actor.world.pos; + sp40.y = player->bodyPartsPos[7].y + 3.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/EnGeg_Destroy.s") + sp34 = this->actor.world.pos; + sp34.y += 70.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/EnGeg_Update.s") + yaw = Math_Vec3f_Pitch(&sp34, &sp40); + Math_SmoothStepToS(&this->unk_468, yaw - this->unk_46C, 4, 0x2AA8, 1); + this->unk_468 = CLAMP(this->unk_468, -0x1C70, 0x1C70); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB3728.s") + yaw = Math_Vec3f_Pitch(&sp34, &sp40); + Math_SmoothStepToS(&this->unk_46C, yaw - this->unk_468, 4, 0x2AA8, 1); + this->unk_46C = CLAMP(this->unk_46C, -0x1C70, 0x1C70); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB3860.s") + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB387C.s") +void func_80BB1FCC(EnGeg* this, GlobalContext* globalCtx) { + gSegments[6] = PHYSICAL_TO_VIRTUAL2(globalCtx->objectCtx.status[this->unk_248].segment); + SkelAnime_Update(&this->skelAnime); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB39F8.s") +void func_80BB2020(EnGeg* this, GlobalContext* globalCtx) { + gSegments[6] = PHYSICAL_TO_VIRTUAL2(globalCtx->objectCtx.status[this->unk_248].segment); + func_8013BC6C(&this->skelAnime, sAnimations, this->unk_4AC); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB3BE0.s") +s32 func_80BB2088(EnGeg* this, GlobalContext* globalCtx) { + if (DECR(this->unk_242) != 0) { + this->unk_468 = 0; + this->unk_46A = 0; + this->unk_230 &= ~2; + this->unk_46C = 0; + this->unk_46E = 0; + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/func_80BB3CB4.s") + if (Actor_IsActorFacingLinkAndWithinRange(&this->actor, 300.0f, 0x7FF8) && + ((this->unk_4AC == 5) || ((this->unk_4AC == 13) && (this->unk_496 == 0xD69)))) { + this->unk_230 |= 2; + func_80BB1D64(this, globalCtx); + } else { + if (this->unk_230 & 2) { + this->unk_242 = 20; + } + this->unk_230 &= ~2; + this->unk_468 = 0; + this->unk_46A = 0; + this->unk_46C = 0; + this->unk_46E = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Geg/EnGeg_Draw.s") + return true; +} + +void func_80BB217C(EnGeg* this, GlobalContext* globalCtx) { + if (Object_IsLoaded(&globalCtx->objectCtx, this->unk_248)) { + this->unk_4AC = 5; + func_80BB2020(this, globalCtx); + Actor_SetScale(&this->actor, 0.01f); + this->unk_230 = 0; + this->actor.shape.shadowScale = 20.0f; + this->actor.gravity = -1.0f; + func_80BB1C1C(this); + this->actionFunc = func_80BB221C; + this->actor.targetMode = 3; + } +} + +void func_80BB221C(EnGeg* this, GlobalContext* globalCtx) { + u8 sp27 = func_80BB1B14(this, globalCtx); + + if (sp27 != 0) { + this->unk_230 &= ~8; + if (func_800B84D0(&this->actor, globalCtx) && (this->unk_230 & 4)) { + if (sp27 == 1) { + this->unk_496 = 0xD66; + this->unk_49A = this->unk_49C[3]; + } else if (sp27 == 2) { + this->unk_496 = 0xD64; + this->unk_49A = this->unk_49C[2]; + this->unk_230 &= ~4; + } else if (sp27 == 3) { + this->unk_230 |= 0x200; + this->unk_496 = 0xD64; + this->unk_49A = this->unk_49C[2]; + this->unk_230 &= ~4; + } + func_801518B0(globalCtx, this->unk_496, &this->actor); + this->actionFunc = func_80BB2520; + this->actor.flags &= ~0x10000; + } else if (this->actor.xzDistToPlayer < 300.0f) { + this->unk_230 |= 4; + this->actor.flags |= 0x10000; + func_800B8614(&this->actor, globalCtx, 300.0f); + } + } else { + this->unk_230 &= ~4; + if (gSaveContext.weekEventReg[35] & 0x40) { + if (func_800B84D0(&this->actor, globalCtx) && (this->unk_230 & 8)) { + this->unk_496 = 0xD62; + func_801518B0(globalCtx, this->unk_496, &this->actor); + this->unk_230 &= ~8; + this->actionFunc = func_80BB27D4; + } else if ((this->actor.xzDistToPlayer < 300.0f) && this->actor.isTargeted) { + func_800B8614(&this->actor, globalCtx, 300.0f); + this->unk_230 |= 8; + } + } else if (func_800B84D0(&this->actor, globalCtx) && (this->unk_230 & 8)) { + gSaveContext.weekEventReg[35] |= 0x40; + this->unk_496 = 0xD5E; + this->unk_49A = this->unk_49C[0]; + func_801518B0(globalCtx, this->unk_496, &this->actor); + this->actionFunc = func_80BB2520; + this->unk_230 &= ~8; + this->actor.flags &= ~0x10000; + } else if (this->actor.xzDistToPlayer < 300.0f) { + this->actor.flags |= 0x10000; + func_800B8614(&this->actor, globalCtx, 300.0f); + this->unk_230 |= 8; + } + } +} + +void func_80BB2520(EnGeg* this, GlobalContext* globalCtx) { + if (this->unk_230 & 0x10) { + ActorCutscene_Stop(this->unk_498); + this->unk_230 &= ~0x10; + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + } + this->unk_498 = this->unk_49A; + ActorCutscene_SetIntentToPlay(this->unk_498); + return; + } + + if (ActorCutscene_GetCanPlayNext(this->unk_498)) { + ActorCutscene_StartAndSetFlag(this->unk_498, &this->actor); + this->unk_230 |= 0x10; + + switch (this->unk_496) { + case 0xD5E: + case 0xD5F: + this->actionFunc = func_80BB26EC; + break; + + case 0xD64: + this->unk_230 &= ~0x20; + this->actionFunc = func_80BB2A54; + break; + + case 0xD66: + this->unk_248 = Object_GetIndex(&globalCtx->objectCtx, OBJECT_OF1D_MAP); + if (this->unk_248 >= 0) { + this->unk_4AC = 19; + func_80BB2020(this, globalCtx); + } + this->unk_230 |= 0x20; + this->actionFunc = func_80BB2944; + break; + + case 0xD67: + this->unk_498 = this->unk_49C[5]; + this->actionFunc = func_80BB2B1C; + break; + + case 0xD69: + case 0xD72: + case 0xD75: + case 0xD8B: + this->unk_248 = Object_GetIndex(&globalCtx->objectCtx, OBJECT_OF1D_MAP); + if (this->unk_248 >= 0) { + this->unk_4AC = 4; + func_80BB2020(this, globalCtx); + } + this->actionFunc = func_80BB2E00; + break; + } + } else { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + } + this->unk_498 = this->unk_49A; + ActorCutscene_SetIntentToPlay(this->unk_498); + } +} + +void func_80BB26EC(EnGeg* this, GlobalContext* globalCtx) { + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + switch (this->unk_496) { + case 0xD5E: + this->unk_49A = this->unk_49C[1]; + this->actionFunc = func_80BB2520; + break; + + case 0xD61: + ActorCutscene_Stop(this->unk_498); + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_230 &= ~0x10; + this->actionFunc = func_80BB221C; + return; + } + + this->unk_496 = func_80BB16D0(this); + func_801518B0(globalCtx, this->unk_496, &this->actor); + } +} + +void func_80BB27D4(EnGeg* this, GlobalContext* globalCtx) { + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + switch (this->unk_496) { + case 0xD63: + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->actionFunc = func_80BB221C; + break; + + case 0xD69: + this->unk_49A = this->unk_49C[6]; + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->actionFunc = func_80BB2520; + break; + + case 0xD6D: + case 0xD6F: + case 0xD8A: + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->actionFunc = func_80BB31B8; + break; + + case 0xD72: + case 0xD75: + case 0xD8B: + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_230 &= ~0x10; + this->unk_49A = this->unk_49C[7]; + this->actionFunc = func_80BB2520; + break; + + default: + this->unk_496 = func_80BB16D0(this); + func_801518B0(globalCtx, this->unk_496, &this->actor); + break; + } + } +} + +void func_80BB2944(EnGeg* this, GlobalContext* globalCtx) { + u8 sp27 = func_80152498(&globalCtx->msgCtx); + s16 curFrame = this->skelAnime.curFrame; + s16 lastFrame = Animation_GetLastFrame(sAnimations[this->unk_4AC].animationSeg); + + if (this->unk_4AC == 19) { + if (curFrame == lastFrame) { + this->unk_4AC = 6; + func_80BB2020(this, globalCtx); + } + } else if ((sp27 == 5) && func_80147624(globalCtx)) { + if (this->unk_496 == 0xD67) { + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->unk_49A = this->unk_49C[4]; + this->actionFunc = func_80BB2520; + } else { + this->unk_496 = func_80BB16D0(this); + func_80151938(globalCtx, this->unk_496); + } + } +} + +void func_80BB2A54(EnGeg* this, GlobalContext* globalCtx) { + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + if (this->unk_496 == 0xD65) { + ActorCutscene_Stop(this->unk_498); + this->unk_230 &= ~0x10; + this->unk_244 = 65; + globalCtx->msgCtx.unk11F22 = 0x43; + globalCtx->msgCtx.unk12023 = 4; + this->actionFunc = func_80BB347C; + } else { + this->unk_496 = func_80BB16D0(this); + func_801518B0(globalCtx, this->unk_496, &this->actor); + } + } +} + +void func_80BB2B1C(EnGeg* this, GlobalContext* globalCtx) { + Vec3f sp74; + f32 temp_f20; + s16 i; + f32 sp68; + + this->actor.child->world.pos = this->unk_4B4; + this->actor.child->shape.rot = this->actor.shape.rot; + + if (ActorCutscene_GetCurrentIndex() != this->unk_49C[4]) { + if (ActorCutscene_GetCanPlayNext(this->unk_498)) { + gSaveContext.weekEventReg[37] |= 8; + if (this->actor.child != NULL) { + Actor_MarkForDeath(this->actor.child); + } + this->unk_230 |= 0x10; + ActorCutscene_StartAndSetFlag(this->unk_498, &this->actor); + this->unk_496 = 0xD68; + func_80151938(globalCtx, this->unk_496); + this->unk_248 = Object_GetIndex(&globalCtx->objectCtx, OBJECT_TAISOU); + if (this->unk_248 >= 0) { + this->unk_4AC = 13; + func_80BB2020(this, globalCtx); + } + this->actionFunc = func_80BB27D4; + } else { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + } + ActorCutscene_SetIntentToPlay(this->unk_498); + } + } else { + temp_f20 = this->unk_4E0 * 0.005f; + sp68 = this->unk_4E0 * 0.07f; + + sp74.x = Rand_Centered() * temp_f20; + sp74.y = Rand_Centered() * temp_f20; + sp74.z = Rand_Centered() * temp_f20; + + this->actor.child->scale.x *= 0.98f; + this->actor.child->scale.y *= 0.98f; + this->actor.child->scale.z *= 0.98f; + + if (this->unk_4E0 > 70) { + for (i = 0; i < ARRAY_COUNT(this->unk_4C0); i++) { + this->unk_4C0[i].x *= temp_f20; + this->unk_4C0[i].y *= temp_f20; + this->unk_4C0[i].z *= temp_f20; + EffectSsHahen_Spawn(globalCtx, &this->unk_4B4, &this->unk_4C0[i], &sp74, 1, sp68, 1, 15, + gameplay_keep_DL_06AB30); + } + } + this->unk_4E0--; + } + func_8019F570(&this->actor.projectedPos, 1); + func_8019F4AC(&this->actor.projectedPos, NA_SE_EN_GOLON_SIRLOIN_EAT - SFX_FLAG); +} + +void func_80BB2E00(EnGeg* this, GlobalContext* globalCtx) { + s16 sp2E = this->skelAnime.curFrame; + s16 sp2C = Animation_GetLastFrame(sAnimations[this->unk_4AC].animationSeg); + + if (this->unk_4AC == 2) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 5, 0x1000, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; + if (sp2E == sp2C) { + ActorCutscene_Stop(this->unk_498); + this->unk_4AC = 20; + func_80BB2020(this, globalCtx); + this->actionFunc = func_80BB30B4; + } else if (Animation_OnFrame(&this->skelAnime, 24.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_STAND_IMT); + } + } else if (this->unk_4AC == 4) { + if (Animation_OnFrame(&this->skelAnime, 0.0f)) { + this->unk_230 |= 1; + this->actor.shape.yOffset = 14.0f; + if (this->unk_496 == 0xD69) { + func_80BB19C0(&this->unk_4E4, this, globalCtx); + this->actionFunc = func_80BB2F7C; + } else { + this->actionFunc = func_80BB3318; + } + } else if (Animation_OnFrame(&this->skelAnime, 24.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_SIT_IMT); + } + } +} + +void func_80BB2F7C(EnGeg* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->actor.world.rot.y, Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_4E4), 4, 1000, 1); + this->actor.shape.rot.y = this->actor.world.rot.y; + + if ((this->actor.xzDistToPlayer < 150.0f) && (fabsf(this->actor.playerHeightRel) < 10.0f) && + (this->actor.bgCheckFlags & 1)) { + this->unk_4AC = 2; + this->actor.speedXZ = 0.0f; + this->unk_230 &= ~1; + this->actor.shape.yOffset = 0.0f; + func_80BB2020(this, globalCtx); + this->actionFunc = func_80BB2E00; + } else { + this->actor.speedXZ = 5.0f; + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + } + + if (this->actor.bgCheckFlags & 1) { + if (this->unk_230 & 0x80) { + func_800B9010(&this->actor, NA_SE_EN_GOLON_SIRLOIN_ROLL - SFX_FLAG); + } else { + this->unk_230 |= 0x80; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_EYEGOLE_ATTACK); + } + } +} + +void func_80BB30B4(EnGeg* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (func_800B84D0(&this->actor, globalCtx)) { + if (player->transformation == PLAYER_FORM_GORON) { + this->unk_496 = 0xD6A; + } else if (Player_GetMask(globalCtx) == PLAYER_MASK_DON_GERO) { + this->unk_496 = 0xD89; + } else { + this->unk_496 = 0xD6E; + } + func_801518B0(globalCtx, this->unk_496, &this->actor); + this->actionFunc = func_80BB27D4; + this->actor.flags &= ~0x10000; + } else if (this->actor.xzDistToPlayer < 150.0f) { + this->actor.flags |= 0x10000; + func_800B8614(&this->actor, globalCtx, 150.0f); + } +} + +void func_80BB31B8(EnGeg* this, GlobalContext* globalCtx) { + s32 getItemId = GI_MASK_DON_GERO; + + if (INV_CONTENT(ITEM_MASK_DON_GERO) == ITEM_MASK_DON_GERO) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_DON_GERO) { + this->unk_496 = 0xD8B; + getItemId = GI_RUPEE_PURPLE; + } else { + this->unk_496 = 0xD73; + getItemId = GI_RUPEE_PURPLE; + } + } else { + this->unk_496 = 0xD70; + } + + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + gSaveContext.weekEventReg[61] |= 1; + if (getItemId == GI_MASK_DON_GERO) { + this->unk_230 |= 0x40; + } + this->actionFunc = func_80BB32AC; + } else { + func_800B8A1C(&this->actor, globalCtx, getItemId, 300.0f, 300.0f); + } +} + +void func_80BB32AC(EnGeg* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + func_801518B0(globalCtx, this->unk_496, &this->actor); + this->actionFunc = func_80BB27D4; + } else { + func_800B85E0(&this->actor, globalCtx, 400.0f, -1); + } +} + +void func_80BB3318(EnGeg* this, GlobalContext* globalCtx) { + static Vec3f D_80BB4044[] = { + { -550.0f, 8.0f, 550.0f }, + { 220.0f, 43.0f, 525.0f }, + }; + s16 sp46; + f32 sp40; + + if (this->unk_4D8 < 2) { + sp46 = Math_Vec3f_Yaw(&this->actor.world.pos, &D_80BB4044[this->unk_4D8]); + sp40 = Math_Vec3f_DistXZ(&this->actor.world.pos, &D_80BB4044[this->unk_4D8]); + Math_SmoothStepToS(&this->actor.world.rot.y, sp46, 4, 1000, 1); + if (sp40 < 20.0f) { + this->unk_4D8++; + } + this->actor.shape.rot.y = this->actor.world.rot.y; + func_800AE930(&globalCtx->colCtx, Effect_GetByIndex(this->unk_4DC), &this->actor.world.pos, 18.0f, + this->actor.shape.rot.y, this->actor.floorPoly, this->actor.floorBgId); + } + + if (ActorCutscene_GetCurrentIndex() != this->unk_49C[7]) { + func_800AEF44(Effect_GetByIndex(this->unk_4DC)); + Actor_MarkForDeath(&this->actor); + } else { + Math_ApproachF(&this->actor.speedXZ, 10.0f, 0.2f, 1.0f); + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + } + + func_800B9010(&this->actor, NA_SE_EN_GOLON_SIRLOIN_ROLL - SFX_FLAG); +} + +void func_80BB347C(EnGeg* this, GlobalContext* globalCtx) { + if (DECR(this->unk_244) == 0) { + this->unk_244 = 65; + this->actionFunc = func_80BB221C; + } +} + +void EnGeg_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnGeg* this = THIS; + s32 pad2; + s32 sp34[] = { 0x3E, 0xF64 }; + + if (gSaveContext.weekEventReg[61] & 1) { + Actor_MarkForDeath(&this->actor); + return; + } + + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 0.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_oF1d_map_Skel_011AC8, &object_oF1d_map_Anim_012DE0, + this->jointTable, this->morphTable, 18); + + Collider_InitCylinder(globalCtx, &this->colliderCylinder); + Collider_SetCylinder(globalCtx, &this->colliderCylinder, &this->actor, &sCylinderInit); + Collider_InitSphere(globalCtx, &this->colliderSphere); + Collider_SetSphere(globalCtx, &this->colliderSphere, &this->actor, &sSphereInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + + if (this->actor.update != NULL) { + this->unk_248 = Object_GetIndex(&globalCtx->objectCtx, OBJECT_OF1D_MAP); + if (this->unk_248 < 0) { + Actor_MarkForDeath(&this->actor); + } + } + + Effect_Add(globalCtx, &this->unk_4DC, 4, 0, 0, &sp34); + thisx->draw = NULL; + this->unk_4E0 = 100; + this->actor.draw = EnGeg_Draw; + this->actionFunc = func_80BB217C; +} + +void EnGeg_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnGeg* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->colliderCylinder); + Collider_DestroySphere(globalCtx, &this->colliderSphere); + Effect_Destroy(globalCtx, this->unk_4DC); +} + +void EnGeg_Update(Actor* thisx, GlobalContext* globalCtx) { + EnGeg* this = THIS; + + this->actionFunc(this, globalCtx); + func_80BB1FCC(this, globalCtx); + func_80BB2088(this, globalCtx); + func_80BB1C8C(this); + func_8013D9C8(globalCtx, &this->unk_238, &this->unk_232, 3); + func_80BB1D04(this); + func_80BB178C(this, globalCtx); +} + +s32 func_80BB3728(s16 arg0, s16 arg1, Vec3f* arg2, Vec3s* arg3, s32 arg4, s32 arg5) { + Vec3f sp7C; + Vec3f sp70 = gZeroVec3f; + Vec3s sp68; + MtxF sp28; + + Matrix_MultiplyVector3fByState(&sp70, &sp7C); + Matrix_CopyCurrentState(&sp28); + func_8018219C(&sp28, &sp68, 0); + *arg2 = sp7C; + + if (!arg4 && !arg5) { + arg3->x = sp68.x; + arg3->y = sp68.y; + arg3->z = sp68.z; + return true; + } + + if (arg5) { + sp68.z = arg0; + sp68.y = arg1; + } + Math_SmoothStepToS(&arg3->x, sp68.x, 3, 0x2AA8, 0xB6); + Math_SmoothStepToS(&arg3->y, sp68.y, 3, 0x2AA8, 0xB6); + Math_SmoothStepToS(&arg3->z, sp68.z, 3, 0x2AA8, 0xB6); + + return true; +} + +s32 EnGeg_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + return false; +} + +void EnGeg_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Vec3f D_80BB407C = { -1500.0f, 1500.0f, 0.0f }; + EnGeg* this = THIS; + Vec3f sp38 = { 1.0f, 5.0f, -0.5f }; + Vec3f sp2C = { -1.0f, 5.0f, -0.5f }; + + if (limbIndex == 17) { + if (!(this->unk_230 & 0x40)) { + func_8012C28C(globalCtx->state.gfxCtx); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gSPDisplayList(POLY_OPA_DISP++, object_oF1d_map_DL_004DB0); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + + sp38.x += Rand_Centered(); + sp38.y += 2.0f * Rand_Centered(); + sp38.z += Rand_Centered(); + + sp2C.x += Rand_Centered(); + sp2C.y += 2.0f * Rand_Centered(); + sp2C.z += Rand_Centered(); + + Matrix_MultiplyVector3fByState(&D_80BB407C, &this->unk_4B4); + Matrix_StatePush(); + Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_MultiplyVector3fByState(&sp38, &this->unk_4C0[0]); + Matrix_MultiplyVector3fByState(&sp2C, &this->unk_4C0[1]); + Matrix_StatePop(); + } +} + +void EnGeg_UnkDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnGeg* this = THIS; + s32 phi_v0; + s32 phi_v1; + + switch (limbIndex) { + case 17: + if (this->unk_230 & 2) { + phi_v1 = true; + } else { + phi_v1 = false; + } + + if (this->unk_242 != 0) { + phi_v0 = true; + } else { + phi_v0 = false; + } + + func_80BB3728(this->unk_468 + this->unk_46C + 0x4000, + this->unk_46A + this->unk_46E + this->actor.shape.rot.y + 0x4000, &this->unk_470, + &this->unk_47C, phi_v0, phi_v1); + Matrix_StatePop(); + Matrix_InsertTranslation(this->unk_470.x, this->unk_470.y, this->unk_470.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateY(this->unk_47C.y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->unk_47C.x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->unk_47C.z, MTXMODE_APPLY); + Matrix_StatePush(); + break; + + case 10: + if (this->unk_230 & 2) { + phi_v1 = true; + } else { + phi_v1 = false; + } + + if (this->unk_242 != 0) { + phi_v0 = true; + } else { + phi_v0 = false; + } + + func_80BB3728(this->unk_46C + 0x4000, this->unk_46E + this->actor.shape.rot.y + 0x4000, &this->unk_484, + &this->unk_490, phi_v0, phi_v1); + Matrix_StatePop(); + Matrix_InsertTranslation(this->unk_484.x, this->unk_484.y, this->unk_484.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateY(this->unk_490.y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->unk_490.x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->unk_490.z, MTXMODE_APPLY); + Matrix_StatePush(); + break; + } +} + +void func_80BB3BE0(EnGeg* this, GlobalContext* globalCtx) { + static TexturePtr D_80BB4088[] = { + &object_oF1d_map_Tex_010438, + &object_oF1d_map_Tex_010C38, + &object_oF1d_map_Tex_011038, + &object_oF1d_map_Tex_010838, + }; + s32 pad; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80BB4088[this->unk_23E])); + gDPPipeSync(POLY_OPA_DISP++); + + func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnGeg_OverrideLimbDraw, EnGeg_PostLimbDraw, EnGeg_UnkDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80BB3CB4(EnGeg* this, GlobalContext* globalCtx) { + f32 sp24 = globalCtx->state.frames * this->actor.speedXZ * 1400.0f; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y + this->actor.shape.yOffset, + this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, -this->actor.shape.yOffset, 0.0f, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, this->actor.shape.yOffset, 0.0f, MTXMODE_APPLY); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_InsertXRotation_s(sp24, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_oF1d_map_DL_0091A8); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnGeg_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnGeg* this = THIS; + + if (this->unk_230 & 1) { + func_80BB3CB4(this, globalCtx); + } else { + func_80BB3BE0(this, globalCtx); + } +} diff --git a/src/overlays/actors/ovl_En_Geg/z_en_geg.h b/src/overlays/actors/ovl_En_Geg/z_en_geg.h index 1bd18cc05..c846f447b 100644 --- a/src/overlays/actors/ovl_En_Geg/z_en_geg.h +++ b/src/overlays/actors/ovl_En_Geg/z_en_geg.h @@ -8,10 +8,44 @@ struct EnGeg; typedef void (*EnGegActionFunc)(struct EnGeg*, GlobalContext*); typedef struct EnGeg { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; - /* 0x0188 */ EnGegActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x364]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ EnGegActionFunc actionFunc; + /* 0x18C */ ColliderCylinder colliderCylinder; + /* 0x1D8 */ ColliderSphere colliderSphere; + /* 0x230 */ u16 unk_230; + /* 0x232 */ s16 unk_232; + /* 0x234 */ UNK_TYPE1 unk234[4]; + /* 0x238 */ s16 unk_238; + /* 0x23A */ UNK_TYPE1 unk23A[0x4]; + /* 0x23E */ s16 unk_23E; + /* 0x240 */ s16 unk_240; + /* 0x242 */ s16 unk_242; + /* 0x244 */ s16 unk_244; + /* 0x248 */ s32 unk_248; + /* 0x24C */ Vec3s jointTable[18]; + /* 0x2B8 */ Vec3s morphTable[18]; + /* 0x324 */ UNK_TYPE1 unk324[0x144]; + /* 0x468 */ s16 unk_468; + /* 0x46A */ s16 unk_46A; + /* 0x46C */ s16 unk_46C; + /* 0x46E */ s16 unk_46E; + /* 0x470 */ Vec3f unk_470; + /* 0x47C */ Vec3s unk_47C; + /* 0x484 */ Vec3f unk_484; + /* 0x490 */ Vec3s unk_490; + /* 0x496 */ u16 unk_496; + /* 0x498 */ s16 unk_498; + /* 0x49A */ s16 unk_49A; + /* 0x49C */ s16 unk_49C[8]; + /* 0x4AC */ s32 unk_4AC; + /* 0x4B0 */ s16 unk_4B0; + /* 0x4B4 */ Vec3f unk_4B4; + /* 0x4C0 */ Vec3f unk_4C0[2]; + /* 0x4D8 */ s16 unk_4D8; + /* 0x4DC */ s32 unk_4DC; + /* 0x4E0 */ s16 unk_4E0; + /* 0x4E4 */ Vec3f unk_4E4; } EnGeg; // size = 0x4F0 extern const ActorInit En_Geg_InitVars; diff --git a/src/overlays/actors/ovl_En_Giant/z_en_giant.c b/src/overlays/actors/ovl_En_Giant/z_en_giant.c index ec6d56ef6..68ccef9fc 100644 --- a/src/overlays/actors/ovl_En_Giant/z_en_giant.c +++ b/src/overlays/actors/ovl_En_Giant/z_en_giant.c @@ -5,6 +5,7 @@ */ #include "z_en_giant.h" +#include "objects/object_giant/object_giant.h" #define FLAGS 0x00000030 @@ -31,41 +32,21 @@ const ActorInit En_Giant_InitVars = { (ActorFunc)EnGiant_Draw, }; -extern AnimationHeader D_06002168; -extern Gfx D_06005A80[]; -extern Gfx D_06006280[]; -extern Gfx D_06007610[]; -extern Gfx D_06006A80[]; -extern FlexSkeletonHeader D_060079B0; -extern AnimationHeader D_06008394; -extern AnimationHeader D_060096E4; -extern AnimationHeader D_0600A1C4; -extern AnimationHeader D_0600ACA4; -extern AnimationHeader D_0600B784; -extern AnimationHeader D_0600C5D4; -extern AnimationHeader D_0600D040; -extern AnimationHeader D_0600DE84; -extern AnimationHeader D_060102A4; -extern AnimationHeader D_060116E4; -extern AnimationHeader D_06012A38; -extern AnimationHeader D_06013004; -extern AnimationHeader D_06013FE8; -extern AnimationHeader D_06015334; -extern AnimationHeader D_06017944; - -static AnimationHeader* sAnimationTable[] = { - &D_06008394, &D_060096E4, &D_060102A4, &D_060116E4, &D_06012A38, &D_06013004, &D_06013FE8, &D_06015334, - &D_06017944, &D_0600A1C4, &D_0600D040, &D_0600DE84, &D_0600ACA4, &D_0600B784, &D_0600C5D4, +static AnimationHeader* sAnimations[] = { + &gGiantLookUpStartAnim, &gGiantLookUpLoopAnim, &gGiantFallingOverAnim, &gGiantRaisedArmsStartAnim, + &gGiantRaisedArmsLoopAnim, &gGiantStruggleStartAnim, &gGiantStruggleLoopAnim, &gGiantIdleAnim, + &gGiantWalkingAnim, &gGiantBigCallStartAnim, &gGiantBigCallLoopAnim, &gGiantBigCallEndAnim, + &gGiantSmallCallStartAnim, &gGiantSmallCallLoopAnim, &gGiantSmallCallEndAnim, }; void EnGiant_ChangeAnimation(EnGiant* this, s16 newAnimationId) { if (newAnimationId >= GIANT_ANIMATION_LOOK_UP_START && newAnimationId < GIANT_ANIMATION_MAX) { if ((this->animationId == GIANT_ANIMATION_WALKING_LOOP && newAnimationId != GIANT_ANIMATION_WALKING_LOOP) || (newAnimationId == GIANT_ANIMATION_WALKING_LOOP && this->animationId != GIANT_ANIMATION_WALKING_LOOP)) { - Animation_Change(&this->skelAnime, sAnimationTable[newAnimationId], 1.0f, 0.0f, - Animation_GetLastFrame(&sAnimationTable[newAnimationId]->common), 2, 10.0f); + Animation_Change(&this->skelAnime, sAnimations[newAnimationId], 1.0f, 0.0f, + Animation_GetLastFrame(&sAnimations[newAnimationId]->common), 2, 10.0f); } else { - Animation_PlayOnce(&this->skelAnime, sAnimationTable[newAnimationId]); + Animation_PlayOnce(&this->skelAnime, sAnimations[newAnimationId]); } this->animationId = newAnimationId; } @@ -118,7 +99,8 @@ void EnGiant_Init(Actor* thisx, GlobalContext* globalCtx) { this->actor.uncullZoneScale = 2000.0f; this->actor.uncullZoneDownward = 2400.0f; Actor_SetScale(&this->actor, 0.32f); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_060079B0, &D_06002168, this->jointTable, this->morphTable, 16); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGiantSkel, &gGiantLargeStrideAnim, this->jointTable, + this->morphTable, GIANT_LIMB_MAX); EnGiant_ChangeAnimation(this, GIANT_ANIMATION_IDLE_LOOP); this->csAction = GIANT_CS_ACTION_NONE; this->actionFunc = EnGiant_PerformCutsceneActions; @@ -131,20 +113,20 @@ void EnGiant_Init(Actor* thisx, GlobalContext* globalCtx) { case GIANT_TYPE_CANYON_TERMINA_FIELD: case GIANT_TYPE_CANYON_CLOCK_TOWER_SUCCESS: case GIANT_TYPE_CANYON_GIANTS_CHAMBER_AND_ENDING: - this->unk_24A = 0x1C6; + this->actorActionCommand = 0x1C6; break; case GIANT_TYPE_SWAMP_TERMINA_FIELD: case GIANT_TYPE_SWAMP_CLOCK_TOWER_SUCCESS: case GIANT_TYPE_SWAMP_GIANTS_CHAMBER_AND_ENDING: - this->unk_24A = 0x1C7; + this->actorActionCommand = 0x1C7; break; case GIANT_TYPE_OCEAN_TERMINA_FIELD: case GIANT_TYPE_OCEAN_CLOCK_TOWER_SUCCESS: case GIANT_TYPE_OCEAN_GIANTS_CHAMBER_AND_ENDING: - this->unk_24A = 0x1C8; + this->actorActionCommand = 0x1C8; break; default: - this->unk_24A = 0x1C5; + this->actorActionCommand = 0x1C5; break; } @@ -153,11 +135,12 @@ void EnGiant_Init(Actor* thisx, GlobalContext* globalCtx) { Actor_MarkForDeath(&this->actor); return; } - this->unk_24A = 0x1C5; + this->actorActionCommand = 0x1C5; Actor_SetScale(&this->actor, 0.32f); this->actionFunc = EnGiant_PerformClockTowerSuccessActions; - Animation_Change(&this->skelAnime, &D_060116E4, 0.0f, Animation_GetLastFrame(&D_060116E4) - 1.0f, - Animation_GetLastFrame(&D_060116E4), 2, 0.0f); + Animation_Change(&this->skelAnime, &gGiantRaisedArmsStartAnim, 0.0f, + Animation_GetLastFrame(&gGiantRaisedArmsStartAnim) - 1.0f, + Animation_GetLastFrame(&gGiantRaisedArmsStartAnim), 2, 0.0f); this->actor.draw = EnGiant_Draw; this->actor.velocity.y = 0.0f; this->actor.minVelocityY = 0.0f; @@ -167,7 +150,8 @@ void EnGiant_Init(Actor* thisx, GlobalContext* globalCtx) { if (GIANT_TYPE_IS_CLOCK_TOWER_FAILURE(type)) { Actor_SetScale(&this->actor, 0.32f); this->actionFunc = EnGiant_PlayClockTowerFailureAnimation; - Animation_Change(&this->skelAnime, &D_06013FE8, 1.0f, 0.0f, Animation_GetLastFrame(&D_06013004), 0, 0.0f); + Animation_Change(&this->skelAnime, &gGiantStruggleLoopAnim, 1.0f, 0.0f, + Animation_GetLastFrame(&gGiantStruggleStartAnim), 0, 0.0f); this->actor.draw = EnGiant_Draw; this->actor.velocity.y = 0.0f; this->actor.minVelocityY = 0.0f; @@ -204,7 +188,7 @@ void EnGiant_Destroy(Actor* thisx, GlobalContext* globalCtx) { } /** - * The animations in sAnimationTable are organized such that looping animations + * The animations in sAnimations are organized such that looping animations * appear immediately after their respective starting animations. The point of * this function is to play the requested start animation if it has not been * played yet and play the respetive looping animation otherwise. @@ -266,8 +250,9 @@ void EnGiant_ChangeAnimationBasedOnCsAction(EnGiant* this) { } break; case GIANT_CS_ACTION_HOLDING_UP_MOON_IN_CLOCK_TOWER: - Animation_Change(&this->skelAnime, &D_060116E4, 0.0f, Animation_GetLastFrame(&D_060116E4) - 1.0f, - Animation_GetLastFrame(&D_060116E4), 2, 0.0f); + Animation_Change(&this->skelAnime, &gGiantRaisedArmsStartAnim, 0.0f, + Animation_GetLastFrame(&gGiantRaisedArmsStartAnim) - 1.0f, + Animation_GetLastFrame(&gGiantRaisedArmsStartAnim), 2, 0.0f); break; } } @@ -352,20 +337,19 @@ void EnGiant_PlaySound(EnGiant* this) { void EnGiant_UpdatePosition(EnGiant* this, GlobalContext* globalCtx, u32 actionIndex) { CsCmdActorAction* actorAction = globalCtx->csCtx.npcActions[actionIndex]; - f32 floatUnk10 = actorAction->unk10; + f32 startPosY = actorAction->unk0C.y; s32 pad[2]; - f32 floatUnk1C = actorAction->unk1C; - f32 functionTemp; + f32 endPosY = actorAction->unk18.y; + f32 scale = func_800F5A8C(actorAction->endFrame, actorAction->startFrame, globalCtx->csCtx.frames, globalCtx); - functionTemp = func_800F5A8C(actorAction->endFrame, actorAction->startFrame, globalCtx->csCtx.frames, globalCtx); - this->actor.world.pos.y = ((floatUnk1C - floatUnk10) * functionTemp) + floatUnk10; + this->actor.world.pos.y = ((endPosY - startPosY) * scale) + startPosY; } void EnGiant_PerformClockTowerSuccessActions(EnGiant* this, GlobalContext* globalCtx) { - if (func_800EE29C(globalCtx, this->unk_24A)) { - EnGiant_UpdatePosition(this, globalCtx, func_800EE200(globalCtx, this->unk_24A)); - if (this->csAction != globalCtx->csCtx.npcActions[func_800EE200(globalCtx, this->unk_24A)]->unk0) { - this->csAction = globalCtx->csCtx.npcActions[func_800EE200(globalCtx, this->unk_24A)]->unk0; + if (func_800EE29C(globalCtx, this->actorActionCommand)) { + EnGiant_UpdatePosition(this, globalCtx, func_800EE200(globalCtx, this->actorActionCommand)); + if (this->csAction != globalCtx->csCtx.npcActions[func_800EE200(globalCtx, this->actorActionCommand)]->unk0) { + this->csAction = globalCtx->csCtx.npcActions[func_800EE200(globalCtx, this->actorActionCommand)]->unk0; EnGiant_ChangeAnimationBasedOnCsAction(this); } EnGiant_UpdateAlpha(this); @@ -385,10 +369,10 @@ void EnGiant_PlayClockTowerFailureAnimation(EnGiant* this, GlobalContext* global void EnGiant_PerformCutsceneActions(EnGiant* this, GlobalContext* globalCtx) { this->actor.draw = EnGiant_Draw; - if (func_800EE29C(globalCtx, this->unk_24A)) { - func_800EDF24(&this->actor, globalCtx, func_800EE200(globalCtx, this->unk_24A)); - if (this->csAction != globalCtx->csCtx.npcActions[func_800EE200(globalCtx, this->unk_24A)]->unk0) { - this->csAction = globalCtx->csCtx.npcActions[func_800EE200(globalCtx, this->unk_24A)]->unk0; + if (func_800EE29C(globalCtx, this->actorActionCommand)) { + func_800EDF24(&this->actor, globalCtx, func_800EE200(globalCtx, this->actorActionCommand)); + if (this->csAction != globalCtx->csCtx.npcActions[func_800EE200(globalCtx, this->actorActionCommand)]->unk0) { + this->csAction = globalCtx->csCtx.npcActions[func_800EE200(globalCtx, this->actorActionCommand)]->unk0; EnGiant_ChangeAnimationBasedOnCsAction(this); } EnGiant_UpdateAlpha(this); @@ -427,10 +411,10 @@ void EnGiant_Update(Actor* thisx, GlobalContext* globalCtx) { } void EnGiant_PostLimbDrawOpa(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { - if (limbIndex == 1) { + if (limbIndex == GIANT_LIMB_HEAD) { OPEN_DISPS(globalCtx->state.gfxCtx); - gSPDisplayList(POLY_OPA_DISP++, D_06007610); + gSPDisplayList(POLY_OPA_DISP++, gGiantBeardDL); CLOSE_DISPS(globalCtx->state.gfxCtx); } @@ -440,21 +424,15 @@ void EnGiant_PostLimbDrawXlu(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLis Gfx** gfx) { EnGiant* this = THIS; - if (limbIndex == 1) { - Matrix_CopyCurrentState(&this->unk_254); + if (limbIndex == GIANT_LIMB_HEAD) { + Matrix_CopyCurrentState(&this->headDrawMtxF); } } void EnGiant_Draw(Actor* thisx, GlobalContext* globalCtx) { s32 pad; EnGiant* this = THIS; - - /** - * 0 = eyes fully open face - * 1 = eyes half-closed face - * 2 = eyes fully closed face - */ - static TexturePtr sFaceTextures[] = { D_06005A80, D_06006280, D_06006A80 }; + static TexturePtr sFaceTextures[] = { gGiantFaceEyeOpenTex, gGiantFaceEyeHalfTex, gGiantFaceEyeClosedTex }; if (this->alpha > 0) { OPEN_DISPS(globalCtx->state.gfxCtx); @@ -479,10 +457,10 @@ void EnGiant_Draw(Actor* thisx, GlobalContext* globalCtx) { POLY_XLU_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, NULL, EnGiant_PostLimbDrawXlu, thisx, POLY_XLU_DISP); - Matrix_InsertMatrix(&this->unk_254, MTXMODE_NEW); + Matrix_InsertMatrix(&this->headDrawMtxF, MTXMODE_NEW); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, D_06007610); + gSPDisplayList(POLY_XLU_DISP++, gGiantBeardDL); } CLOSE_DISPS(globalCtx->state.gfxCtx); diff --git a/src/overlays/actors/ovl_En_Giant/z_en_giant.h b/src/overlays/actors/ovl_En_Giant/z_en_giant.h index 6f50370f7..e28aa2a32 100644 --- a/src/overlays/actors/ovl_En_Giant/z_en_giant.h +++ b/src/overlays/actors/ovl_En_Giant/z_en_giant.h @@ -86,6 +86,26 @@ typedef enum { /* 15 */ GIANT_CS_ACTION_HOLDING_UP_MOON_IN_CLOCK_TOWER } GiantCsActionIndex; +typedef enum { + /* 0 */ GIANT_LIMB_NONE, + /* 1 */ GIANT_LIMB_HEAD, + /* 2 */ GIANT_LIMB_LEFT_THIGH, + /* 3 */ GIANT_LIMB_LEFT_LOWER_LEG, + /* 4 */ GIANT_LIMB_LEFT_FOOT, + /* 5 */ GIANT_LIMB_RIGHT_THIGH, + /* 6 */ GIANT_LIMB_RIGHT_LOWER_LEG, + /* 7 */ GIANT_LIMB_RIGHT_FOOT, + /* 8 */ GIANT_LIMB_LEFT_SHOULDER, + /* 9 */ GIANT_LIMB_LEFT_UPPER_ARM, + /* 10 */ GIANT_LIMB_LEFT_FOREARM, + /* 11 */ GIANT_LIMB_LEFT_HAND, + /* 12 */ GIANT_LIMB_RIGHT_SHOULDER, + /* 13 */ GIANT_LIMB_RIGHT_UPPER_ARM, + /* 14 */ GIANT_LIMB_RIGHT_FOREARM, + /* 15 */ GIANT_LIMB_RIGHT_HAND, + /* 16 */ GIANT_LIMB_MAX, +} EnGiantLimbs; + struct EnGiant; typedef void (*EnGiantActionFunc)(struct EnGiant*, GlobalContext*); @@ -93,14 +113,14 @@ typedef void (*EnGiantActionFunc)(struct EnGiant*, GlobalContext*); typedef struct EnGiant { /* 0x000 */ Actor actor; /* 0x144 */ SkelAnime skelAnime; - /* 0x188 */ Vec3s jointTable[16]; - /* 0x1E8 */ Vec3s morphTable[16]; + /* 0x188 */ Vec3s jointTable[GIANT_LIMB_MAX]; + /* 0x1E8 */ Vec3s morphTable[GIANT_LIMB_MAX]; /* 0x248 */ s16 animationId; - /* 0x24A */ u16 unk_24A; + /* 0x24A */ u16 actorActionCommand; /* 0x24C */ u16 csAction; /* 0x24E */ s16 alpha; /* 0x250 */ u16 sfxId; - /* 0x254 */ MtxF unk_254; + /* 0x254 */ MtxF headDrawMtxF; /* 0x294 */ s16 faceIndex; /* 0x296 */ s16 blinkTimer; /* 0x298 */ EnGiantActionFunc actionFunc; diff --git a/src/overlays/actors/ovl_En_Ginko_Man/z_en_ginko_man.c b/src/overlays/actors/ovl_En_Ginko_Man/z_en_ginko_man.c index 393106e4c..6946f58ec 100644 --- a/src/overlays/actors/ovl_En_Ginko_Man/z_en_ginko_man.c +++ b/src/overlays/actors/ovl_En_Ginko_Man/z_en_ginko_man.c @@ -642,12 +642,12 @@ s32 EnGinkoMan_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** d if (limbIndex == 15) { Matrix_InsertTranslation(1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); - Matrix_InsertXRotation_s(this->limb15Rot.y, 1); - Matrix_InsertZRotation_s(this->limb15Rot.x, 1); + Matrix_InsertXRotation_s(this->limb15Rot.y, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->limb15Rot.x, MTXMODE_APPLY); Matrix_InsertTranslation(-1500.0f, 0.0f, 0.0f, MTXMODE_APPLY); } else if (limbIndex == 8) { - Matrix_InsertXRotation_s(-this->limb8Rot.y, 1); - Matrix_InsertZRotation_s(-this->limb8Rot.x, 1); + Matrix_InsertXRotation_s(-this->limb8Rot.y, MTXMODE_APPLY); + Matrix_InsertZRotation_s(-this->limb8Rot.x, MTXMODE_APPLY); } return 0; diff --git a/src/overlays/actors/ovl_En_Gm/z_en_gm.c b/src/overlays/actors/ovl_En_Gm/z_en_gm.c index bb81c00a0..b6b8bc8ad 100644 --- a/src/overlays/actors/ovl_En_Gm/z_en_gm.c +++ b/src/overlays/actors/ovl_En_Gm/z_en_gm.c @@ -5,6 +5,7 @@ */ #include "z_en_gm.h" +#include "overlays/actors/ovl_En_Door/z_en_door.h" #define FLAGS 0x00000019 @@ -18,7 +19,79 @@ void EnGm_Draw(Actor* thisx, GlobalContext* globalCtx); void func_80950CDC(EnGm* this, GlobalContext* globalCtx); void func_80950DB8(EnGm* this, GlobalContext* globalCtx); -#if 0 +extern UNK_PTR D_06005028; +extern UNK_PTR D_060054A8; +extern UNK_PTR D_06005CE8; +extern UNK_PTR D_06006828; +extern UNK_PTR D_06006C68; +extern Gfx D_06007528[]; +extern FlexSkeletonHeader D_060078B0; +extern AnimationHeader D_06008090; +extern AnimationHeader D_0600898C; +extern AnimationHeader D_06009450; +extern AnimationHeader D_06009CDC; +extern AnimationHeader D_0600A5E0; +extern AnimationHeader D_0600A70C; +extern AnimationHeader D_0600AD18; +extern AnimationHeader D_0600B8B0; +extern AnimationHeader D_0600B990; +extern AnimationHeader D_0600BA80; +extern AnimationHeader D_0600C03C; + +static u32 D_80951820[] = { + 0x0D000101, 0x360A0061, 0x25020600, 0x09001902, 0x0900090A, 0x0D02090A, 0x090F0105, 0x0E090A09, 0x0F0F0E09, + 0x00090A18, 0x0E060009, 0x00060A00, 0x6C490209, 0x0A090F3D, 0x02090F0A, 0x0031020A, 0x000A0525, 0x020C0F0C, + 0x1419020C, 0x140C320D, 0x020C320C, 0x3701050E, 0x0C320C37, 0x0C0E0C14, 0x0C32160E, 0x0C0F0C14, 0x0B0E0A00, + 0x0A050A0E, 0x090F0A00, 0x150E090A, 0x090F090B, 0x00120085, 0x020A000A, 0x0579020A, 0x050A0A6D, 0x020A0A0A, + 0x1E61020A, 0x1E0A2855, 0x020A280A, 0x2D49020A, 0x2D0A373D, 0x020A370B, 0x2D31020B, 0x2D0B3725, 0x020B370C, + 0x0019020C, 0x000C0F0D, 0x020C0F0C, 0x1401050E, 0x0C0F0C14, 0x110E0C00, 0x0C0F1D0E, 0x0B370C00, 0x130E0B2D, + 0x0B371C0E, 0x0A370B2D, 0x020E0A2D, 0x0A371B0E, 0x0A280A2D, 0x120E0A1E, 0x0A281A0E, 0x0A0A0A1E, 0x010E0A05, + 0x0A0A190E, 0x0A000A05, 0x100A0015, 0x31020C37, 0x0D002502, 0x0D000D19, 0x19020D19, 0x15050D02, 0x15370505, + 0x01050E15, 0x37050505, 0x0E0D1915, 0x05030E0D, 0x000D191E, 0x0E0C370D, 0x0014050D, 0x000200AB, 0x01320100, + 0x880A0061, 0x31020600, 0x12002502, 0x12001500, 0x19021500, 0x150A0D02, 0x150A150F, 0x01050E15, 0x0A150F0F, + 0x0E150015, 0x0A180E12, 0x00150006, 0x0E060012, 0x00070A00, 0x6C250215, 0x0A150F19, 0x02150F15, 0x190D0215, + 0x19151E01, 0x050E1519, 0x151E0E0E, 0x150F1519, 0x170E150A, 0x150F0D0A, 0x00152502, 0x151E152D, 0x1902152D, + 0x160A0D02, 0x160A0600, 0x01050E16, 0x0A060005, 0x0E152D16, 0x0A1E0E15, 0x1E152D14, 0x050A0061, 0x19020600, + 0x12000D02, 0x12000600, 0x01050E00, 0x00000008, 0x0E060012, 0x00070505, +}; + +static s32 D_80951A0C[] = { + -1, 1, 4, 1, -1, 1, -1, -1, -1, 0, 2, 3, 5, 6, 8, 1, 0, 8, 3, 6, 0, 1, 4, 7, 0, 1, 2, 4, 5, 7, 1, +}; + +static s32 D_80951A88[] = { 0x0E2AB92D, 0x000A0C10 }; + +static s32 D_80951A90[] = { 0x0E2ABA2D, 0x000A0C10 }; + +static s32 D_80951A98[] = { + 0x00564000, 0x1A090000, 0x0E2AA40C, 0x09000017, 0x0E2AA52D, 0x000A0C09, 0x00001211, 0x56401009, + 0x00000E2A, 0xEC0C0900, 0x00170E2A, 0xED0C0900, 0x00180E2A, 0xEE2D000A, 0x0C090000, 0x12100000, +}; + +static s32 D_80951AD8[] = { + 0x00562000, 0xA1090000, 0x0E2AA60C, 0x09000017, 0x0E2AA70C, 0x09000018, 0x0E2AA80C, 0x09000017, + 0x0E2AA90C, 0x09000018, 0x0E2AAA0C, 0x09000017, 0x0E2AAB0C, 0x09000018, 0x0E2AAC0C, 0x09000017, + 0x0E2AAD0C, 0x0F2AAE0C, 0x09000017, 0x0E2AAF0C, 0x09000017, 0x0E2AB00C, 0x09000018, 0x0E2AB10C, + 0x09000017, 0x0E2AB20C, 0x09000017, 0x0E2AB30C, 0x09000017, 0x0E2AB40C, 0x09000018, 0x0E2AB50C, + 0x09000017, 0x0E2AB60C, 0x09000018, 0x0E2AB70C, 0x09000017, 0x0E2AB82D, 0x00082D00, 0x092D000A, + 0x0C115620, 0x12100900, 0x000E2AEA, 0x0C090000, 0x170E2AEB, 0x2D00082D, 0x000A0C09, 0x00001210, +}; + +static s32 D_80951B98[] = { + 0x004B0100, 0x42090000, 0x0900000E, 0x2B010C09, 0x0000170E, 0x2B020C09, 0x0000180E, + 0x2B030C09, 0x0000170E, 0x2B040C0F, 0x2B050C09, 0x0000180E, 0x2B060C09, 0x0000170E, + 0x2B072D00, 0x0A0C114B, 0x01150900, 0x0012100E, 0x2B082D00, 0x0A0C1210, +}; + +static s32 D_80951BE8[] = { + 0x09000000, 0x32010031, 0x00338000, 0x2C004B02, 0x000D0E2B, 0x132D000A, 0x0C114B02, 0x1900150E, 0x2B140C0F, + 0x2B150C0F, 0x2B160C0F, 0x2B170C0F, 0x2B180C15, 0x09000012, 0x100E2B12, 0x2D000A0C, 0x10000000, +}; + +static s32 D_80951C2C[] = { 0x0E295A2D, 0x000A0C10 }; + +static s32 D_80951C34[] = { 0x0E29622D, 0x000A0C10 }; + const ActorInit En_Gm_InitVars = { ACTOR_EN_GM, ACTORCAT_NPC, @@ -31,130 +104,1667 @@ const ActorInit En_Gm_InitVars = { (ActorFunc)EnGm_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80951C5C = { - { COLTYPE_HIT1, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK1, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_HIT1, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK1, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 14, 62, 0, { 0, 0, 0 } }, }; -// static ColliderSphereInit sSphereInit = { -static ColliderSphereInit D_80951C88 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_SPHERE, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +static ColliderSphereInit sSphereInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_SPHERE, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 20 }, 100 }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80951CB4 = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -#endif +static ActorAnimationEntryS D_80951CC0[13] = { + { &D_06009CDC, 1.0f, 0, -1, 0, 0 }, { &D_06009CDC, 1.0f, 0, -1, 0, -4 }, { &D_0600A5E0, 1.0f, 0, -1, 0, 0 }, + { &D_0600A70C, 1.0f, 0, 1, 0, 0 }, { &D_06008090, 1.0f, 0, -1, 0, 0 }, { &D_0600898C, 1.0f, 0, -1, 2, -4 }, + { &D_06009450, 1.0f, 0, -1, 2, -4 }, { &D_0600AD18, 1.0f, 0, -1, 0, 0 }, { &D_0600AD18, 1.0f, 0, -1, 0, -4 }, + { &D_0600B8B0, 1.0f, 0, -1, 2, 0 }, { &D_0600BA80, 1.0f, 0, -1, 0, -4 }, { &D_0600C03C, 1.0f, 0, -1, 0, -4 }, + { &D_0600B990, 1.0f, 0, -1, 0, -4 }, +}; -extern ColliderCylinderInit D_80951C5C; -extern ColliderSphereInit D_80951C88; -extern CollisionCheckInfoInit2 D_80951CB4; +Actor* func_8094DEE0(EnGm* this, GlobalContext* globalCtx, u8 arg2, s16 arg3) { + Actor* foundActor = NULL; + Actor* actor; -extern UNK_TYPE D_06007528; -extern UNK_TYPE D_060078B0; + while (true) { + actor = SubS_FindActor(globalCtx, foundActor, arg2, arg3); + foundActor = actor; + if (actor == NULL) { + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094DEE0.s") + if ((this != (EnGm*)foundActor) && (foundActor->update != NULL)) { + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094DF90.s") + actor = actor->next; + if (actor == NULL) { + foundActor = NULL; + break; + } + foundActor = actor; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094DFF8.s") + return foundActor; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094E054.s") +EnDoor* func_8094DF90(GlobalContext* globalCtx, s32 arg1) { + s32 phi_a1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094E0F8.s") + switch (arg1) { + case 9: + case 13: + case 15: + phi_a1 = 11; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094E1DC.s") + case 10: + case 11: + case 16: + case 17: + phi_a1 = 17; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094E278.s") + case 12: + case 14: + case 20: + phi_a1 = 10; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094E2D0.s") + case 18: + case 19: + phi_a1 = 19; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094E454.s") + default: + phi_a1 = -1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094E4D0.s") + return SubS_FindDoor(globalCtx, phi_a1); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094E52C.s") +s32 func_8094DFF8(EnGm* this, GlobalContext* globalCtx) { + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094E69C.s") + if (this->unk_262 < 0) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094EA34.s") + if (this->unk_262 >= 0) { + this->skelAnime.playSpeed = this->unk_3A8; + ret = SkelAnime_Update(&this->skelAnime); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094EB1C.s") + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094EDBC.s") +s32 func_8094E054(EnGm* this, GlobalContext* globalCtx, s32 arg2) { + s8 tmp = this->unk_262; + s32 phi_v1 = false; + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094EE84.s") + if ((arg2 == 0) || (arg2 == 1)) { + if ((this->unk_3E8 != 0) && (this->unk_3E8 != 1)) { + phi_v1 = true; + } + } else if (arg2 != this->unk_3E8) { + phi_v1 = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094EFC4.s") + if (phi_v1) { + if (tmp >= 0) { + this->unk_3E8 = arg2; + ret = func_8013BC6C(&this->skelAnime, D_80951CC0, arg2); + this->unk_3A8 = this->skelAnime.playSpeed; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094F074.s") + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094F0E0.s") +s32 func_8094E0F8(EnGm* this, GlobalContext* globalCtx) { + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094F2E8.s") + if ((this->unk_260 != globalCtx->roomCtx.currRoom.num) && (globalCtx->roomCtx.unk31 == 0)) { + this->unk_260 = globalCtx->roomCtx.currRoom.num; + this->unk_262 = func_8013D924(0x248, globalCtx); + this->actor.draw = NULL; + this->unk_3FC = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094F3D0.s") + if (this->unk_3FC == 0) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094F4EC.s") + if ((this->unk_262 < 0) || !func_8013D8DC(this->unk_262, globalCtx)) { + ret = true; + } else { + this->actor.draw = EnGm_Draw; + if (this->unk_258 == 2) { + this->unk_268 = NULL; + this->unk_3B8 = 0; + } + this->unk_3FC = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094F53C.s") + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094F7D0.s") +void func_8094E1DC(EnGm* this, GlobalContext* globalCtx) { + s32 pad; + f32 temp; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094F904.s") + if (this->unk_258 == 7) { + temp = this->colliderSphere.dim.modelSphere.radius * this->colliderSphere.dim.scale; + this->colliderSphere.dim.worldSphere.radius = temp; + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere.base); + } else { + Collider_UpdateCylinder(&this->actor, &this->colliderCylinder); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094FAC4.s") +void func_8094E278(GlobalContext* globalCtx) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_DM_CHAR07, 115.0f, 32.0f, -121.0f, 0, 0, 0, 3); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094FCC4.s") +void func_8094E2D0(EnGm* this) { + s32 phi_a1 = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094FD88.s") + if (this->unk_3A4 & 0x100) { + if (DECR(this->unk_3CC) == 0) { + switch (this->unk_3CA) { + case 1: + if ((this->unk_3CE == 5) || (this->unk_3CE == 2)) { + phi_a1 = true; + this->unk_3CE = 5; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094FE10.s") + case 2: + if ((this->unk_3CE == 4) || (this->unk_3CE == 2)) { + phi_a1 = true; + this->unk_3CE = 4; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8094FF04.s") + case 3: + if (this->unk_3CE == 2) { + phi_a1 = true; + this->unk_3CE = 2; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_80950088.s") + case 4: + if (this->unk_3CE == 1) { + phi_a1 = true; + this->unk_3CE = 1; + } + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_80950120.s") + if (!phi_a1 && ((this->unk_3CE == 4) || (this->unk_3CE == 5))) { + this->unk_3CE = 1; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_809501B8.s") + if (!phi_a1) { + this->unk_3CE++; + if (this->unk_3CE >= 4) { + if (this->unk_3CA == 0) { + this->unk_3CC = Rand_S16Offset(30, 30); + } else { + this->unk_3CC = 8; + } + this->unk_3CE = 0; + } + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_80950280.s") +s32 func_8094E454(EnGm* this, s16 arg1) { + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_80950388.s") + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(arg1); + } else if (ActorCutscene_GetCanPlayNext(arg1)) { + ActorCutscene_StartAndSetUnkLinkFields(arg1, &this->actor); + ret = true; + } else { + ActorCutscene_SetIntentToPlay(arg1); + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_809503F8.s") +s16 func_8094E4D0(EnGm* this, s32 arg1) { + s32 i; + s16 cutscene = this->actor.cutscene; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_80950490.s") + for (i = 0; i < arg1; i++) { + cutscene = ActorCutscene_GetAdditionalCutscene(cutscene); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_80950690.s") + return cutscene; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_80950804.s") +s32 func_8094E52C(EnGm* this, GlobalContext* globalCtx) { + s32 pad; + s16 sp2A = func_8094E4D0(this, 0); + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_8095097C.s") + switch (this->unk_3E0) { + case 0: + if (!func_8094E454(this, sp2A)) { + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_80950C24.s") + case 2: + if (!(gSaveContext.weekEventReg[86] & 0x40) && (this->unk_3E0 == 2)) { + ActorCutscene_Stop(sp2A); + } else { + func_800E0308(Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(sp2A)), &this->actor); + } + this->unk_3E0++; + ret = true; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_80950CDC.s") + case 1: + if ((this->actor.child != NULL) && (this->actor.child->update != NULL)) { + func_800E0308(Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(sp2A)), this->actor.child); + } + this->unk_3E0++; + ret = true; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_80950DB8.s") + case 3: + ActorCutscene_Stop(sp2A); + this->unk_3E0++; + ret = true; + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_80950F2C.s") + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/EnGm_Init.s") +s32 func_8094E69C(EnGm* this, GlobalContext* globalCtx) { + Camera* camera; + s16 sp4A = func_8094E4D0(this, 0); + s16 sp48; + Vec3f sp3C; + Vec3f sp30; + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/EnGm_Destroy.s") + switch (this->unk_3E0) { + case 0: + Audio_PlayActorSound2(&this->actor, NA_SE_EV_CHAIR_ROLL); + func_8094E054(this, globalCtx, 2); + this->unk_3E2 = 0; + this->unk_3E0++; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/EnGm_Update.s") + case 1: + if ((this->actor.child != NULL) || (this->actor.child->update != NULL)) { + Math_Vec3f_Copy(&sp3C, &this->actor.child->world.pos); + Math_Vec3f_Copy(&sp30, &this->actor.world.pos); + sp48 = Math_Vec3f_Yaw(&sp30, &sp3C); + this->unk_3E2++; + if (((this->actor.shape.rot.y / 364) != (sp48 / 364)) && (this->unk_3E2 < 20)) { + Math_ApproachS(&this->actor.shape.rot.y, sp48, 3, 0x2AA8); + } else { + this->actor.shape.rot.y = sp48; + this->unk_3A4 |= 0x20; + this->unk_3E2 = 0; + this->unk_3E0++; + ret = true; + } + } else { + this->unk_3A4 |= 0x20; + this->actor.shape.rot.y = this->actor.world.rot.y; + this->unk_3E0++; + ret = true; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_809513AC.s") + case 2: + if (func_8094E454(this, sp4A)) { + case 4: + case 6: + camera = Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(sp4A)); + func_800E0308(camera, &this->actor); + this->unk_3E0++; + ret = true; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_809514BC.s") + case 3: + case 5: + case 7: + if ((this->actor.child != NULL) && (this->actor.child->update != NULL)) { + camera = Play_GetCamera(globalCtx, ActorCutscene_GetCurrentCamera(sp4A)); + func_800E0308(camera, this->actor.child); + } + this->unk_3E0++; + ret = true; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/func_80951594.s") + case 8: + Audio_PlayActorSound2(&this->actor, NA_SE_EV_CHAIR_ROLL); + ActorCutscene_Stop(sp4A); + this->unk_3E2 = 0; + this->unk_3E0++; + break; + case 9: + sp48 = this->actor.world.rot.y; + this->unk_3E2++; + if (((this->actor.shape.rot.y / 364) != (sp48 / 364)) && (this->unk_3E2 < 20)) { + Math_ApproachS(&this->actor.shape.rot.y, sp48, 3, 0x2AA8); + this->unk_3A4 &= ~0x20; + } else { + func_8094E054(this, globalCtx, 1); + this->actor.shape.rot.y = sp48; + this->unk_3E0++; + this->unk_3E2 = 0; + ret = true; + } + break; + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gm/EnGm_Draw.s") +s32 func_8094EA34(EnGm* this, GlobalContext* globalCtx) { + s32 pad[2]; + Actor* al; + Actor* toto; + + al = func_8094DEE0(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_AL); + toto = func_8094DEE0(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_TOTO); + if ((al == NULL) || (al->update == NULL) || (toto == NULL) || (toto->update == NULL)) { + this->unk_3E0++; + return true; + } + + switch (this->unk_3E0) { + case 0: + case 2: + case 4: + case 6: + case 10: + case 14: + case 16: + this->unk_3E0++; + break; + + case 7: + case 9: + case 12: + this->actor.child = toto; + this->unk_3E0++; + break; + + case 1: + case 3: + case 5: + case 8: + case 11: + case 13: + case 15: + case 17: + this->actor.child = al; + this->unk_3E0++; + break; + + default: + this->unk_3E0++; + break; + } + + return true; +} + +s32 func_8094EB1C(EnGm* this, GlobalContext* globalCtx) { + s32 pad[2]; + s32 ret = false; + s16 oldYaw; + + switch (this->unk_3E0) { + case 0: + if ((gSaveContext.weekEventReg[50] & 1) || (gSaveContext.weekEventReg[51] & 0x80) || + (gSaveContext.weekEventReg[75] & 2)) { + ret = true; + break; + } + Audio_PlayActorSound2(&this->actor, NA_SE_EV_CHAIR_ROLL); + func_8094E054(this, globalCtx, 2); + this->unk_3E2 = 0; + this->unk_3E0++; + + case 1: + oldYaw = this->actor.yawTowardsPlayer; + this->unk_3E2++; + if (((this->actor.shape.rot.y / 364) != (oldYaw / 364)) && (this->unk_3E2 < 20)) { + Math_ApproachS(&this->actor.shape.rot.y, oldYaw, 3, 0x2AA8); + } else { + this->actor.shape.rot.y = oldYaw; + this->unk_3A4 |= 0x20; + this->unk_3E2 = 0; + this->unk_3E0++; + ret = true; + } + break; + + case 2: + Audio_PlayActorSound2(&this->actor, NA_SE_EV_CHAIR_ROLL); + this->unk_3E2 = 0; + this->unk_3E0++; + + case 3: + oldYaw = this->actor.world.rot.y; + this->unk_3E2++; + if (((this->actor.shape.rot.y / 364) != (oldYaw / 364)) && (this->unk_3E2 < 20)) { + Math_ApproachS(&this->actor.shape.rot.y, oldYaw, 3, 0x2AA8); + this->unk_3A4 &= ~0x20; + } else { + func_8094E054(this, globalCtx, 1); + this->actor.shape.rot.y = oldYaw; + this->unk_3E2 = 0; + this->unk_3E0++; + ret = true; + } + break; + } + return ret; +} + +s32* func_8094EDBC(EnGm* this, GlobalContext* globalCtx) { + switch (this->unk_258) { + case 1: + this->unk_3E4 = func_8094E52C; + return D_80951A98; + + case 2: + this->unk_3E4 = func_8094EA34; + return D_80951AD8; + + case 3: + this->unk_3E4 = func_8094E69C; + return D_80951B98; + + case 5: + this->unk_3E4 = func_8094EB1C; + return D_80951BE8; + + case 7: + return D_80951C2C; + + case 8: + return D_80951C34; + + case 6: + case 21: + case 23: + case 24: + case 25: + case 26: + case 27: + case 30: + return D_80951A88; + + case 12: + case 17: + case 19: + case 20: + case 22: + case 28: + case 29: + return D_80951A90; + + default: + break; + } + return NULL; +} + +s32 func_8094EE84(EnGm* this, GlobalContext* globalCtx) { + s32 ret = false; + + if (this->unk_3A4 & 7) { + if (func_800B84D0(&this->actor, globalCtx)) { + func_8013AED4(&this->unk_3A4, 0, 7); + this->unk_3E0 = 0; + this->unk_3E4 = NULL; + this->actor.child = this->unk_268; + this->unk_264 = func_8094EDBC(this, globalCtx); + + if ((this->unk_258 == 5) && !(gSaveContext.weekEventReg[50] & 1) && + !(gSaveContext.weekEventReg[51] & 0x80) && !(gSaveContext.weekEventReg[75] & 2)) { + this->unk_3A4 |= 0x20; + } else if ((this->unk_258 != 1) && (this->unk_258 != 5) && (this->unk_258 != 7)) { + this->unk_3A4 |= 0x20; + } + + if ((this->unk_258 == 3) && (gSaveContext.weekEventReg[75] & 1)) { + this->unk_3A4 &= ~0x20; + } + + this->actionFunc = func_80950DB8; + ret = true; + } + } + return ret; +} + +s32 func_8094EFC4(EnGm* this, GlobalContext* globalCtx) { + s32 ret = false; + + if (globalCtx->csCtx.state != 0) { + if (this->unk_3F8 == 0) { + if ((globalCtx->sceneNum == SCENE_MILK_BAR) && (gSaveContext.sceneSetupIndex == 2)) { + func_8094E054(this, globalCtx, 0); + this->unk_258 = 255; + } + this->unk_259 = 255; + this->unk_3F8 = 1; + } + ret = true; + } else if (this->unk_3F8 != 0) { + if (globalCtx->sceneNum == SCENE_MILK_BAR) { + this->unk_400 = 0; + } + this->unk_3F8 = 0; + } + return ret; +} + +Actor* func_8094F074(EnGm* this, GlobalContext* globalCtx) { + Actor* actor; + + switch (this->unk_258) { + case 1: + actor = func_8094DEE0(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_RECEPGIRL); + break; + + case 2: + actor = this->unk_268; + break; + + case 3: + actor = func_8094DEE0(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_TAB); + break; + + default: + actor = &GET_PLAYER(globalCtx)->actor; + break; + } + + return actor; +} + +void func_8094F0E0(EnGm* this) { + s32 pad; + Vec3f sp40; + Vec3f sp34; + s16 sp32; + + Math_Vec3f_Copy(&sp40, &this->unk_268->world.pos); + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + sp32 = Math_Vec3f_Yaw(&sp34, &sp40); + Math_ApproachS(&this->unk_3BE, (sp32 - this->unk_3C2) - this->actor.shape.rot.y, 4, 0x2AA8); + this->unk_3BE = CLAMP(this->unk_3BE, -0x1FFE, 0x1FFE); + + Math_ApproachS(&this->unk_3C2, (sp32 - this->unk_3BE) - this->actor.shape.rot.y, 4, 0x2AA8); + this->unk_3C2 = CLAMP(this->unk_3C2, -0x1C70, 0x1C70); + + Math_Vec3f_Copy(&sp34, &this->actor.focus.pos); + + if (this->unk_268->id == ACTOR_PLAYER) { + sp40.y = ((Player*)this->unk_268)->bodyPartsPos[7].y + 3.0f; + } else { + Math_Vec3f_Copy(&sp40, &this->unk_268->focus.pos); + } + + Math_ApproachS(&this->unk_3BC, Math_Vec3f_Pitch(&sp34, &sp40) - this->unk_3C0, 4, 0x2AA8); + this->unk_3BC = CLAMP(this->unk_3BC, -0x1554, 0x1554); + + Math_ApproachS(&this->unk_3C0, Math_Vec3f_Pitch(&sp34, &sp40) - this->unk_3BC, 4, 0x2AA8); + this->unk_3C0 = CLAMP(this->unk_3C0, -0xE38, 0xE38); +} + +void func_8094F2E8(EnGm* this) { + if ((this->unk_3A4 & 0x20) && (this->unk_268 != NULL) && (this->unk_268->update != NULL)) { + if (DECR(this->unk_3C6) == 0) { + func_8094F0E0(this); + this->unk_3A4 &= ~0x200; + this->unk_3A4 |= 0x80; + return; + } + } + + if (this->unk_3A4 & 0x80) { + this->unk_3A4 &= ~0x80; + this->unk_3BC = 0; + this->unk_3BE = 0; + this->unk_3C0 = 0; + this->unk_3C2 = 0; + this->unk_3C6 = 20; + } else if (DECR(this->unk_3C6) == 0) { + this->unk_3A4 |= 0x200; + } +} + +void func_8094F3D0(EnGm* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 sp28 = func_80152498(&globalCtx->msgCtx); + s32 var = globalCtx->msgCtx.unk11F04; + + if ((&this->actor == player->targetActor) && ((var < 0xFF) || (var > 0x200)) && (sp28 == 3) && + (this->unk_3F0 == 3)) { + if ((globalCtx->state.frames % 3) == 0) { + if (this->unk_3AC == 120.0f) { + this->unk_3AC = 0.0f; + } else { + this->unk_3AC = 120.0f; + } + } + } else { + this->unk_3AC = 0.0f; + } + Math_SmoothStepToF(&this->unk_3B0, this->unk_3AC, 0.8f, 40.0f, 10.0f); + Matrix_InsertTranslation(this->unk_3B0, 0.0f, 0.0f, 1); + this->unk_3F0 = sp28; +} + +s32 func_8094F4EC(EnGm* this, GlobalContext* globalCtx) { + if ((this->unk_258 != 6) && (this->unk_3E8 == 12)) { + this->unk_3A4 &= ~0x2000; + func_8094E054(this, globalCtx, 8); + } + return true; +} + +s32 func_8094F53C(EnGm* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + u16 sp32 = globalCtx->msgCtx.unk11F04; + Actor* al = func_8094DEE0(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_AL); + Actor* toto = func_8094DEE0(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_TOTO); + + if (player->stateFlags1 & 0x440) { + this->unk_3A4 |= 0x400; + if (this->unk_3A6 != sp32) { + switch (sp32) { + case 0x2B13: + func_8094E054(this, globalCtx, 2); + break; + + case 0x2B14: + case 0x2B18: + func_8094E054(this, globalCtx, 0); + break; + + case 0x2B16: + func_8094E054(this, globalCtx, 1); + break; + + case 0x2B15: + func_8094E054(this, globalCtx, 5); + break; + + case 0x2B17: + func_8094E054(this, globalCtx, 6); + break; + + default: + if ((this->unk_3E8 == 7) || (this->unk_3E8 == 8)) { + this->unk_3A4 |= 0x2000; + func_8094E054(this, globalCtx, 12); + } + break; + } + + switch (sp32) { + case 0x2AA6: + case 0x2AAF: + case 0x2AB4: + if ((al != NULL) && (al->update != NULL)) { + this->unk_268 = al; + } + break; + + case 0x2AAD: + case 0x2AB0: + case 0x2AB2: + if ((toto != NULL) && (toto->update != NULL)) { + this->unk_268 = toto; + } + break; + } + + if (sp32 == 0x2AA8) { + this->unk_3C8 = 0; + this->unk_3CA = 0; + this->unk_3CC = 8; + } + } + this->unk_3A6 = sp32; + } else if (this->unk_3A4 & 0x400) { + this->unk_18C = NULL; + this->unk_3A6 = 0; + this->unk_3A4 &= ~0x400; + this->unk_3CA = this->unk_3C8; + this->unk_3CC = 4; + func_8094F4EC(this, globalCtx); + } + + if (this->unk_18C != NULL) { + this->unk_18C(this, globalCtx); + } + + if ((this->unk_3E8 == 6) && !(globalCtx->actorCtx.unk5 & 0x20) && Animation_OnFrame(&this->skelAnime, 20.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_HANKO); + } + + return false; +} + +s32 func_8094F7D0(EnGm* this, GlobalContext* globalCtx, struct_80133038_arg2* arg2, u8 arg3, s16 arg4) { + u8 sp4F = ENGM_GET_FF(&this->actor); + Vec3s* sp48; + Vec3f sp3C; + Vec3f sp30; + Actor* actor; + s32 pad; + s32 ret = false; + + this->unk_234 = NULL; + actor = func_8094DEE0(this, globalCtx, arg3, arg4); + + if (D_80951A0C[arg2->unk0] >= 0) { + this->unk_234 = func_8013BB34(globalCtx, sp4F, D_80951A0C[arg2->unk0]); + } + + if ((actor != NULL) && (actor->update != NULL)) { + if (this->unk_234 != NULL) { + sp48 = (Vec3s*)Lib_SegmentedToVirtual(this->unk_234->points); + Math_Vec3s_ToVec3f(&sp3C, &sp48[this->unk_234->count - 2]); + Math_Vec3s_ToVec3f(&sp30, &sp48[this->unk_234->count - 1]); + this->actor.shape.shadowDraw = NULL; + this->actor.world.rot.y = Math_Vec3f_Yaw(&sp3C, &sp30); + Math_Vec3f_Copy(&this->actor.world.pos, &sp30); + ret = true; + } + } + return ret; +} + +s32 func_8094F904(EnGm* this, GlobalContext* globalCtx, struct_80133038_arg2* arg2) { + u16 sp56 = gSaveContext.time - 0x3FFC; + u8 sp55 = ENGM_GET_FF(&this->actor); + EnDoor* sp50; + Vec3s* sp4C; + Vec3f sp40; + Vec3f sp34; + s32 pad; + s32 ret = false; + + this->unk_234 = NULL; + sp50 = func_8094DF90(globalCtx, arg2->unk0); + + if (D_80951A0C[arg2->unk0] >= 0) { + this->unk_234 = func_8013BB34(globalCtx, sp55, D_80951A0C[arg2->unk0]); + } + + if ((sp50 != NULL) && (sp50->actor.update != NULL)) { + if (this->unk_234 != NULL) { + sp4C = (Vec3s*)Lib_SegmentedToVirtual(this->unk_234->points); + Math_Vec3s_ToVec3f(&sp40, &sp4C[0]); + Math_Vec3s_ToVec3f(&sp34, &sp4C[1]); + Math_Vec3f_Copy(&this->unk_278, &sp40); + Math_Vec3f_Copy(&this->unk_284, &sp34); + this->actor.world.rot.y = Math_Vec3f_Yaw(&sp40, &sp34); + Math_Vec3f_Copy(&this->actor.world.pos, &sp40); + + if (ABS_ALT(BINANG_SUB(this->actor.world.rot.y, sp50->actor.shape.rot.y)) <= 0x4000) { + this->unk_261 = -75; + } else { + this->unk_261 = 75; + } + + this->unk_3B8 = arg2->unk8 - arg2->unk4; + this->unk_3BA = sp56 - arg2->unk4; + this->actor.flags &= ~1; + this->unk_3A4 |= 0x100; + this->unk_3A4 |= 0x200; + func_8094E054(this, globalCtx, 7); + this->actor.gravity = 0.0f; + ret = true; + } + } + return ret; +} + +s32 func_8094FAC4(EnGm* this, GlobalContext* globalCtx, struct_80133038_arg2* arg2) { + u16 sp2E = gSaveContext.time - 0x3FFC; + u16 phi_v1; + u8 sp2B = ENGM_GET_FF(&this->actor); + s32 pad; + s32 ret = false; + + this->unk_234 = NULL; + if (D_80951A0C[arg2->unk0] >= 0) { + this->unk_234 = func_8013BB34(globalCtx, sp2B, D_80951A0C[arg2->unk0]); + } + + if ((this->unk_234 != NULL) && (this->unk_234->count < 3)) { + this->unk_234 = NULL; + } + + if (this->unk_234 != NULL) { + if ((this->unk_258 < 9) && (this->unk_258 != 0) && (this->unk_3C4 >= 0)) { + phi_v1 = sp2E; + } else { + phi_v1 = arg2->unk4; + } + + if (arg2->unk8 < phi_v1) { + this->unk_248 = (phi_v1 - arg2->unk8) + 0xFFFF; + } else { + this->unk_248 = arg2->unk8 - phi_v1; + } + + this->unk_254 = sp2E - phi_v1; + phi_v1 = this->unk_234->count - 2; + this->unk_24C = this->unk_248 / phi_v1; + this->unk_250 = (this->unk_254 / this->unk_24C) + 2; + this->unk_3A4 &= ~0x8; + this->unk_3A4 &= ~0x10; + func_8013AED4(&this->unk_3A4, 3, 7); + this->unk_3A4 |= 0x100; + this->unk_3A4 |= 0x200; + func_8094E054(this, globalCtx, 7); + this->actor.gravity = -1.0f; + ret = true; + } + return ret; +} + +s32 func_8094FCC4(EnGm* this, GlobalContext* globalCtx, struct_80133038_arg2* arg2) { + static Vec3f D_80951D90 = { 64.0f, 0.0f, -122.0f }; + s32 ret = false; + + if (func_8094F7D0(this, globalCtx, arg2, ACTORCAT_NPC, ACTOR_EN_TAB)) { + if (this->unk_258 == 0) { + Math_Vec3f_Copy(&this->actor.world.pos, &D_80951D90); + func_8013AED4(&this->unk_3A4, 3, 7); + func_8094E054(this, globalCtx, 0); + } else { + func_8094E054(this, globalCtx, 9); + this->skelAnime.moveFlags = 0x10; + } + this->unk_3A4 |= 0x100; + this->unk_3A4 |= 0x200; + ret = true; + } + return ret; +} + +s32 func_8094FD88(EnGm* this, GlobalContext* globalCtx, struct_80133038_arg2* arg2) { + s32 ret = false; + + if (func_8094F7D0(this, globalCtx, arg2, ACTORCAT_NPC, ACTOR_EN_RECEPGIRL)) { + func_8094E054(this, globalCtx, 11); + func_8013AED4(&this->unk_3A4, 3, 7); + this->unk_3A4 |= 0x100; + this->unk_3A4 |= 0x200; + ret = true; + } + return ret; +} + +s32 func_8094FE10(EnGm* this, GlobalContext* globalCtx, struct_80133038_arg2* arg2) { + s32 ret = false; + Actor* al; + + al = func_8094DEE0(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_AL); + if (func_8094F7D0(this, globalCtx, arg2, ACTORCAT_NPC, ACTOR_EN_TOTO) && (al != NULL) && (al->update != NULL)) { + func_8094E054(this, globalCtx, 11); + func_8013AED4(&this->unk_3A4, 3, 7); + this->unk_268 = al; + if (!(gSaveContext.weekEventReg[86] & 0x20)) { + this->unk_3C8 = 2; + this->unk_3CA = 2; + this->unk_3CC = 8; + } + this->unk_3A4 |= (0x100 | 0x20); + this->unk_3A4 |= 0x200; + ret = true; + } + return ret; +} + +s32 func_8094FF04(EnGm* this, GlobalContext* globalCtx, struct_80133038_arg2* arg2) { + static Vec3f D_80951D9C = { 64.0f, 0.0f, -122.0f }; + u8 sp4F = ENGM_GET_FF(&this->actor); + Vec3s* sp48; + Vec3f sp3C; + Vec3f sp30; + s32 pad; + s32 ret = false; + + this->unk_234 = NULL; + + if (D_80951A0C[arg2->unk0] >= 0) { + this->unk_234 = func_8013BB34(globalCtx, sp4F, D_80951A0C[arg2->unk0]); + } + + if (this->unk_234 != NULL) { + sp48 = (Vec3s*)Lib_SegmentedToVirtual(this->unk_234->points); + Math_Vec3s_ToVec3f(&sp3C, &sp48[this->unk_234->count - 2]); + Math_Vec3s_ToVec3f(&sp30, &sp48[this->unk_234->count - 1]); + this->actor.shape.shadowDraw = NULL; + this->actor.world.rot.y = Math_Vec3f_Yaw(&sp3C, &sp30); + if (this->unk_258 == 0) { + Math_Vec3f_Copy(&this->actor.world.pos, &D_80951D9C); + func_8013AED4(&this->unk_3A4, 3, 7); + this->unk_3C8 = 4; + this->unk_3CA = 4; + this->unk_3CC = 8; + func_8094E054(this, globalCtx, 0); + func_8094E278(globalCtx); + } else { + Math_Vec3f_Copy(&this->actor.world.pos, &sp30); + func_8094E054(this, globalCtx, 9); + this->skelAnime.moveFlags = 0x10; + } + this->unk_400 = 0; + this->unk_3A4 |= 0x100; + this->unk_3A4 |= 0x200; + ret = true; + } + return ret; +} + +s32 func_80950088(EnGm* this, GlobalContext* globalCtx, struct_80133038_arg2* arg2) { + static Vec3f D_80951DA8 = { 278.0f, 0.0f, 223.0f }; + static Vec3s D_80951DB4 = { 0x0000, 0xC000, 0x0000 }; + s32 pad; + + Math_Vec3f_Copy(&this->actor.world.pos, &D_80951DA8); + Math_Vec3s_Copy(&this->actor.world.rot, &D_80951DB4); + Math_Vec3s_Copy(&this->actor.shape.rot, &this->actor.world.rot); + func_8013AED4(&this->unk_3A4, 3, 7); + this->unk_3A4 |= (0x2000 | 0x100); + this->unk_3A4 |= 0x200; + func_8094E054(this, globalCtx, 12); + return true; +} + +s32 func_80950120(EnGm* this, GlobalContext* globalCtx, struct_80133038_arg2* arg2) { + static Vec3f D_80951DBC = { -525.0f, 214.0f, 515.0f }; + static Vec3s D_80951DC8 = { 0x0000, 0x38E0, 0x0000 }; + s32 pad; + + Math_Vec3f_Copy(&this->actor.world.pos, &D_80951DBC); + Math_Vec3s_Copy(&this->actor.world.rot, &D_80951DC8); + Math_Vec3s_Copy(&this->actor.shape.rot, &this->actor.world.rot); + func_8013AED4(&this->unk_3A4, 3, 7); + this->unk_3A4 |= (0x800 | 0x100); + this->unk_3A4 |= 0x200; + func_8094E054(this, globalCtx, 4); + return true; +} + +s32 func_809501B8(EnGm* this, GlobalContext* globalCtx, struct_80133038_arg2* arg2) { + static Vec3f D_80951DD0 = { -334.0f, 225.0f, 903.0f }; + static Vec3s D_80951DDC = { 0x0000, 0x7FFF, 0x0000 }; + s32 pad; + + Math_Vec3f_Copy(&this->actor.world.pos, &D_80951DD0); + Math_Vec3s_Copy(&this->actor.world.rot, &D_80951DDC); + Math_Vec3s_Copy(&this->actor.shape.rot, &this->actor.world.rot); + this->actor.targetMode = 6; + func_8013AED4(&this->unk_3A4, 3, 7); + this->unk_3A4 |= (0x1000 | 0x100); + this->unk_3A4 |= 0x200; + this->unk_3C8 = 3; + this->unk_3CA = 3; + this->unk_3CC = 8; + this->actor.targetMode = 6; + this->unk_3B4 = 60.0f; + func_8094E054(this, globalCtx, 10); + return true; +} + +s32 func_80950280(EnGm* this, GlobalContext* globalCtx, struct_80133038_arg2* arg2) { + s32 phi_v1; + + this->actor.flags |= 1; + this->actor.targetMode = 0; + this->unk_3A4 = 0; + this->unk_3C8 = 0; + this->unk_3CA = 0; + this->unk_3CC = 8; + this->unk_3B4 = 40.0f; + + switch (arg2->unk0) { + case 1: + phi_v1 = func_8094FD88(this, globalCtx, arg2); + break; + + case 2: + phi_v1 = func_8094FE10(this, globalCtx, arg2); + break; + + case 3: + phi_v1 = func_8094FCC4(this, globalCtx, arg2); + break; + + case 5: + phi_v1 = func_8094FF04(this, globalCtx, arg2); + break; + + case 6: + phi_v1 = func_80950088(this, globalCtx, arg2); + break; + + case 7: + phi_v1 = func_809501B8(this, globalCtx, arg2); + break; + + case 8: + phi_v1 = func_80950120(this, globalCtx, arg2); + break; + + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + phi_v1 = func_8094F904(this, globalCtx, arg2); + break; + + case 21: + case 22: + case 23: + case 24: + case 25: + case 26: + case 27: + case 28: + case 29: + case 30: + phi_v1 = func_8094FAC4(this, globalCtx, arg2); + break; + + default: + phi_v1 = false; + break; + } + + return phi_v1; +} + +s32 func_80950388(EnGm* this, GlobalContext* globalCtx) { + Vec3f sp2C; + Vec3f sp20; + + if ((this->unk_268 != NULL) && (this->unk_268->update != NULL)) { + Math_Vec3f_Copy(&sp2C, &this->unk_268->world.pos); + Math_Vec3f_Copy(&sp20, &this->actor.world.pos); + this->actor.world.rot.y = Math_Vec3f_Yaw(&sp20, &sp2C); + } + + return false; +} + +s32 func_809503F8(EnGm* this, GlobalContext* globalCtx) { + s32 pad; + + if (this->unk_3E8 == 9) { + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->actor.shape.shadowDraw = func_800B3FC0; + func_8013AED4(&this->unk_3A4, 3, 7); + func_8094E054(this, globalCtx, 0); + } else { + AnimationContext_SetMoveActor(globalCtx, &this->actor, &this->skelAnime, 1.0f); + } + } + return false; +} + +s32 func_80950490(EnGm* this, GlobalContext* globalCtx) { + static s32 D_80951DE4[] = { + 1, 5, 5, 1, 6, 5, 1, 5, 6, 1, 5, 6, + }; + s32 pad; + + if ((gSaveContext.weekEventReg[50] & 1) || (gSaveContext.weekEventReg[51] & 0x80)) { + if (this->unk_400 == 0) { + this->unk_3C8 = 1; + this->unk_3CA = 1; + this->unk_3CC = 8; + this->unk_400 = 1; + func_8094E054(this, globalCtx, 3); + } + return false; + } + + this->unk_400 = 0; + + switch (this->unk_3E8) { + case 9: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->actor.shape.shadowDraw = func_800B3FC0; + func_8013AED4(&this->unk_3A4, 3, 7); + this->unk_3C8 = 4; + this->unk_3CA = 4; + this->unk_3CC = 8; + func_8094E054(this, globalCtx, 0); + func_8094E278(globalCtx); + } else { + AnimationContext_SetMoveActor(globalCtx, &this->actor, &this->skelAnime, 1.0f); + } + break; + + case 5: + case 6: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + func_8094E054(this, globalCtx, D_80951DE4[this->unk_3F4]); + this->unk_3F4++; + this->unk_3F4 %= 12; + this->unk_3DE = Rand_S16Offset(30, 30); + } + break; + + default: + if (DECR(this->unk_3DE) == 0) { + func_8094E054(this, globalCtx, D_80951DE4[this->unk_3F4]); + this->unk_3F4++; + this->unk_3F4 %= 12; + this->unk_3DE = Rand_S16Offset(30, 30); + } + break; + } + return false; +} + +s32 func_80950690(EnGm* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Actor* al; + Actor* toto; + + switch (this->unk_258) { + case 2: + al = func_8094DEE0(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_AL); + toto = func_8094DEE0(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_TOTO); + if ((al != NULL) && (al->update != NULL) && (toto != NULL) && (toto->update != NULL) && + !(player->stateFlags1 & 0x40)) { + if (DECR(this->unk_3B8) == 0) { + if (al == this->unk_268) { + this->unk_268 = toto; + } else { + this->unk_268 = al; + } + this->unk_3B8 = Rand_S16Offset(60, 60); + } + } + break; + + case 7: + this->unk_3D0 += 992; + if (DECR(this->unk_3B8) == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_VO_GO_SLEEP); + this->unk_3B8 = 30; + } + break; + + case 8: + break; + } + + func_8013D9C8(globalCtx, this->unk_3D8, this->unk_3D2, ARRAY_COUNT(this->unk_3D2)); + + return false; +} + +s32 func_80950804(EnGm* this, GlobalContext* globalCtx) { + EnDoor* sp44; + Vec3f sp38; + s32 pad; + f32 temp_f0; + + sp44 = func_8094DF90(globalCtx, this->unk_258); + if (!func_8013AD6C(globalCtx) && (this->unk_3C4 != 0)) { + if ((sp44 != NULL) && (sp44->actor.update != NULL)) { + if ((this->unk_3BA / (f32)this->unk_3B8) <= 0.9f) { + sp44->unk_1A7 = this->unk_261; + } else { + sp44->unk_1A7 = 0; + } + } + + this->unk_3BA = CLAMP(this->unk_3BA, 0, this->unk_3B8); + temp_f0 = Math_Vec3f_DistXZ(&this->unk_278, &this->unk_284) / this->unk_3B8; + sp38.x = 0.0f; + sp38.y = 0.0f; + sp38.z = this->unk_3BA * temp_f0; + Lib_Vec3f_TranslateAndRotateY(&this->unk_278, this->actor.world.rot.y, &sp38, &this->actor.world.pos); + this->unk_3BA += this->unk_3C4; + if (Animation_OnFrame(&this->skelAnime, 3.0f) || Animation_OnFrame(&this->skelAnime, 13.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_PIRATE_WALK); + } + } + + return false; +} + +s32 func_8095097C(EnGm* this, GlobalContext* globalCtx) { + f32 sp7C[0x109]; + Vec3f sp70; + Vec3f sp64; + Vec3f sp58; + s32 sp54 = 0; + s32 sp50 = 0; + s32 pad2; + + func_8013AF00(sp7C, 3, this->unk_234->count + 3); + + if (!(this->unk_3A4 & 8)) { + sp58 = gZeroVec3f; + func_8013B6B0(this->unk_234, &this->unk_244, &this->unk_254, this->unk_24C, this->unk_248, &this->unk_250, sp7C, + &sp58, this->unk_3C4); + func_8013B878(globalCtx, this->unk_234, this->unk_250, &sp58); + this->actor.world.pos.y = sp58.y; + this->unk_3A4 |= 8; + } else { + sp58 = this->unk_238; + } + + this->actor.world.pos.x = sp58.x; + this->actor.world.pos.z = sp58.z; + + if (func_8013AD6C(globalCtx)) { + sp54 = this->unk_254; + sp50 = this->unk_250; + sp58 = this->actor.world.pos; + } + + this->unk_238 = gZeroVec3f; + + if (func_8013B6B0(this->unk_234, &this->unk_244, &this->unk_254, this->unk_24C, this->unk_248, &this->unk_250, sp7C, + &this->unk_238, this->unk_3C4)) { + this->unk_3A4 |= 0x10; + } else { + sp70 = this->actor.world.pos; + sp64 = this->unk_238; + this->actor.world.rot.y = Math_Vec3f_Yaw(&sp70, &sp64); + } + + if (func_8013AD6C(globalCtx)) { + this->unk_254 = sp54; + this->unk_250 = sp50; + this->unk_238 = sp58; + } else if (Animation_OnFrame(&this->skelAnime, 3.0f) || Animation_OnFrame(&this->skelAnime, 13.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_PIRATE_WALK); + } + return false; +} + +void func_80950C24(EnGm* this, GlobalContext* globalCtx) { + switch (this->unk_258) { + case 1: + func_80950388(this, globalCtx); + break; + + case 2: + case 6: + case 7: + case 8: + func_80950690(this, globalCtx); + break; + + case 3: + func_809503F8(this, globalCtx); + break; + + case 5: + func_80950490(this, globalCtx); + break; + + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + func_80950804(this, globalCtx); + break; + + case 21: + case 22: + case 23: + case 24: + case 25: + case 26: + case 27: + case 28: + case 29: + case 30: + func_8095097C(this, globalCtx); + break; + } + + Math_ApproachS(&this->actor.shape.rot.y, this->actor.world.rot.y, 3, 0x2AA8); +} + +void func_80950CDC(EnGm* this, GlobalContext* globalCtx) { + u32* unk_14 = &gSaveContext.unk_14; + struct_80133038_arg2 sp20; + + this->unk_3C4 = REG(15) + *unk_14; + + if (!func_80133038(globalCtx, (void*)&D_80951820, &sp20) || + ((this->unk_258 != sp20.unk0) && !func_80950280(this, globalCtx, &sp20))) { + this->actor.shape.shadowDraw = NULL; + this->actor.flags &= ~1; + sp20.unk0 = 0; + } else { + this->actor.shape.shadowDraw = func_800B3FC0; + this->actor.flags |= 1; + } + this->unk_258 = sp20.unk0; + this->unk_268 = func_8094F074(this, globalCtx); + func_80950C24(this, globalCtx); +} + +void func_80950DB8(EnGm* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp40; + Vec3f sp34; + Actor* al; + + if (func_8010BF58(&this->actor, globalCtx, this->unk_264, this->unk_3E4, &this->unk_25C)) { + func_8013AED4(&this->unk_3A4, 3, 7); + al = func_8094DEE0(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_AL); + if ((this->unk_258 == 2) && (al != NULL) && (al->update != NULL)) { + this->unk_268 = al; + this->unk_3B8 = Rand_S16Offset(60, 60); + } else { + this->unk_3A4 &= ~0x20; + } + this->unk_3A4 |= 0x200; + this->unk_3C6 = 20; + this->unk_25C = 0; + this->actionFunc = func_80950CDC; + } else if ((this->unk_258 != 1) && (this->unk_258 != 2) && (this->unk_258 != 3) && (this->unk_258 != 5) && + (this->unk_258 != 7)) { + if ((this->unk_268 != NULL) && (this->unk_268->update != NULL)) { + Math_Vec3f_Copy(&sp40, &this->unk_268->world.pos); + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + Math_ApproachS(&this->actor.shape.rot.y, Math_Vec3f_Yaw(&sp34, &sp40), 4, 0x2AA8); + } + } + func_8013D9C8(globalCtx, this->unk_3D8, this->unk_3D2, 3); +} + +void func_80950F2C(EnGm* this, GlobalContext* globalCtx) { + s32 sp50[] = { + 0, + 0, + 3, + 2, + }; + Player* player = GET_PLAYER(globalCtx); + s32 pad; + Vec3f sp3C; + Vec3f sp30; + s32 sp2C; + s16 yaw; + + if (func_800EE29C(globalCtx, 0x20E)) { + sp2C = globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x20E)]->unk0; + if (this->unk_259 != (sp2C & 0xFF)) { + if (sp2C == 3) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_CHAIR_ROLL); + } + this->unk_259 = sp2C; + func_8094E054(this, globalCtx, sp50[sp2C]); + } + + if ((this->unk_259 == 3) && (this->unk_268 != NULL) && (this->unk_268->update != NULL)) { + Math_Vec3f_Copy(&sp3C, &player->actor.world.pos); + Math_Vec3f_Copy(&sp30, &this->actor.world.pos); + yaw = Math_Vec3f_Yaw(&sp30, &sp3C); + if ((this->actor.shape.rot.y / 0x16C) != (yaw / 0x16C)) { + Math_ApproachS(&this->actor.shape.rot.y, yaw, 3, 0x2AA8); + this->unk_3A4 &= ~0x20; + } else { + this->actor.shape.rot.y = yaw; + } + } + } +} + +void EnGm_Init(Actor* thisx, GlobalContext* globalCtx) { + EnGm* this = THIS; + + if (func_8094DEE0(this, globalCtx, ACTORCAT_NPC, ACTOR_EN_GM)) { + Actor_MarkForDeath(&this->actor); + return; + } + + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 22.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_060078B0, NULL, this->jointTable, this->morphTable, 20); + this->unk_3E8 = -1; + func_8094E054(this, globalCtx, 0); + Collider_InitAndSetCylinder(globalCtx, &this->colliderCylinder, &this->actor, &sCylinderInit); + Collider_InitAndSetSphere(globalCtx, &this->colliderSphere, &this->actor, &sSphereInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(0x16), &sColChkInfoInit); + Actor_SetScale(&this->actor, 0.01f); + this->actor.room = -1; + this->unk_260 = -128; + this->unk_3FC = 0; + this->unk_258 = 0; + this->actionFunc = func_80950CDC; + this->actionFunc(this, globalCtx); +} + +void EnGm_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnGm* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->colliderCylinder); + Collider_DestroySphere(globalCtx, &this->colliderSphere); +} + +void EnGm_Update(Actor* thisx, GlobalContext* globalCtx) { + EnGm* this = THIS; + + if (!func_8094E0F8(this, globalCtx)) { + if (!func_8094EE84(this, globalCtx) && func_8094EFC4(this, globalCtx)) { + func_80950F2C(this, globalCtx); + func_8094DFF8(this, globalCtx); + func_8094E2D0(this); + return; + } + + this->actionFunc(this, globalCtx); + + func_8094F53C(this, globalCtx); + + if (this->unk_258 != 0) { + func_8094DFF8(this, globalCtx); + func_8094E2D0(this); + func_8094F2E8(this); + func_8013C964(&this->actor, globalCtx, this->unk_3B4, 30.0f, 0, this->unk_3A4 & 7); + if ((this->unk_258 != 3) && (this->unk_258 != 5) && (this->unk_258 != 8)) { + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 4); + } + func_8094E1DC(this, globalCtx); + } + } +} + +s32 func_809513AC(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + s32 pad; + EnGm* this = THIS; + s32 phi_v0; + + if (limbIndex == 16) { + func_8094F3D0(this, globalCtx); + } + + switch (limbIndex) { + case 9: + phi_v0 = 0; + break; + + case 10: + phi_v0 = 1; + break; + + case 13: + phi_v0 = 2; + break; + + default: + phi_v0 = 9; + break; + } + + if ((this->unk_3A4 & 0x2000) && (phi_v0 < 9)) { + rot->y += (s16)(Math_SinS(this->unk_3D8[phi_v0]) * 200.0f); + rot->z += (s16)(Math_CosS(this->unk_3D2[phi_v0]) * 200.0f); + } + + return false; +} + +void func_809514BC(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Vec3f D_80951E24 = { 1400.0f, 0.0f, 0.0f }; + EnGm* this = THIS; + s32 pad[4]; + Vec3f sp30; + s32 pad2; + + if ((ActorCutscene_GetCurrentIndex() == -1) && (limbIndex == 16)) { + Matrix_MultiplyVector3fByState(&D_80951E24, &this->actor.focus.pos); + Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.world.rot); + } + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if ((limbIndex == 15) && (this->unk_3A4 & 0x800)) { + gSPDisplayList(POLY_OPA_DISP++, D_06007528); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + if (limbIndex == 9) { + Matrix_MultiplyVector3fByState(&gZeroVec3f, &sp30); + Math_Vec3f_ToVec3s(&this->colliderSphere.dim.worldSphere.center, &sp30); + } +} + +void func_80951594(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnGm* this = THIS; + s32 phi_v0 = 1; + s32 phi_v1 = 0; + + if (!(this->unk_3A4 & 0x200)) { + if (this->unk_3A4 & 0x80) { + phi_v0 = 1; + phi_v1 = 1; + } else { + phi_v0 = 0; + phi_v1 = 1; + } + } else { + phi_v0 = 0; + } + + if (limbIndex == 16) { + func_8013AD9C(BINANG_ADD(this->unk_3BC + this->unk_3C0, 0x4000), + BINANG_ADD(this->unk_3BE + this->unk_3C2 + this->actor.shape.rot.y, 0x4000), &this->unk_290, + &this->unk_2A8, phi_v1, phi_v0); + Matrix_StatePop(); + Matrix_InsertTranslation(this->unk_290.x, this->unk_290.y, this->unk_290.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateY(this->unk_2A8.y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->unk_2A8.x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->unk_2A8.z, MTXMODE_APPLY); + Matrix_StatePush(); + } else if (limbIndex == 9) { + func_8013AD9C(BINANG_ADD(this->unk_3C0, 0x4000), BINANG_ADD(this->unk_3C2 + this->actor.shape.rot.y, 0x4000), + &this->unk_29C, &this->unk_2AE, phi_v1, phi_v0); + Matrix_StatePop(); + Matrix_InsertTranslation(this->unk_29C.x, this->unk_29C.y, this->unk_29C.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateY(this->unk_2AE.y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->unk_2AE.x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->unk_2AE.z, MTXMODE_APPLY); + Matrix_StatePush(); + } +} + +void EnGm_Draw(Actor* thisx, GlobalContext* globalCtx) { + static UNK_PTR D_80951E30[] = { &D_060054A8, &D_06005028, &D_06006828, &D_06005028, &D_06005CE8, &D_06006C68 }; + EnGm* this = THIS; + + if ((this->unk_258 != 0) && (this->unk_262 >= 0)) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80951E30[this->unk_3CE])); + + func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + func_809513AC, func_809514BC, func_80951594, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} diff --git a/src/overlays/actors/ovl_En_Gm/z_en_gm.h b/src/overlays/actors/ovl_En_Gm/z_en_gm.h index 177254711..63b6b8f57 100644 --- a/src/overlays/actors/ovl_En_Gm/z_en_gm.h +++ b/src/overlays/actors/ovl_En_Gm/z_en_gm.h @@ -6,12 +6,74 @@ struct EnGm; typedef void (*EnGmActionFunc)(struct EnGm*, GlobalContext*); +typedef s32 (*EnGmUnkFunc)(struct EnGm*, GlobalContext*); +typedef void (*EnGmUnkFunc2)(struct EnGm*, GlobalContext*); + +#define ENGM_GET_FF(thisx) ((thisx)->params & 0xFF) typedef struct EnGm { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnGmActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x278]; + /* 0x018C */ EnGmUnkFunc2 unk_18C; + /* 0x0190 */ ColliderCylinder colliderCylinder; + /* 0x01DC */ ColliderSphere colliderSphere; + /* 0x0234 */ Path* unk_234; + /* 0x0238 */ Vec3f unk_238; + /* 0x0244 */ f32 unk_244; + /* 0x0248 */ s32 unk_248; + /* 0x024C */ s32 unk_24C; + /* 0x0250 */ s32 unk_250; + /* 0x0254 */ s32 unk_254; + /* 0x0258 */ u8 unk_258; + /* 0x0259 */ u8 unk_259; + /* 0x025C */ s32 unk_25C; + /* 0x0260 */ s8 unk_260; + /* 0x0261 */ s8 unk_261; + /* 0x0262 */ s8 unk_262; + /* 0x0264 */ s32* unk_264; + /* 0x0268 */ Actor* unk_268; + /* 0x026C */ UNK_TYPE1 unk26C[0xC]; + /* 0x0278 */ Vec3f unk_278; + /* 0x0284 */ Vec3f unk_284; + /* 0x0290 */ Vec3f unk_290; + /* 0x029C */ Vec3f unk_29C; + /* 0x02A8 */ Vec3s unk_2A8; + /* 0x02AE */ Vec3s unk_2AE; + /* 0x02B4 */ Vec3s jointTable[20]; + /* 0x032C */ Vec3s morphTable[20]; + /* 0x03A4 */ u16 unk_3A4; + /* 0x03A6 */ u16 unk_3A6; + /* 0x03A8 */ f32 unk_3A8; + /* 0x03AC */ f32 unk_3AC; + /* 0x03B0 */ f32 unk_3B0; + /* 0x03B4 */ f32 unk_3B4; + /* 0x03B8 */ s16 unk_3B8; + /* 0x03BA */ s16 unk_3BA; + /* 0x03BC */ s16 unk_3BC; + /* 0x03BE */ s16 unk_3BE; + /* 0x03C0 */ s16 unk_3C0; + /* 0x03C2 */ s16 unk_3C2; + /* 0x03C4 */ s16 unk_3C4; + /* 0x03C6 */ s16 unk_3C6; + /* 0x03C8 */ s16 unk_3C8; + /* 0x03CA */ s16 unk_3CA; + /* 0x03CC */ s16 unk_3CC; + /* 0x03CE */ s16 unk_3CE; + /* 0x03D0 */ s16 unk_3D0; + /* 0x03D2 */ s16 unk_3D2[3]; + /* 0x03D8 */ s16 unk_3D8[3]; + /* 0x03DE */ s16 unk_3DE; + /* 0x03E0 */ s16 unk_3E0; + /* 0x03E2 */ s16 unk_3E2; + /* 0x03E4 */ EnGmUnkFunc unk_3E4; + /* 0x03E8 */ s32 unk_3E8; + /* 0x03EC */ UNK_TYPE1 unk3EC[0x4]; + /* 0x03F0 */ s32 unk_3F0; + /* 0x03F4 */ s32 unk_3F4; + /* 0x03F8 */ s32 unk_3F8; + /* 0x03FC */ s32 unk_3FC; + /* 0x0400 */ s32 unk_400; } EnGm; // size = 0x404 extern const ActorInit En_Gm_InitVars; diff --git a/src/overlays/actors/ovl_En_Go/z_en_go.c b/src/overlays/actors/ovl_En_Go/z_en_go.c index a79aef7ea..0f7bb8fb7 100644 --- a/src/overlays/actors/ovl_En_Go/z_en_go.c +++ b/src/overlays/actors/ovl_En_Go/z_en_go.c @@ -5,6 +5,10 @@ */ #include "z_en_go.h" +#include "objects/object_oF1d_map/object_oF1d_map.h" +#include "objects/object_hakugin_demo/object_hakugin_demo.h" +#include "objects/object_taisou/object_taisou.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x02000019 @@ -23,8 +27,56 @@ void func_80A14EB0(EnGo* this, GlobalContext* globalCtx); void func_80A14FC8(EnGo* this, GlobalContext* globalCtx); void func_80A153FC(EnGo* this, GlobalContext* globalCtx); void func_80A157C4(EnGo* this, GlobalContext* globalCtx); +void func_80A15FEC(Actor* thisx, GlobalContext* globalCtx); + +static s32 D_80A16100[] = { + 0x00150800, 0x40010022, 0x00150200, 0x180E0E10, 0x0C0F0E11, 0x0C0F0E12, 0x0C0F0E13, 0x0C0F0E14, 0x0C111502, + 0x100E0E15, 0x0C100015, 0x0400110E, 0x0E160C0F, 0x0E170C0F, 0x0E180C11, 0x15041610, 0x0E0E190C, 0x10001504, + 0x000D0100, 0x050E0E31, 0x0C100E0E, 0x2F0C1001, 0x00050E0E, 0x2D0C100E, 0x0E2B0C10, +}; + +static s32 D_80A16164[] = { + 0x00150800, 0x7E01004D, 0x00150400, 0x180E0E1A, 0x0C170F0E, 0x230C180F, 0x0E240C0F, 0x0E250C12, 0x16111508, + 0x100E0E1A, 0x0C170F0E, 0x230C180F, 0x0E240C0F, 0x0E250C17, 0x0F0E260C, 0x180F0E27, 0x0C170F0E, 0x280C180F, + 0x0E290C17, 0x0F0E2A0C, 0x16111508, 0x100E0E1A, 0x0C170F0E, 0x1B0C180F, 0x0E1C0C0F, 0x0E1D0C0F, 0x0E1E0C17, + 0x0F0E1F0C, 0x180F0E20, 0x0C170F0E, 0x210C0F0E, 0x220C1611, 0x15081000, 0x1504000D, 0x0100050E, 0x0E320C10, + 0x0E0E300C, 0x10010005, 0x0E0E2E0C, 0x100E0E2C, 0x0C100000, +}; + +static s32 D_80A16208[2] = { 0xE0E520C, 0x10000000 }; + +static s32 D_80A16210[17] = { + 0x160400, 0x38010010, 0xE0E430C, 0xF0E440C, 0xF0E450C, 0x11188010, 0x160800, 0x1B0E0E46, 0xC0F0E47, + 0xC0F0E48, 0xC0F0E49, 0xC0F0E4A, 0xC111608, 0x11188010, 0xE0E4B0C, 0x100E0E42, 0xC100000, +}; + +static s32 D_80A16254[11] = { + 0x160400, 0x22010009, 0xE0E4D0C, 0xF0E4E0C, 0x10001701, 0xC0E0E, + 0x4F0C0F0E, 0x500C1117, 0x1100E0E, 0x510C100E, 0xE4C0C10, +}; + +static s32 D_80A16280[52] = { + 0x1001200, 0x12200008, 0xE0C8E0C, 0x11122010, 0xE0C8F0C, 0x10001240, 0x1D0E0C, 0x800C1112, 0x40001280, + 0x742500, 0xC006F00, 0x13010045, 0xF0C810C, 0x19001300, 0x1280005E, 0x25000C00, 0x59001301, 0x2F0E0C, + 0x810C0F0C, 0x820C0500, 0x1A00, 0x1A300E0C, 0x830C1209, 0x700, 0xE0C84, 0x160C1113, 0x1100E0C, + 0x840C1031, 0xE0C850C, 0x1029FFF2, 0x130200, 0xF0E0C88, 0xC0F0C89, 0xC05000A, 0xFFE3FFE3, 0xE0C860C, + 0x11128019, 0x213019, 0xFFC02900, 0x2C0E0C8C, 0xC050000, 0x50000, 0x8006400, 0x6320E0C, 0x8D0C1030, + 0x14FF9C12, 0x6003400, 0x130034, 0x700000E, 0xC870C16, 0x100E0C8B, 0xC100000, +}; + +static s32 D_80A16350[27] = { + 0x584000, 0x2903000E, 0x2001301, 0x180058, 0x80005119, 0x1E0059, 0x1004919, 0x160059, 0x2004119, + 0xE0059, 0x4003919, 0x2F0E0D, 0x4D0C1210, 0xE0D480C, 0xF0D490C, 0xF0D4A0C, 0x5000000, 0xF000F30, + 0xE0D4B0C, 0x15090000, 0xE0D4D0C, 0x1210310E, 0xD4C0C12, 0x100E0D4E, 0xC19FFD8, 0xE0D4F0C, 0x19FFD500, +}; + +static s32 D_80A163BC[4] = { 0x100060E, 0xDFE0C12, 0x100E0DFF, 0xC121000 }; +static s32 D_80A163CC[4] = { 0x100060E, 0xE000C12, 0x100E0E01, 0xC121000 }; +static s32 D_80A163DC[4] = { 0x100060E, 0xE020C12, 0x100E0E03, 0xC121000 }; +static s32 D_80A163EC[4] = { 0x100060E, 0xE040C12, 0x100E0E05, 0xC121000 }; +static s32 D_80A163FC[4] = { 0x100060E, 0xE060C12, 0x100E0E07, 0xC121000 }; +static s32 D_80A1640C[2] = { 0xE023A0C, 0x12100000 }; -#if 0 const ActorInit En_Go_InitVars = { ACTOR_EN_GO, ACTORCAT_NPC, @@ -37,32 +89,69 @@ const ActorInit En_Go_InitVars = { (ActorFunc)NULL, }; -// static ColliderSphereInit sSphereInit = { -static ColliderSphereInit D_80A16434 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_SPHERE, }, - { ELEMTYPE_UNK0, { 0x20000000, 0x00, 0x04 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderSphereInit sSphereInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_SPHERE, + }, + { + ELEMTYPE_UNK0, + { 0x20000000, 0x00, 0x04 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 0 }, 100 }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A16460 = { - { COLTYPE_METAL, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER | AC_TYPE_OTHER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK2, { 0xF7CFFFFF, 0x02, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit1 = { + { + COLTYPE_METAL, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER | AC_TYPE_OTHER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK2, + { 0xF7CFFFFF, 0x02, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 0, 0, 0, { 0, 0, 0 } }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A1648C = { - { COLTYPE_HIT1, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK1, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit2 = { + { + COLTYPE_HIT1, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK1, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 0, 0, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80A164B8 = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -// static DamageTable sDamageTable = { -static DamageTable D_80A164C4 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(1, 0x0), /* Deku Stick */ DMG_ENTRY(1, 0x0), /* Horse trample */ DMG_ENTRY(1, 0x0), @@ -97,156 +186,1887 @@ static DamageTable D_80A164C4 = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; +static ActorAnimationEntryS sAnimations[] = { + { &object_oF1d_map_Anim_011D98, 1.0f, 0, -1, 0, 0 }, { &object_oF1d_map_Anim_011D98, 1.0f, 0, -1, 0, -4 }, + { &object_oF1d_map_Anim_012DE0, 2.0f, 0, -1, 2, 0 }, { &object_oF1d_map_Anim_012DE0, 2.0f, 0, -1, 2, -4 }, + { &object_oF1d_map_Anim_012DE0, -2.0f, 0, -1, 2, 0 }, { &object_oF1d_map_Anim_003E28, 1.0f, 0, -1, 0, 0 }, + { &object_oF1d_map_Anim_003E28, 1.0f, 0, -1, 0, -4 }, { &object_oF1d_map_Anim_0039D8, 1.0f, 0, -1, 2, -4 }, + { &object_oF1d_map_Anim_003650, 1.0f, 0, -1, 0, 0 }, { &object_oF1d_map_Anim_0135E8, 1.0f, 0, -1, 2, -4 }, + + { &object_taisou_Anim_004DD4, 1.0f, 0, -1, 0, 0 }, { &object_taisou_Anim_0016C8, 1.0f, 0, -1, 0, 0 }, + { &object_taisou_Anim_00283C, 1.0f, 0, -1, 0, 0 }, { &object_taisou_Anim_007764, 1.0f, 0, -1, 0, 0 }, + { &object_taisou_Anim_005EE0, 1.0f, 0, -1, 0, 0 }, { &object_taisou_Anim_002C48, 1.0f, 0, -1, 0, 0 }, + { &object_taisou_Anim_0031D8, 1.0f, 0, -1, 0, 0 }, { &object_taisou_Anim_005790, 1.0f, 0, -1, 0, 0 }, + + { &object_hakugin_demo_Anim_001420, 1.0f, 0, -1, 2, 0 }, { &object_hakugin_demo_Anim_001A4C, 1.0f, 0, -1, 0, -4 }, + { &object_hakugin_demo_Anim_002704, 1.0f, 0, -1, 2, 0 }, { &object_hakugin_demo_Anim_003378, 1.0f, 0, -1, 0, -4 }, +}; + +EnGoStruct* func_80A10FD0(EnGoStruct ptr[], Vec3f arg1, Vec3f arg2, Vec3f arg3, f32 arg4, f32 arg5, s32 arg6) { + s32 i; + + for (i = 16; i < 32; i++, ptr++) { + if (ptr->unk_00 == 0) { + ptr->unk_00 = 7; + ptr->unk_01 = (Rand_ZeroOne() * (2.0f * (arg6 / 3.0f))) + (arg6 / 3.0f); + ptr->unk_02 = ptr->unk_01; + ptr->unk_10 = arg1; + ptr->unk_1C = arg2; + ptr->unk_28 = arg3; + ptr->unk_34 = arg4; + ptr->unk_38 = arg5; + break; + } + } + + return ptr; +} + +void func_80A11144(EnGoStruct ptr[], GlobalContext* globalCtx) { + s32 pad; + s32 i; + s32 flag = false; + f32 temp; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + for (i = 0; i < 32; i++, ptr++) { + + if (ptr->unk_00 == 7) { + gDPPipeSync(POLY_XLU_DISP++); + + if (!flag) { + gSPDisplayList(POLY_XLU_DISP++, object_oF1d_map_DL_0031A0); + flag = true; + } + + Matrix_StatePush(); + + temp = ((f32)ptr->unk_02 / ptr->unk_01); + temp *= 255; + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 225, 235, (u8)temp); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, (ptr->unk_02 + (i * 3)) * 3, + (ptr->unk_02 + (i * 3)) * 15, 0x20, 0x40, 1, 0, 0, 0x20, 0x20)); + + Matrix_InsertTranslation(ptr->unk_10.x, ptr->unk_10.y, ptr->unk_10.z, MTXMODE_NEW); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + Matrix_Scale(ptr->unk_34, ptr->unk_34, 1.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_oF1d_map_DL_003258); + + Matrix_StatePop(); + if (globalCtx->state.gfxCtx) {} + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80A1143C(EnGoStruct ptr[], Vec3f arg1, Vec3f arg2, Vec3f arg3, f32 arg4, f32 arg5, s32 arg6, s32 arg7) { + s32 i; + + for (i = 16; i < 32; i++, ptr++) { + if (ptr->unk_00 == 0) { + ptr->unk_00 = arg7 + 4; + + ptr->unk_01 = (Rand_ZeroOne() * (2.0f * (arg6 / 3.0f))) + (arg6 / 3.0f); + ptr->unk_02 = ptr->unk_01; + + ptr->unk_10 = arg1; + ptr->unk_1C = arg2; + ptr->unk_28 = arg3; + ptr->unk_34 = arg4; + ptr->unk_38 = arg5; + break; + } + } +} + +void func_80A115B4(EnGoStruct ptr[], GlobalContext* globalCtx) { + static TexturePtr D_80A16644[] = { + &gameplay_keep_Tex_08F7E0, &gameplay_keep_Tex_08F3E0, &gameplay_keep_Tex_08EFE0, &gameplay_keep_Tex_08EBE0, + &gameplay_keep_Tex_08E7E0, &gameplay_keep_Tex_08E3E0, &gameplay_keep_Tex_08DFE0, &gameplay_keep_Tex_08DBE0, + }; + static Color_RGBA8 D_80A16664[] = { + { 255, 255, 255, 0 }, + { 170, 130, 90, 0 }, + { 0, 0, 0, 0 }, + }; + static Color_RGBA8 D_80A16670[] = { + { 255, 255, 255, 0 }, + { 100, 60, 20, 0 }, + { 0, 0, 0, 0 }, + }; + s32 i; + u8 flag = false; + f32 temp; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + for (i = 0; i < 32; i++, ptr++) { + if ((ptr->unk_00 >= 4) && (ptr->unk_00 < 7)) { + if (!flag) { + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0); + gSPDisplayList(POLY_XLU_DISP++, object_oF1d_map_DL_014CF0); + flag = true; + } + Matrix_StatePush(); + + temp = (f32)ptr->unk_02 / ptr->unk_01; + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, D_80A16664[(s32)ptr->unk_00 - 4].r, + D_80A16664[(s32)ptr->unk_00 - 4].g, D_80A16664[(s32)ptr->unk_00 - 4].b, (u8)(temp * 255)); + gDPSetEnvColor(POLY_XLU_DISP++, D_80A16670[(s32)ptr->unk_00 - 4].r, D_80A16670[(s32)ptr->unk_00 - 4].g, + D_80A16670[(s32)ptr->unk_00 - 4].b, 0); + + Matrix_InsertTranslation(ptr->unk_10.x, ptr->unk_10.y, ptr->unk_10.z, MTXMODE_NEW); + Matrix_Scale(ptr->unk_34, ptr->unk_34, 1.0f, MTXMODE_APPLY); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(D_80A16644[(s32)(temp * 7.0f)])); + gSPDisplayList(POLY_XLU_DISP++, object_oF1d_map_DL_014D00); + + Matrix_StatePop(); + } + if (globalCtx->state.gfxCtx) {} + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +#ifdef NON_MATCHING +void func_80A118F8(EnGoStruct ptr[32], Vec3f arg1) { + static u8 D_80A1667C[] = { + 3, 1, 1, 2, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1, 1, 2, + }; + EnGoStruct* ptr2 = &ptr[16]; + s32 i; + Vec3f spB4; + Vec3f spA8; + f32 temp_f20; + + for (i = 0; i < 16; i++, ptr++) { + if (ptr->unk_00 == 0) { + ptr->unk_10 = arg1; + ptr->unk_10.y += 56.0f; + + ptr->unk_04.x = (Rand_ZeroOne() - 0.5f) * 5460.0f; + ptr->unk_04.y = (Rand_ZeroOne() - 0.5f) * 5460.0f; + ptr->unk_04.z = (Rand_ZeroOne() - 0.5f) * 5460.0f; + + temp_f20 = (Rand_ZeroOne() * 4.0f) + 6.0f; + ptr->unk_28.x = Math_SinS(i * 0x1000) * temp_f20; + ptr->unk_28.z = Math_CosS(i * 0x1000) * temp_f20; + ptr->unk_28.y = (Rand_ZeroOne() * 3.0f) + 6.0f; + + ptr->unk_1C = gZeroVec3f; + ptr->unk_1C.y = -0.8f; + + ptr->unk_01 = ptr->unk_02 = 1; + ptr->unk_00 = D_80A1667C[i]; + + spB4.x = ((Rand_ZeroOne() - 0.5f) * 80.0f) + ptr->unk_10.x; + spB4.y = ((Rand_ZeroOne() - 0.5f) * 40.0f) + ptr->unk_10.y; + spB4.z = ((Rand_ZeroOne() - 0.5f) * 80.0f) + ptr->unk_10.z; + + spA8 = gZeroVec3f; + spA8.y = (Rand_ZeroOne() * 3.0f) + 1.0f; + + func_80A1143C(ptr2, spB4, gZeroVec3f, spA8, 0.6f, 0.2f, 16, 0); + } + } +} +#else +static u8 D_80A1667C[] = { + 3, 1, 1, 2, 3, 1, 1, 2, 3, 1, 1, 2, 3, 1, 1, 2, +}; +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A118F8.s") #endif -extern ColliderSphereInit D_80A16434; -extern ColliderCylinderInit D_80A16460; -extern ColliderCylinderInit D_80A1648C; -extern CollisionCheckInfoInit2 D_80A164B8; -extern DamageTable D_80A164C4; +void func_80A11BF8(EnGoStruct ptr[], f32 arg1) { + f32 test; + f32 test2; + f32 x; + f32 z; -extern UNK_TYPE D_06000458; -extern UNK_TYPE D_06003258; -extern UNK_TYPE D_060091A8; -extern UNK_TYPE D_06011AC8; -extern UNK_TYPE D_06014D00; + ptr->unk_10.x += ptr->unk_28.x; + ptr->unk_10.y += ptr->unk_28.y; + ptr->unk_10.z += ptr->unk_28.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A10FD0.s") + ptr->unk_28.y += ptr->unk_1C.y; + ptr->unk_34 += ptr->unk_38; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A11144.s") + if (ptr->unk_10.y < arg1) { + ptr->unk_10.y = arg1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A1143C.s") + ptr->unk_00 = 4; + ptr->unk_01 = (Rand_ZeroOne() * 8.0f) + 4.0f; + ptr->unk_02 = ptr->unk_01; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A115B4.s") + ptr->unk_28 = gZeroVec3f; + ptr->unk_28.y = (Rand_ZeroOne() * 3.0f) + 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A118F8.s") + ptr->unk_34 = 0.4f; + ptr->unk_38 = 0.1f; + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A11BF8.s") + if (ptr->unk_28.x != 0.0f) { + x = ptr->unk_28.x / fabsf(ptr->unk_28.x); + x *= ((sREG(13) + 140) * 0.01f); + Math_StepToF(&ptr->unk_28.x, x, (sREG(14) + 40) * 0.01f); + } + if (ptr->unk_28.z != 0.0f) { + z = ptr->unk_28.z / fabsf(ptr->unk_28.z); + z *= ((sREG(13) + 140) * 0.01f); + Math_StepToF(&ptr->unk_28.z, z, (sREG(14) + 40) * 0.01f); + } + + ptr->unk_0A.x += ptr->unk_04.x; + ptr->unk_0A.y += ptr->unk_04.y; + ptr->unk_0A.z += ptr->unk_04.z; +} + +#ifdef NON_MATCHING +void func_80A11EC0(EnGoStruct ptr[], GlobalContext* globalCtx, Gfx arg2[], Gfx arg3[], u8 arg4) { + s32 i; + u8 flag = false; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + for (i = 0; i < 16; i++, ptr++) { + if (ptr->unk_00 == arg4) { + if (!flag) { + gSPDisplayList(POLY_OPA_DISP++, arg2); + flag = true; + } + + Matrix_StatePush(); + Matrix_InsertTranslation(ptr->unk_10.x, ptr->unk_10.y, ptr->unk_10.z, MTXMODE_NEW); + Matrix_Scale(0.08f, 0.08f, 0.08f, MTXMODE_APPLY); + Matrix_InsertZRotation_s(ptr->unk_0A.z, MTXMODE_APPLY); + Matrix_InsertXRotation_s(ptr->unk_0A.x, MTXMODE_APPLY); + Matrix_RotateY(ptr->unk_0A.y, MTXMODE_APPLY); + + if (1) { + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, arg3); + } + + Matrix_StatePop(); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} +#else #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A11EC0.s") +#endif -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A1203C.s") +void func_80A1203C(EnGo* this) { + EnGoStruct* ptr = this->unk_3F8; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A1213C.s") + for (i = 0; i < ARRAY_COUNT(this->unk_3F8); i++, ptr++) { + if (ptr->unk_00 != 0) { + if (ptr->unk_02 == 0) { + ptr->unk_00 = 0; + } else if ((ptr->unk_00 > 0) && (ptr->unk_00 < 4)) { + func_80A11BF8(ptr, this->actor.world.pos.y); + } else { + ptr->unk_10.x += ptr->unk_28.x; + ptr->unk_10.y += ptr->unk_28.y; + ptr->unk_10.z += ptr->unk_28.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A121F4.s") + ptr->unk_28.x += ptr->unk_1C.x; + ptr->unk_28.y += ptr->unk_1C.y; + ptr->unk_28.z += ptr->unk_1C.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A1222C.s") + ptr->unk_34 += ptr->unk_38; + ptr->unk_02--; + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A122EC.s") +void func_80A1213C(EnGo* this, GlobalContext* globalCtx) { + func_80A11EC0(this->unk_3F8, globalCtx, object_oF1d_map_DL_0003D0, object_oF1d_map_DL_000458, 1); + func_80A11EC0(this->unk_3F8, globalCtx, object_oF1d_map_DL_0008C0, object_oF1d_map_DL_000948, 2); + func_80A11EC0(this->unk_3F8, globalCtx, object_oF1d_map_DL_000D50, object_oF1d_map_DL_000DD8, 3); + func_80A11144(this->unk_3F8, globalCtx); + func_80A115B4(this->unk_3F8, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A123A0.s") +s32 func_80A121F4(GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A124A0.s") + if ((player->transformation == PLAYER_FORM_GORON) && (player->stateFlags3 & 0x2000000)) { + return false; + } + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A124FC.s") +s32 func_80A1222C(EnGo* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A125BC.s") + if (((player->transformation == PLAYER_FORM_GORON) && (globalCtx->msgCtx.unk1202A == 3) && + (globalCtx->msgCtx.unk1202E == 1) && (this->unk_3EC == 0) && (this->actor.xzDistToPlayer < 400.0f)) || + (!(gSaveContext.weekEventReg[22] & 4) && (globalCtx->sceneNum == SCENE_16GORON_HOUSE) && + (gSaveContext.sceneSetupIndex == 0) && (this->unk_3EC == 0) && (globalCtx->csCtx.unk_12 == 1))) { + ret = true; + } + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12660.s") +s32 func_80A122EC(EnGo* this) { + static Vec3f D_80A1668C = { 0.0f, 100.0f, 160.0f }; + s32 pad; + f32 sp20 = 58.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A126BC.s") + if (ENGO_GET_F(&this->actor) == ENGO_F_8) { + Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, this->actor.shape.rot.y, &D_80A1668C, + &this->actor.focus.pos); + } else { + if ((this->unk_390 & 0x200) || (this->unk_390 & 0x100)) { + sp20 = this->actor.shape.yOffset; + } + Math_Vec3f_Copy(&this->actor.focus.pos, &this->actor.world.pos); + this->actor.focus.pos.y += sp20; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12774.s") + this->actor.focus.rot.x = this->actor.world.rot.x; + this->actor.focus.rot.y = this->actor.world.rot.y; + this->actor.focus.rot.z = this->actor.world.rot.z; + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12868.s") +void func_80A123A0(EnGo* this, GlobalContext* globalCtx) { + Vec3f sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12954.s") + Math_Vec3f_Copy(&sp2C, &this->actor.world.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12A64.s") + this->colliderSphere.dim.worldSphere.center.x = sp2C.x; + this->colliderSphere.dim.worldSphere.center.y = sp2C.y; + this->colliderSphere.dim.worldSphere.center.y += (s16)this->actor.shape.yOffset; + this->colliderSphere.dim.worldSphere.center.z = sp2C.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12B78.s") + this->colliderSphere.dim.modelSphere.radius = 48; + this->colliderSphere.dim.worldSphere.radius = + this->colliderSphere.dim.modelSphere.radius * this->colliderSphere.dim.scale; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12C48.s") + if (func_80A121F4(globalCtx)) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere.base); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12D6C.s") + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12DF4.s") +void func_80A124A0(EnGo* this, GlobalContext* globalCtx) { + this->colliderSphere.dim.worldSphere.radius = + this->colliderSphere.dim.modelSphere.radius * this->colliderSphere.dim.scale; + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12E80.s") +void func_80A124FC(EnGo* this, GlobalContext* globalCtx) { + Vec3f sp1C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A12FE8.s") + Math_Vec3f_Copy(&sp1C, &this->actor.world.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A131F8.s") + this->colliderSphere.dim.worldSphere.center.x = sp1C.x; + this->colliderSphere.dim.worldSphere.center.y = sp1C.y; + this->colliderSphere.dim.worldSphere.center.y += (s16)this->actor.shape.yOffset; + this->colliderSphere.dim.worldSphere.center.z = sp1C.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A132C8.s") + this->colliderSphere.dim.modelSphere.radius = 20; + this->colliderSphere.dim.worldSphere.radius = + this->colliderSphere.dim.modelSphere.radius * this->colliderSphere.dim.scale; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A133A8.s") + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A13400.s") +void func_80A125BC(EnGo* this, GlobalContext* globalCtx) { + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A134B0.s") + Math_Vec3f_ToVec3s(&this->colliderCylinder.dim.pos, &this->actor.world.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A134F4.s") + this->colliderCylinder.dim.radius = 46; + this->colliderCylinder.dim.height = 78; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A13564.s") + if (this->unk_3C6 == 0) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base); + } + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A136B8.s") +void func_80A12660(EnGo* this, GlobalContext* globalCtx) { + Math_Vec3f_ToVec3s(&this->colliderCylinder.dim.pos, &this->actor.world.pos); + this->colliderCylinder.dim.radius = 24; + this->colliderCylinder.dim.height = 62; + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A13728.s") +void func_80A126BC(EnGo* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A137C0.s") + if (!(player->stateFlags2 & 0x4000)) { + if (this->unk_3C6 != 0) { + this->unk_3C6--; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A139E4.s") + if (ENGO_GET_F(&this->actor) == ENGO_F_8) { + func_80A124A0(this, globalCtx); + } else if (this->unk_390 & 0x100) { + func_80A123A0(this, globalCtx); + } else if (this->unk_390 & 0x200) { + func_80A124FC(this, globalCtx); + } else if (this->unk_390 & 0x400) { + func_80A125BC(this, globalCtx); + } else { + func_80A12660(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A13B1C.s") +s32 func_80A12774(EnGo* this, GlobalContext* globalCtx) { + if (!(this->unk_390 & 7) || !func_800B84D0(&this->actor, globalCtx)) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A13E80.s") + if ((ENGO_GET_F(&this->actor) != ENGO_F_8) && (ENGO_GET_F(&this->actor) != ENGO_F_1)) { + if (!(this->unk_390 & 0x200)) { + this->unk_390 |= 8; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14018.s") + if ((ENGO_GET_F(&this->actor) == ENGO_F_5) || (ENGO_GET_F(&this->actor) == ENGO_F_6) || + (ENGO_GET_F(&this->actor) == ENGO_F_7)) { + this->unk_3BC = 0; + this->unk_3BE = 0; + this->unk_390 |= 0x20; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14104.s") + func_8013AED4(&this->unk_390, 0, 7); + this->unk_3C0 = 0; + this->unk_3C4 = 0; + this->unk_18C = this->actionFunc; + this->actionFunc = func_80A157C4; + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A141D4.s") +s32 func_80A12868(EnGo* this, GlobalContext* globalCtx) { + this->unk_390 &= ~0x800; + this->unk_390 &= ~0x1000; + this->unk_390 &= ~0x2000; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A1428C.s") + if ((this->colliderCylinder.base.atFlags & AT_HIT) || (this->colliderSphere.base.atFlags & AT_HIT)) { + this->colliderCylinder.base.atFlags &= ~AT_HIT; + this->colliderSphere.base.atFlags &= ~AT_HIT; + this->unk_390 |= 0x800; + this->unk_3C6 = 0x28; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14324.s") + if ((this->colliderCylinder.base.acFlags & AC_HIT) || (this->colliderSphere.base.acFlags & AC_HIT)) { + this->colliderCylinder.base.acFlags &= ~AC_HIT; + this->colliderSphere.base.acFlags &= ~AC_HIT; + this->unk_390 |= 0x1000; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A143A8.s") + if ((this->colliderCylinder.base.ocFlags1 & OC1_HIT) || (this->colliderSphere.base.ocFlags1 & OC1_HIT)) { + this->colliderCylinder.base.ocFlags1 &= ~OC1_HIT; + this->colliderSphere.base.ocFlags1 &= ~OC1_HIT; + this->unk_390 |= 0x2000; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14430.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A1449C.s") +s32 func_80A12954(EnGo* this, GlobalContext* globalCtx) { + if ((ENGO_GET_F(&this->actor) == ENGO_F_4) && (globalCtx->csCtx.state != 0) && (this->actor.draw != NULL) && + (globalCtx->sceneNum == SCENE_10YUKIYAMANOMURA2) && (gSaveContext.sceneSetupIndex == 1) && + (globalCtx->csCtx.unk_12 == 0)) { + if (this->unk_3F0 == 0) { + this->actor.flags &= ~1; + this->unk_394 = 255; + this->unk_3F0 = 1; + this->unk_18C = this->actionFunc; + } + func_8013AED4(&this->unk_390, 0, 7); + this->actionFunc = func_80A14FC8; + } else if (this->unk_3F0 != 0) { + this->actor.flags |= 1; + this->unk_394 = 255; + this->unk_3F0 = 0; + func_8013AED4(&this->unk_390, 3, 7); + this->actionFunc = this->unk_18C; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A144F4.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A145AC.s") +s32 func_80A12A64(EnGo* this, GlobalContext* globalCtx) { + s8 objIdx = this->actor.objBankIndex; + s8 objIdx2 = -1; + s32 ret = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14668.s") + if ((this->unk_3DC >= 18) && (this->unk_289 >= 0)) { + objIdx2 = this->unk_289; + } else if ((this->unk_3DC >= 10) && (this->unk_288 >= 0)) { + objIdx2 = this->unk_288; + } else if (this->unk_3DC < 10) { + objIdx2 = this->actor.objBankIndex; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A146CC.s") + if (objIdx2 >= 0) { + gSegments[6] = PHYSICAL_TO_VIRTUAL2(globalCtx->objectCtx.status[objIdx2].segment); + this->skelAnime.playSpeed = this->unk_398; + ret = SkelAnime_Update(&this->skelAnime); + gSegments[6] = PHYSICAL_TO_VIRTUAL2(globalCtx->objectCtx.status[objIdx].segment); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14798.s") + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A149B0.s") +s32 func_80A12B78(EnGo* this, GlobalContext* globalCtx) { + if (globalCtx->csCtx.state == 0) { + if (this->unk_3DC == 4) { + if (Animation_OnFrame(&this->skelAnime, 2.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_CIRCLE); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14B30.s") + if (Animation_OnFrame(&this->skelAnime, 22.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_SIT_IMT); + } + } else if ((this->unk_3DC == 2) || (this->unk_3DC == 3)) { + if (Animation_OnFrame(&this->skelAnime, 2.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_CIRCLE_OFF); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14E14.s") + if (Animation_OnFrame(&this->skelAnime, 24.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_STAND_IMT); + } + } + } + return 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14E74.s") +s32 func_80A12C48(EnGo* this, GlobalContext* globalCtx, s32 arg2) { + s8 objIdx = this->actor.objBankIndex; + s8 objIdx2 = -1; + s32 ret = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14EB0.s") + if ((arg2 >= 18) && (this->unk_289 >= 0)) { + objIdx2 = this->unk_289; + } else if ((arg2 >= 10) && (this->unk_288 >= 0)) { + objIdx2 = this->unk_288; + } else if (arg2 < 10) { + objIdx2 = this->actor.objBankIndex; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A14FC8.s") + if (objIdx2 >= 0) { + gSegments[6] = PHYSICAL_TO_VIRTUAL2(globalCtx->objectCtx.status[objIdx2].segment); + this->unk_3DC = arg2; + ret = func_8013BC6C(&this->skelAnime, sAnimations, arg2); + this->unk_398 = this->skelAnime.playSpeed; + gSegments[6] = PHYSICAL_TO_VIRTUAL2(globalCtx->objectCtx.status[objIdx].segment); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A153FC.s") + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A15684.s") +void func_80A12D6C(EnGo* this) { + if ((this->unk_390 & 0x20) && (DECR(this->unk_3BC) == 0)) { + this->unk_3BE++; + if (this->unk_3BE >= 4) { + this->unk_3BC = Rand_S16Offset(30, 30); + this->unk_3BE = 0; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A157C4.s") +void func_80A12DF4(EnGo* this, GlobalContext* globalCtx) { + if (this->unk_3D4 == 0) { + func_80A12C48(this, globalCtx, 9); + this->unk_3D4++; + } else if ((this->unk_3D4 == 1) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + func_80A12C48(this, globalCtx, 6); + this->unk_3D4++; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/EnGo_Init.s") +s32 func_80A12E80(EnGo* this, GlobalContext* globalCtx) { + u16 temp = globalCtx->msgCtx.unk11F04; + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/EnGo_Destroy.s") + if (ENGO_GET_F(&this->actor) != ENGO_F_4) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/EnGo_Update.s") + if (player->stateFlags1 & 0x40) { + if (this->unk_392 != temp) { + switch (temp) { + case 0xE1A: + this->unk_390 |= 8; + this->unk_38C = this->actor.child; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A15B80.s") + case 0xE1D: + case 0xE25: + if (ENGO_GET_70(&this->actor) == ENGO_70_1) { + this->unk_38C = &GET_PLAYER(globalCtx)->actor; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A15D04.s") + case 0xE27: + if (ENGO_GET_70(&this->actor) == ENGO_70_1) { + this->unk_38C = this->actor.child; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A15E38.s") + case 0xE16: + case 0xE1E: + this->unk_190 = func_80A12DF4; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Go/func_80A15FEC.s") + case 0xE1F: + if (ENGO_GET_70(&this->actor) == ENGO_70_0) { + this->unk_38C = &GET_PLAYER(globalCtx)->actor; + } + break; + } + } + this->unk_3F4 = 1; + this->unk_392 = temp; + } else if (this->unk_3F4 != 0) { + this->unk_3F4 = 0; + this->unk_190 = NULL; + this->unk_392 = 0; + func_80A12C48(this, globalCtx, 5); + this->unk_390 &= ~8; + } + + if (this->unk_190 != NULL) { + this->unk_190(this, globalCtx); + } + + return false; +} + +s32 func_80A12FE8(EnGo* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp40; + Vec3f sp34; + s16 sp32; + + Math_Vec3f_Copy(&sp40, &this->unk_38C->world.pos); + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + sp32 = Math_Vec3f_Yaw(&sp34, &sp40); + + Math_ApproachS(&this->unk_3B2, (sp32 - this->unk_3B6) - this->actor.shape.rot.y, 4, 0x2AA8); + this->unk_3B2 = CLAMP(this->unk_3B2, -0x1FFE, 0x1FFE); + + Math_ApproachS(&this->unk_3B6, (sp32 - this->unk_3B2) - this->actor.shape.rot.y, 4, 0x2AA8); + this->unk_3B6 = CLAMP(this->unk_3B6, -0x1C70, 0x1C70); + + Math_Vec3f_Copy(&sp34, &this->actor.focus.pos); + + if (this->unk_38C->id == ACTOR_PLAYER) { + sp40.y = ((Player*)this->unk_38C)->bodyPartsPos[7].y + 3.0f; + } else { + Math_Vec3f_Copy(&sp40, &this->unk_38C->focus.pos); + } + + Math_ApproachS(&this->unk_3B0, Math_Vec3f_Pitch(&sp34, &sp40) - this->unk_3B4, 4, 0x2AA8); + this->unk_3B0 = CLAMP(this->unk_3B0, -0x1554, 0x1554); + + Math_ApproachS(&this->unk_3B4, Math_Vec3f_Pitch(&sp34, &sp40) - this->unk_3B0, 4, 0x2AA8); + this->unk_3B4 = CLAMP(this->unk_3B4, -0xE38, 0xE38); + + return false; +} + +s32 func_80A131F8(EnGo* this, GlobalContext* globalCtx) { + if (this->unk_3F4 == 0) { + this->unk_38C = &GET_PLAYER(globalCtx)->actor; + } + + func_80A12E80(this, globalCtx); + + if (this->unk_390 & 8) { + this->unk_390 &= ~0x40; + this->unk_390 |= 0x10; + func_80A12FE8(this, globalCtx); + } else if (this->unk_390 & 0x10) { + this->unk_390 &= ~0x10; + this->unk_3B0 = 0; + this->unk_3B2 = 0; + this->unk_3B4 = 0; + this->unk_3B6 = 0; + this->unk_3BA = 0x14; + } else if (DECR(this->unk_3BA) == 0) { + this->unk_390 |= 0x40; + this->unk_3BA = 0x14; + } + + return true; +} + +void func_80A132C8(EnGo* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 temp_v1 = BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y); + + if ((fabsf(this->actor.playerHeightRel) > 20.0f) || (this->actor.xzDistToPlayer > 300.0f)) { + func_8013AED4(&this->unk_390, 3, 7); + } else if ((player->transformation != PLAYER_FORM_GORON) || (ABS_ALT(temp_v1) >= 0x1C70) || + (gSaveContext.weekEventReg[21] & 4) || (gSaveContext.weekEventReg[21] & 8)) { + func_8013AED4(&this->unk_390, 3, 7); + } else { + func_8013AED4(&this->unk_390, 4, 7); + } +} + +void func_80A133A8(EnGo* this, GlobalContext* globalCtx) { + if (gSaveContext.weekEventReg[21] & 8) { + func_8013AED4(&this->unk_390, 3, 7); + } else { + func_8013AED4(&this->unk_390, 4, 7); + } +} + +Actor* func_80A13400(EnGo* this, GlobalContext* globalCtx) { + Actor* actor; + Actor* retActor = NULL; + + while (true) { + actor = SubS_FindActor(globalCtx, retActor, ACTORCAT_NPC, ACTOR_EN_GO); + retActor = actor; + + if ((actor != NULL) && ((EnGo*)actor != this) && (ENGO_GET_F(actor) == ENGO_F_4) && + (ENGO_GET_70(actor) == ENGO_70_0)) { + return retActor; + } + + if (actor == NULL) { + break; + } + + actor = actor->next; + if (actor == NULL) { + break; + } + retActor = actor; + } + + return NULL; +} + +void func_80A134B0(EnGo* this, GlobalContext* globalCtx, s32 arg2) { + if ((gSaveContext.weekEventReg[18] & 0x80) || (globalCtx->actorCtx.unk5 & 1) || arg2) { + this->colliderSphere.dim.modelSphere.radius = 300; + } else { + this->colliderSphere.dim.modelSphere.radius = 380; + } +} + +s32 func_80A134F4(EnGo* this, s16 arg1) { + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + } else if (ActorCutscene_GetCanPlayNext(arg1)) { + ActorCutscene_StartAndSetUnkLinkFields(arg1, &this->actor); + return true; + } + ActorCutscene_SetIntentToPlay(arg1); + return false; +} + +s32 func_80A13564(EnGo* this, f32 arg1, f32 arg2, s32 arg3) { + s32 pad; + f32 temp_f0 = 1.0f; + f32 temp_f14 = this->actor.velocity.y + this->actor.gravity; + s32 ret; + + if (this->actor.bgCheckFlags & 2) { + ret = true; + } else { + if (temp_f14 > 0.0f) { + temp_f0 = temp_f14 / arg1; + this->actor.shape.rot.x += (s16)(9100.0f * temp_f0); + this->unk_3AE = 0; + } else if ((s32)this->actor.velocity.y == 0) { + if (arg3 >= this->unk_3AE) { + temp_f0 = (f32)this->unk_3AE / arg3; + } else { + this->actor.gravity = -6.0f; + } + this->unk_3AE++; + } else if (this->unk_3AE == 0) { + this->actor.velocity.y = 0.0f; + this->actor.gravity = 0.0f; + temp_f0 = temp_f14 / arg1; + } + ret = false; + } + + this->unk_3A8 = (1.0f - temp_f0) * arg2; + this->actor.scale.x = this->unk_3A4 - this->unk_3A8; + this->actor.scale.y = this->unk_3A4 + this->unk_3A8; + + if (this->actor.scale.y < this->actor.scale.x) { + this->actor.scale.z = this->actor.scale.x; + } else { + this->actor.scale.z = this->actor.scale.y; + } + return ret; +} + +void func_80A136B8(GlobalContext* globalCtx, s16 arg1, s16 arg2, s16 arg3) { + s16 sp26 = Quake_Add(Play_GetCamera(globalCtx, MAIN_CAM), 3); + + Quake_SetCountdown(sp26, arg3); + Quake_SetSpeed(sp26, arg1); + Quake_SetQuakeValues(sp26, arg2, 0, 0, 0); +} + +void func_80A13728(EnGo* this, GlobalContext* globalCtx) { + func_80A136B8(globalCtx, 0x6C77, 7, 20); + globalCtx->actorCtx.unk2 = 4; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_TEST, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 0, 0, 0, 0); + EffectSsBlast_SpawnWhiteShockwave(globalCtx, &this->actor.world.pos, &gZeroVec3f, &gZeroVec3f); +} + +void func_80A137C0(EnGo* this, GlobalContext* globalCtx, f32 arg2, f32 arg3) { + u32 frames1; + u32 frames2; + + if (this->unk_390 & 0x400) { + Matrix_StatePush(); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, + MTXMODE_NEW); + Matrix_Scale(arg2 * 0.7f, arg2 * 0.8f, arg2, MTXMODE_APPLY); + func_800B8118(&this->actor, globalCtx, 0); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + frames1 = globalCtx->gameplayFrames % 256; + frames2 = (globalCtx->gameplayFrames * 2) % 256; + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, frames1, 0x20, 0x10, 1, 0, frames2, 0x40, 0x20)); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 50, 100, (u8)arg3); + gSPDisplayList(POLY_XLU_DISP++, &gameplay_keep_DL_050D10); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + Matrix_StatePop(); + } +} + +void func_80A139E4(EnGo* this) { + static Vec3f D_80A16698 = { 0.0f, 0.06f, 0.0f }; + Vec3f sp54; + Vec3f sp48; + s16 sp46 = Rand_ZeroOne() * 360.0f * 182.0f; + + Math_Vec3f_Copy(&sp54, &gZeroVec3f); + sp54.z = 28.0f; + Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, sp46, &sp54, &sp48); + sp48.y = (Rand_ZeroOne() * 10.0f) + 4.0f; + sp48.y += this->actor.floorHeight; + func_80A10FD0(&this->unk_3F8[16], sp48, D_80A16698, gZeroVec3f, 0.01f, 0.002f, 16); +} + +s32 func_80A13B1C(EnGo* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 pad; + s32 ret = false; + + switch (this->unk_3C0) { + case 0: + this->unk_3B8 = ActorCutscene_GetAdditionalCutscene(this->actor.cutscene); + if (func_80A134F4(this, this->unk_3B8)) { + this->unk_3C4 = 1; + this->unk_3C0 = 1; + } else { + break; + } + + case 1: + if (ActorCutscene_GetCurrentIndex() != this->unk_3B8) { + this->unk_3B8 = ActorCutscene_GetAdditionalCutscene(this->unk_3B8); + this->unk_3C0 = 2; + } else { + break; + } + + case 2: + if (func_80A134F4(this, this->unk_3B8)) { + this->unk_3C0 = 3; + } else { + break; + } + + case 3: + if (ActorCutscene_GetCanPlayNext(0x7C)) { + ActorCutscene_StartAndSetUnkLinkFields(0x7C, NULL); + this->unk_3C0 = 4; + } else if (ActorCutscene_GetCurrentIndex() == this->unk_3B8) { + ActorCutscene_SetIntentToPlay(0x7C); + } + } + + switch (this->unk_3C4) { + case 1: + func_80A12C48(this, globalCtx, 4); + this->unk_390 |= 0x4000; + this->unk_3C4++; + break; + + case 2: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->unk_390 &= ~0x4000; + this->unk_390 &= ~0x80; + this->unk_390 |= 0x200; + this->unk_3C4++; + this->unk_3C2 = 0; + this->actor.shape.yOffset = 14.0f; + } + break; + + case 3: + this->unk_3C2++; + if (this->unk_3C2 >= 10) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_JUMP); + this->actor.velocity.y = 10.0f; + this->actor.gravity = -1.0f; + this->unk_3C4++; + } + break; + + case 4: + if (func_80A13564(this, 10.0f, 0.004f, 6)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_LAND_BIG); + func_80A13728(this, globalCtx); + this->unk_3C4++; + this->unk_3C2 = 0; + gSaveContext.weekEventReg[88] |= 0x40; + } + break; + + case 5: + this->unk_3C2++; + if (this->unk_3C2 >= 10) { + func_80A12C48(this, globalCtx, 5); + this->actor.shape.rot.x = 0; + this->unk_390 &= ~0x200; + this->unk_390 |= 0x80; + this->unk_3C4++; + } + break; + + case 6: + this->unk_3C0++; + if (this->unk_3C0 >= 65) { + switch (player->transformation) { + case 4: + gSaveContext.weekEventReg[88] |= 0x80; + break; + + case 1: + gSaveContext.weekEventReg[89] |= 4; + break; + + case 2: + gSaveContext.weekEventReg[89] |= 2; + break; + + case 3: + gSaveContext.weekEventReg[89] |= 1; + break; + } + ret = true; + } + break; + } + + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + return ret; +} + +s32 func_80A13E80(EnGo* this, GlobalContext* globalCtx) { + static Vec3f D_80A166A4 = { 0.0f, 200.0f, 280.0f }; + s32 pad; + Vec3f sp48; + s32 ret = false; + + switch (this->unk_3C0) { + case 0: + this->unk_3B8 = this->actor.cutscene; + if (func_80A134F4(this, this->unk_3B8)) { + this->unk_3C0++; + } + break; + + case 1: + func_80A12C48(this, globalCtx, 7); + this->unk_3C0++; + + case 2: + if (Animation_OnFrame(&this->skelAnime, 16.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_GORON_HAND_HIT); + } + + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + func_80A12C48(this, globalCtx, 1); + Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, this->actor.shape.rot.y, &D_80A166A4, &sp48); + gSaveContext.powderKegTimer = 2400; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_BOM, sp48.x, sp48.y, sp48.z, 1, 0, 0, 0); + func_80A134B0(this, globalCtx, 1); + this->unk_3C2 = 0; + this->unk_3C0++; + } + break; + + case 3: + if (this->unk_3C2 >= 60) { + ActorCutscene_Stop(this->unk_3B8); + this->unk_3C2 = 0; + this->unk_3C0 = 0; + ret = true; + } else { + this->unk_3C2++; + } + break; + } + + return ret; +} + +void func_80A14018(EnGo* this, GlobalContext* globalCtx) { + static Vec3f D_80A166B0 = { 0.0f, 0.0f, 40.0f }; + static s32 D_80A166BC[] = { 11, 10, 12, 13, 14, 17 }; + Vec3f sp2C; + s32 phi_v0 = ENGO_GET_70(&this->actor) % 6; + + if (phi_v0 < 4) { + phi_v0 = ((gSaveContext.eventInf[2] & 0xF) + phi_v0) % 4; + } + + func_80A12C48(this, globalCtx, D_80A166BC[phi_v0]); + + if (this->unk_3DC == 14) { + Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, this->actor.shape.rot.y, &D_80A166B0, &sp2C); + Math_Vec3f_Copy(&this->actor.world.pos, &sp2C); + } + this->actor.flags &= ~1; + Actor_SetScale(&this->actor, this->unk_3A4); + this->unk_3EC = 0; + this->unk_390 = 0; + this->unk_390 |= (0x40 | 0x20); + this->actor.gravity = 0.0f; +} + +void func_80A14104(EnGo* this, GlobalContext* globalCtx) { + static s32 D_80A166D4[] = { 15, 16 }; + s16 temp; + + func_80A12C48(this, globalCtx, D_80A166D4[ENGO_GET_70(&this->actor) % 2]); + temp = Rand_ZeroOne() * this->skelAnime.endFrame; + this->skelAnime.curFrame = temp; + this->actor.flags &= ~1; + Actor_SetScale(&this->actor, this->unk_3A4); + this->unk_3EC = 0; + this->unk_390 = 0; + this->unk_390 |= 0x40; + this->unk_390 |= 0x20; + this->actor.gravity = 0.0f; +} + +void func_80A141D4(EnGo* this, GlobalContext* globalCtx) { + Collider_InitAndSetCylinder(globalCtx, &this->colliderCylinder, &this->actor, &sCylinderInit1); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + this->unk_3DC = -1; + func_80A12C48(this, globalCtx, 5); + this->unk_3EC = 0; + this->unk_39C = (this->unk_3A4 / 0.01f) * 0.9f; + this->unk_3BE = 2; + this->unk_390 = 0; + this->unk_390 |= 0x40; + this->unk_390 |= 0x400; + this->unk_3A0 = 100.0f; +} + +void func_80A1428C(EnGo* this, GlobalContext* globalCtx) { + s16 temp; + Vec3f sp30; + Vec3f sp24; + + Math_Vec3f_Copy(&sp30, &this->actor.world.pos); + if (this->unk_284 != NULL) { + this->actor.flags &= ~0x2000000; + func_8013C8B8(this->unk_284, 0, &sp24); + temp = Math_Vec3f_Yaw(&sp30, &sp24); + this->actor.shape.rot.y = temp; + this->actor.world.rot.y = temp; + } + this->unk_390 = 0; + this->unk_390 |= 0x100; + this->actor.shape.yOffset = 46.0f; + this->actor.gravity = -1.0f; +} + +void func_80A14324(EnGo* this, GlobalContext* globalCtx) { + func_80A12C48(this, globalCtx, 8); + Actor_SetScale(&this->actor, this->unk_3A4); + this->unk_390 = 0; + this->actor.gravity = -1.0f; + func_8013AED4(&this->unk_390, 3, 7); + this->unk_3EC = 0; + this->unk_390 |= 0x40; + this->unk_3BC = 0; + this->unk_3BE = 4; + this->unk_39C = 0.0f; + this->unk_3A0 = 0.0f; +} + +void func_80A143A8(EnGo* this, GlobalContext* globalCtx) { + func_80A12C48(this, globalCtx, 5); + Actor_SetScale(&this->actor, this->unk_3A4); + this->unk_390 = 0; + this->actor.gravity = -1.0f; + func_8013AED4(&this->unk_390, 3, 7); + this->unk_3EC = 0; + this->unk_390 |= 0x40; + this->unk_390 |= 0x20; + this->unk_3BC = 0; + this->unk_3BE = 0; + this->unk_39C = 0.0f; + this->unk_3A0 = 0.0f; +} + +void func_80A14430(EnGo* this, GlobalContext* globalCtx) { + if (((gSaveContext.entranceIndex == 0xD000) || (gSaveContext.entranceIndex == 0xD020)) && + (gSaveContext.weekEventReg[33] & 0x80)) { + func_80A14018(this, globalCtx); + this->actionFunc = func_80A149B0; + } else { + Actor_MarkForDeath(&this->actor); + } +} + +void func_80A1449C(EnGo* this, GlobalContext* globalCtx) { + if ((gSaveContext.entranceIndex == 0xD010) || (gSaveContext.entranceIndex == 0x1C00)) { + func_80A14104(this, globalCtx); + this->actionFunc = func_80A149B0; + } else { + Actor_MarkForDeath(&this->actor); + } +} + +void func_80A144F4(EnGo* this, GlobalContext* globalCtx) { + if (gSaveContext.day >= 2) { + this->unk_284 = func_8013BEDC(globalCtx, ENGO_GET_7F80(&this->actor), 0xFF, &this->unk_3E4); + if (this->unk_284 != NULL) { + this->unk_3E4 = 1; + } + func_80A1428C(this, globalCtx); + this->actionFunc = func_80A153FC; + this->unk_3D8 = func_80A13B1C; + } else { + func_80A143A8(this, globalCtx); + this->actionFunc = func_80A149B0; + this->unk_3D8 = func_80A13B1C; + } +} + +void func_80A145AC(EnGo* this, GlobalContext* globalCtx) { + if ((ENGO_GET_70(&this->actor) == ENGO_70_1) && + (((globalCtx->sceneNum == SCENE_10YUKIYAMANOMURA2) && (gSaveContext.sceneSetupIndex == 1) && + (globalCtx->csCtx.unk_12 == 0)) || + !(gSaveContext.weekEventReg[21] & 8))) { + this->actor.child = func_80A13400(this, globalCtx); + this->actor.child->child = &this->actor; + func_80A141D4(this, globalCtx); + this->actionFunc = func_80A14E14; + } else { + func_80A143A8(this, globalCtx); + this->actionFunc = func_80A149B0; + } +} + +void func_80A14668(EnGo* this, GlobalContext* globalCtx) { + if (!(gSaveContext.weekEventReg[22] & 4)) { + func_80A14324(this, globalCtx); + this->actionFunc = func_80A149B0; + } else { + func_80A143A8(this, globalCtx); + this->actionFunc = func_80A149B0; + } +} + +void func_80A146CC(EnGo* this, GlobalContext* globalCtx) { + func_80A134B0(this, globalCtx, 0); + func_80A12C48(this, globalCtx, 0); + this->unk_3A4 *= 5.0f; + Actor_SetScale(&this->actor, this->unk_3A4); + this->actor.flags &= ~1; + this->actor.targetMode = 3; + this->unk_390 = 0; + this->actor.gravity = -1.0f; + func_8013AED4(&this->unk_390, 3, 7); + this->unk_390 |= 0x40; + this->unk_390 |= 0x20; + this->unk_3D8 = func_80A13E80; + this->actionFunc = func_80A149B0; +} + +void func_80A14798(EnGo* this, GlobalContext* globalCtx) { + s32 sp38[2] = { 0x0000003E, 0x00000F64 }; + + if ((this->unk_288 < 0) || func_8013D8DC(this->unk_288, globalCtx) || (this->unk_289 < 0) || + func_8013D8DC(this->unk_289, globalCtx)) { + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 20.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_oF1d_map_Skel_011AC8, NULL, this->jointTable, + this->morphTable, 18); + + this->unk_3DC = -1; + func_80A12C48(this, globalCtx, 2); + this->actor.draw = func_80A15FEC; + + Collider_InitAndSetSphere(globalCtx, &this->colliderSphere, &this->actor, &sSphereInit); + Collider_InitAndSetCylinder(globalCtx, &this->colliderCylinder, &this->actor, &sCylinderInit2); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + Effect_Add(globalCtx, &this->unk_3E8, 4, 0, 0, &sp38); + + this->actor.targetMode = 1; + this->unk_3A4 = 0.01f; + this->unk_3D8 = NULL; + + switch (ENGO_GET_F(&this->actor)) { + case ENGO_F_1: + func_80A14430(this, globalCtx); + break; + + case ENGO_F_2: + func_80A1449C(this, globalCtx); + break; + + case ENGO_F_3: + func_80A144F4(this, globalCtx); + break; + + case ENGO_F_4: + func_80A145AC(this, globalCtx); + break; + + case ENGO_F_5: + case ENGO_F_6: + case ENGO_F_7: + func_80A14668(this, globalCtx); + break; + + case ENGO_F_8: + func_80A146CC(this, globalCtx); + break; + + default: + Actor_MarkForDeath(&this->actor); + break; + } + } +} + +void func_80A149B0(EnGo* this, GlobalContext* globalCtx) { + s16 sp26 = this->actor.world.rot.y; + + if ((ENGO_GET_F(&this->actor) == ENGO_F_2) && (gSaveContext.entranceIndex == 0xD010)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_GORON_CHEER - SFX_FLAG); + } else if (ENGO_GET_F(&this->actor) != ENGO_F_8) { + if (func_80A1222C(this, globalCtx)) { + func_8013AED4(&this->unk_390, 0, 7); + this->unk_3EC = 1; + this->actionFunc = func_80A14B30; + } else if (ENGO_GET_F(&this->actor) == ENGO_F_4) { + switch (ENGO_GET_70(&this->actor)) { + case ENGO_70_0: + func_80A132C8(this, globalCtx); + break; + + case ENGO_70_1: + func_80A133A8(this, globalCtx); + break; + } + } else if (ENGO_GET_F(&this->actor) == ENGO_F_1) { + if (ABS_ALT(BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y)) < 0x3FFC) { + func_8013AED4(&this->unk_390, 3, 7); + } else { + func_8013AED4(&this->unk_390, 0, 7); + } + } + } + Math_ApproachS(&this->actor.shape.rot.y, sp26, 4, 0x2AA8); +} + +void func_80A14B30(EnGo* this, GlobalContext* globalCtx) { + s16 sp26 = this->actor.world.rot.y; + u16 sfxId; + + if (func_80A1222C(this, globalCtx)) { + this->unk_3EC = 1; + } + + if (this->unk_390 & 0x4000) { + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->unk_390 &= ~0x4000; + this->unk_390 |= 0x200; + if (this->unk_3EC != 0) { + this->unk_3AE = 0; + } + this->actor.shape.yOffset = 14.0f; + } + } else if (this->unk_390 & 0x8000) { + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->unk_390 |= 0x80; + this->unk_390 &= ~0x8000; + } + } else if (this->unk_390 & 0x200) { + if ((this->actor.xzDistToPlayer < 160.0f) && (this->actor.playerHeightRel < 20.0f) && (this->unk_3EC == 0)) { + func_80A12C48(this, globalCtx, 3); + this->unk_390 &= ~0x80; + this->unk_390 &= ~0x200; + this->unk_390 |= 0x8000; + this->actor.shape.yOffset = 0.0f; + } else if ((this->unk_3EC != 0) && (gSaveContext.weekEventReg[22] & 4)) { + this->actor.scale.x = this->unk_3A4 - (Math_SinS(this->unk_3AE) * 0.001f); + this->actor.scale.y = (Math_SinS(this->unk_3AE) * 0.001f) + this->unk_3A4; + this->actor.scale.z = (Math_SinS(this->unk_3AE) * 0.001f) + this->unk_3A4; + if (this->unk_3AE == 0) { + this->unk_3EC = -this->unk_3EC; + if (this->unk_3EC > 0) { + sfxId = NA_SE_EN_GOLON_SNORE1; + } else { + sfxId = NA_SE_EN_GOLON_SNORE2; + } + Audio_PlayActorSound2(&this->actor, sfxId); + } + this->unk_3AE += 0x400; + this->actor.shape.yOffset = (this->actor.scale.y / this->unk_3A4) * 14.0f; + func_8013AED4(&this->unk_390, 3, 7); + } + } else if ((this->actor.xzDistToPlayer >= 240.0f) || (this->actor.playerHeightRel >= 20.0f) || + (this->unk_3EC != 0)) { + func_80A12C48(this, globalCtx, 4); + this->unk_390 &= ~0x80; + this->unk_390 &= ~0x200; + this->unk_390 |= 0x4000; + this->actor.shape.yOffset = 0.0f; + } + + func_8013D9C8(globalCtx, &this->unk_3CE[0], &this->unk_3C8[0], 3); + Math_ApproachS(&this->actor.shape.rot.y, sp26, 4, 0x2AA8); +} + +void func_80A14E14(EnGo* this, GlobalContext* globalCtx) { + Actor* actor = this->colliderCylinder.base.ac; + + if ((this->unk_390 & 0x1000) && (((actor != NULL) && (actor->id == ACTOR_OBJ_AQUA) && (actor->params & 1)) || + (this->actor.colChkInfo.damageEffect == 2))) { + this->actionFunc = func_80A14E74; + } +} + +void func_80A14E74(EnGo* this, GlobalContext* globalCtx) { + if (func_80A134F4(this, this->actor.cutscene)) { + this->actionFunc = func_80A14EB0; + } +} + +void func_80A14EB0(EnGo* this, GlobalContext* globalCtx) { + EnGo* sp24 = (EnGo*)this->actor.child; + + if ((s32)(this->unk_39C * 3.0f) != 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_ICE_MELT_LEVEL - SFX_FLAG); + Math_ApproachF(&this->unk_39C, 0.0f, 0.02f, 1.0f); + this->unk_3A0 = (this->unk_39C / 0.9f) * 100.0f; + func_80A139E4(this); + } else { + ActorCutscene_Stop(this->actor.cutscene); + func_80A143A8(this, globalCtx); + if ((ENGO_GET_F(&this->actor) == ENGO_F_4) && (ENGO_GET_70(&this->actor) == ENGO_70_1)) { + func_8013AED4(&this->unk_390, 4, 7); + func_80A143A8(sp24, globalCtx); + sp24->actionFunc = func_80A149B0; + } + this->actionFunc = func_80A149B0; + } +} + +void func_80A14FC8(EnGo* this, GlobalContext* globalCtx) { + s32 sp38[] = { + 0, 2, 6, 20, 18, 5, 5, 15, + }; + u16 sp36 = 0; + s32 sp30; + u32 sp2C; + + switch (ENGO_GET_70(&this->actor)) { + case ENGO_70_0: + sp36 = 0x80; + break; + + case ENGO_70_1: + sp36 = 0x81; + break; + } + + if ((sp36 == 0x80) || (sp36 == 0x81)) { + if (func_800EE29C(globalCtx, sp36)) { + sp2C = func_800EE200(globalCtx, sp36); + sp30 = globalCtx->csCtx.npcActions[sp2C]->unk0; + + if (this->unk_394 != (u8)sp30) { + this->unk_394 = sp30; + func_80A12C48(this, globalCtx, sp38[sp30]); + this->unk_390 = 0; + this->unk_390 |= 0x20; + this->unk_3BE = 0; + this->unk_39C = 0.0f; + this->unk_3A0 = 0.0f; + + switch (sp30) { + case 1: + this->unk_390 |= 0x80; + this->skelAnime.curFrame = this->skelAnime.endFrame; + break; + + case 5: + case 6: + func_80A141D4(this, globalCtx); + break; + } + } + + switch (this->unk_394) { + case 3: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame) && (this->unk_3DC == 20)) { + func_80A12C48(this, globalCtx, 21); + } + break; + + case 4: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame) && (this->unk_3DC == 18)) { + func_80A12C48(this, globalCtx, 19); + } + break; + + case 6: + if ((s32)(this->unk_39C * 3.0f) != 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_ICE_MELT_LEVEL - SFX_FLAG); + Math_ApproachF(&this->unk_39C, 0.0f, 0.02f, 1.0f); + this->unk_3A0 = (this->unk_39C / 0.9f) * 100.0f; + func_80A139E4(this); + } else if (this->unk_390 & 0x400) { + func_80A143A8(this, globalCtx); + } + break; + } + + if (sp36 == 0x80) { + switch (globalCtx->csCtx.frames) { + case 55: + case 100: + case 130: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_COLD); + break; + + case 185: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_WAKE_UP); + break; + + case 250: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_EYE_BIG); + break; + + case 465: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_IWAIGORON_SOLO); + break; + + case 490: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_VOICE_EATFULL); + break; + } + } else if (sp36 == 0x81) { + switch (globalCtx->csCtx.frames) { + case 360: + case 390: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_COLD); + break; + + case 430: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_WAKE_UP); + break; + + case 450: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_EYE_BIG); + break; + + case 480: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_VOICE_EATFULL); + break; + } + } + + func_8013D9C8(globalCtx, this->unk_3CE, this->unk_3C8, 3); + func_800EDF24(&this->actor, globalCtx, sp2C); + } + } +} + +void func_80A153FC(EnGo* this, GlobalContext* globalCtx) { + Vec3s* sp5C; + Vec3f sp50; + Vec3f sp44; + + if ((this->unk_390 & 0x1000) && (this->actor.colChkInfo.damageEffect == 0xF)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_SNOWBALL_BROKEN); + + this->actor.flags &= ~0x10; + this->actor.flags |= 0x2000000; + + func_80A118F8(this->unk_3F8, this->actor.world.pos); + this->actor.shape.rot.x = 0; + this->actor.speedXZ = 0.0f; + + Audio_PlayActorSound2(&this->actor, NA_SE_EN_GOLON_COLD); + + if (gSaveContext.day == 3) { + func_80A141D4(this, globalCtx); + this->actionFunc = func_80A14E14; + } else { + func_80A143A8(this, globalCtx); + this->actionFunc = func_80A149B0; + } + } else if (this->unk_284 != NULL) { + if (this->unk_390 & 0x800) { + func_800B8E58(&GET_PLAYER(globalCtx)->actor, NA_SE_PL_BODY_HIT); + func_800B8D50(globalCtx, &this->actor, 2.0f, this->actor.yawTowardsPlayer, 0.0f, 0); + } + + sp5C = Lib_SegmentedToVirtual(this->unk_284->points); + if (func_8013BD40(&this->actor, this->unk_284, this->unk_3E4)) { + if (this->unk_3E4 >= (this->unk_284->count - 1)) { + this->unk_3E4 = 0; + } else { + this->unk_3E4++; + } + } + + Math_Vec3s_ToVec3f(&sp44, &sp5C[this->unk_3E4]); + Math_Vec3f_Copy(&sp50, &this->actor.world.pos); + Math_ApproachS(&this->actor.world.rot.y, Math_Vec3f_Yaw(&sp50, &sp44), 4, 0x38E); + this->actor.shape.rot.y = this->actor.world.rot.y; + + if (this->actor.bgCheckFlags & 1) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_BIGBALL_ROLL - SFX_FLAG); + func_800AE930(&globalCtx->colCtx, Effect_GetByIndex(this->unk_3E8), &this->actor.world.pos, 18.0f, + this->actor.shape.rot.y, this->actor.floorPoly, this->actor.floorBgId); + } else { + func_800AEF44(Effect_GetByIndex(this->unk_3E8)); + } + + this->actor.speedXZ = 4.0f; + this->actor.shape.rot.x += (s16)(this->actor.speedXZ * 546.0f); + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + } +} + +s32* func_80A15684(EnGo* this, GlobalContext* globalCtx) { + static s32 D_80A16704[] = { + D_80A16100, + D_80A16164, + }; + + if (this->unk_3EC != 0) { + return D_80A1640C; + } + + if (ENGO_GET_F(&this->actor) == ENGO_F_1) { + switch (ENGO_GET_70(&this->actor) % 6) { + case ENGO_70_0: + return D_80A163BC; + case ENGO_70_1: + return D_80A163CC; + case ENGO_70_2: + return D_80A163DC; + case ENGO_70_3: + return D_80A163EC; + case ENGO_70_4: + return D_80A163FC; + case ENGO_70_5: + return D_80A163FC; + } + } + + switch (ENGO_GET_F(&this->actor)) { + case ENGO_F_3: + return D_80A16350; + case ENGO_F_4: + return D_80A16704[ENGO_GET_70(&this->actor)]; + case ENGO_F_5: + return D_80A16208; + case ENGO_F_6: + return D_80A16254; + case ENGO_F_7: + return D_80A16210; + case ENGO_F_8: + return D_80A16280; + default: + return D_80A16208; + } +} + +void func_80A157C4(EnGo* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp40; + Vec3f sp34; + + if (!func_8010BF58(&this->actor, globalCtx, func_80A15684(this, globalCtx), this->unk_3D8, &this->unk_28C)) { + if ((ENGO_GET_F(&this->actor) != ENGO_F_1) && !(this->unk_390 & 0x200)) { + Math_Vec3f_Copy(&sp40, &this->unk_38C->world.pos); + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + Math_ApproachS(&this->actor.shape.rot.y, Math_Vec3f_Yaw(&sp34, &sp40), 4, 0x2AA8); + } + func_8013D9C8(globalCtx, this->unk_3CE, this->unk_3C8, 3); + return; + } + + if ((ENGO_GET_F(&this->actor) == ENGO_F_5) || (ENGO_GET_F(&this->actor) == ENGO_F_6) || + (ENGO_GET_F(&this->actor) == ENGO_F_7)) { + this->unk_3BC = 0; + this->unk_390 &= ~0x20; + this->unk_3BE = 4; + } + + this->unk_390 &= ~0x8; + func_8013AED4(&this->unk_390, 3, 7); + this->unk_28C = 0; + this->unk_390 |= 0x40; + this->actionFunc = this->unk_18C; +} + +void EnGo_Init(Actor* thisx, GlobalContext* globalCtx) { + EnGo* this = THIS; + + this->unk_288 = func_8013D924(OBJECT_TAISOU, globalCtx); + this->unk_289 = func_8013D924(OBJECT_HAKUGIN_DEMO, globalCtx); + this->actionFunc = func_80A14798; +} + +void EnGo_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnGo* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->colliderCylinder); + Collider_DestroySphere(globalCtx, &this->colliderSphere); + Effect_Destroy(globalCtx, this->unk_3E8); +} + +void EnGo_Update(Actor* thisx, GlobalContext* globalCtx) { + EnGo* this = THIS; + f32 phi_f0; + + func_80A12868(this, globalCtx); + if (!func_80A12774(this, globalCtx)) { + func_80A12954(this, globalCtx); + } + + this->actionFunc(this, globalCtx); + + if (!(this->unk_390 & 0x400)) { + func_80A12D6C(this); + func_80A12A64(this, globalCtx); + func_80A131F8(this, globalCtx); + func_80A12B78(this, globalCtx); + } + + if (!(this->unk_390 & 0x100) && !(this->unk_390 & 0x200) && !(this->unk_390 & 0x400)) { + if (ENGO_GET_F(&this->actor) == ENGO_F_8) { + phi_f0 = this->colliderSphere.dim.worldSphere.radius + 60; + } else { + phi_f0 = this->colliderCylinder.dim.radius + 40; + } + func_8013C964(&this->actor, globalCtx, phi_f0, 20.0f, 0, this->unk_390 & 7); + } else if ((this->unk_390 & 0x200) && (this->unk_3EC != 0)) { + phi_f0 = this->colliderCylinder.dim.radius + 40; + func_8013C964(&this->actor, globalCtx, phi_f0, 20.0f, 0, this->unk_390 & 7); + } + + if ((ENGO_GET_F(&this->actor) != ENGO_F_8) && (ENGO_GET_F(&this->actor) != ENGO_F_2) && + (ENGO_GET_F(&this->actor) != ENGO_F_1)) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 4); + } + + func_80A122EC(this); + func_80A126BC(this, globalCtx); + func_80A1203C(this); +} + +void func_80A15B80(EnGo* this, GlobalContext* globalCtx) { + Gfx* gfx; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y + this->actor.shape.yOffset, + this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, -this->actor.shape.yOffset, 0.0f, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->actor.shape.rot.z, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, this->actor.shape.yOffset, 0.0f, MTXMODE_APPLY); + + if (this->unk_390 & 0x100) { + Matrix_Scale(this->actor.scale.x * 8.0f, this->actor.scale.y * 8.0f, this->actor.scale.z * 8.0f, MTXMODE_APPLY); + } else { + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + } + + Matrix_InsertXRotation_s(this->actor.shape.rot.x, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, (this->unk_390 & 0x100) ? object_oF1d_map_DL_001560 : object_oF1d_map_DL_0091A8); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +s32 EnGo_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnGo* this = THIS; + Vec3f sp30; + s32 idx; + + if ((ENGO_GET_F(&this->actor) == ENGO_F_8) && (limbIndex == 10)) { + limbIndex = limbIndex; + Matrix_GetStateTranslation(&sp30); + sp30.y = this->actor.world.pos.y; + Math_Vec3f_ToVec3s(&this->colliderSphere.dim.worldSphere.center, &sp30); + } + + switch (limbIndex) { + case 10: + idx = 0; + break; + + case 11: + idx = 1; + break; + + case 14: + idx = 2; + break; + + default: + idx = 9; + break; + } + + if ((this->unk_390 & 0x80) && (idx < 9)) { + rot->y += (s16)(Math_SinS(this->unk_3CE[idx]) * 200.0f); + rot->z += (s16)(Math_CosS(this->unk_3C8[idx]) * 200.0f); + } + return false; +} + +void EnGo_UnkDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnGo* this = THIS; + u16 temp_v0; + s32 phi_v1; + s32 phi_v0; + + if (this->unk_390 & 0x40) { + phi_v1 = false; + } else { + phi_v1 = true; + } + + if (this->unk_390 & 0x10) { + phi_v0 = true; + } else { + phi_v0 = false; + } + + if (!phi_v1) { + phi_v0 = false; + } + + switch (limbIndex) { + case 17: + func_8013AD9C(this->unk_3B0 + this->unk_3B4 + 0x4000, + this->unk_3B2 + this->unk_3B6 + this->actor.shape.rot.y + 0x4000, &this->unk_290, + &this->unk_2A8, phi_v1, phi_v0); + Matrix_StatePop(); + Matrix_InsertTranslation(this->unk_290.x, this->unk_290.y, this->unk_290.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateY(this->unk_2A8.y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->unk_2A8.x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->unk_2A8.z, MTXMODE_APPLY); + Matrix_StatePush(); + break; + + case 10: + func_8013AD9C(this->unk_3B4 + 0x4000, this->unk_3B6 + this->actor.shape.rot.y + 0x4000, &this->unk_29C, + &this->unk_2AE, phi_v1, phi_v0); + Matrix_StatePop(); + Matrix_InsertTranslation(this->unk_29C.x, this->unk_29C.y, this->unk_29C.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + Matrix_RotateY(this->unk_2AE.y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->unk_2AE.x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->unk_2AE.z, MTXMODE_APPLY); + Matrix_StatePush(); + break; + } +} + +void func_80A15FEC(Actor* thisx, GlobalContext* globalCtx) { + static UNK_TYPE D_80A1670C[] = { + &object_oF1d_map_Tex_010438, &object_oF1d_map_Tex_010C38, &object_oF1d_map_Tex_011038, + &object_oF1d_map_Tex_010C38, &object_oF1d_map_Tex_010838, + }; + EnGo* this = THIS; + + if (!(this->unk_390 & 0x300)) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80A1670C[this->unk_3BE])); + + if (this->unk_3DC == 14) { + Matrix_InsertTranslation(0.0f, 0.0f, -4000.0f, MTXMODE_APPLY); + } + func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnGo_OverrideLimbDraw, NULL, EnGo_UnkDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } else { + func_80A15B80(this, globalCtx); + } + func_80A137C0(this, globalCtx, this->unk_39C, this->unk_3A0); + func_80A1213C(this, globalCtx); +} diff --git a/src/overlays/actors/ovl_En_Go/z_en_go.h b/src/overlays/actors/ovl_En_Go/z_en_go.h index 08363e822..ab7f068e1 100644 --- a/src/overlays/actors/ovl_En_Go/z_en_go.h +++ b/src/overlays/actors/ovl_En_Go/z_en_go.h @@ -7,11 +7,98 @@ struct EnGo; typedef void (*EnGoActionFunc)(struct EnGo*, GlobalContext*); +#define ENGO_GET_F(thisx) (((thisx)->params & 0xF) & 0xFF) +#define ENGO_GET_70(thisx) ((((thisx)->params & 0x70) >> 4) & 0xFF) +#define ENGO_GET_7F80(thisx) ((((thisx)->params & 0x7F80) >> 7) & 0xFF) + +enum { + /* 0 */ ENGO_F_0, + /* 1 */ ENGO_F_1, + /* 2 */ ENGO_F_2, + /* 3 */ ENGO_F_3, + /* 4 */ ENGO_F_4, + /* 5 */ ENGO_F_5, + /* 6 */ ENGO_F_6, + /* 7 */ ENGO_F_7, + /* 8 */ ENGO_F_8, +}; + +enum { + /* 0 */ ENGO_70_0, + /* 1 */ ENGO_70_1, + /* 2 */ ENGO_70_2, + /* 3 */ ENGO_70_3, + /* 4 */ ENGO_70_4, + /* 5 */ ENGO_70_5, +}; + +typedef struct { + /* 0x00 */ u8 unk_00; + /* 0x01 */ u8 unk_01; + /* 0x02 */ u8 unk_02; + /* 0x04 */ Vec3s unk_04; + /* 0x0A */ Vec3s unk_0A; + /* 0x10 */ Vec3f unk_10; + /* 0x1C */ Vec3f unk_1C; + /* 0x28 */ Vec3f unk_28; + /* 0x34 */ f32 unk_34; + /* 0x38 */ f32 unk_38; +} EnGoStruct; // size = 0x3C; + typedef struct EnGo { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnGoActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x9EC]; + /* 0x018C */ EnGoActionFunc unk_18C; + /* 0x0190 */ EnGoActionFunc unk_190; + /* 0x0194 */ ColliderCylinder colliderCylinder; + /* 0x01E0 */ UNK_TYPE1 unk1E0[0x4C]; + /* 0x022C */ ColliderSphere colliderSphere; + /* 0x0284 */ Path* unk_284; + /* 0x0288 */ s8 unk_288; + /* 0x0289 */ s8 unk_289; + /* 0x028C */ s32 unk_28C; + /* 0x0290 */ Vec3f unk_290; + /* 0x029C */ Vec3f unk_29C; + /* 0x02A8 */ Vec3s unk_2A8; + /* 0x02AE */ Vec3s unk_2AE; + /* 0x02B4 */ Vec3s jointTable[18]; + /* 0x0320 */ Vec3s morphTable[18]; + /* 0x038C */ Actor* unk_38C; + /* 0x0390 */ u16 unk_390; + /* 0x0392 */ u16 unk_392; + /* 0x0394 */ u8 unk_394; + /* 0x0398 */ f32 unk_398; + /* 0x039C */ f32 unk_39C; + /* 0x03A0 */ f32 unk_3A0; + /* 0x03A4 */ f32 unk_3A4; + /* 0x03A8 */ f32 unk_3A8; + /* 0x03AC */ UNK_TYPE1 unk3AC[0x2]; + /* 0x03AE */ s16 unk_3AE; + /* 0x03B0 */ s16 unk_3B0; + /* 0x03B2 */ s16 unk_3B2; + /* 0x03B4 */ s16 unk_3B4; + /* 0x03B6 */ s16 unk_3B6; + /* 0x03B8 */ s16 unk_3B8; + /* 0x03BA */ s16 unk_3BA; + /* 0x03BC */ s16 unk_3BC; + /* 0x03BE */ s16 unk_3BE; + /* 0x03C0 */ s16 unk_3C0; + /* 0x03C2 */ s16 unk_3C2; + /* 0x03C4 */ s16 unk_3C4; + /* 0x03C6 */ s16 unk_3C6; + /* 0x03C8 */ s16 unk_3C8[3]; + /* 0x03CE */ s16 unk_3CE[3]; + /* 0x03D4 */ s16 unk_3D4; + /* 0x03D8 */ void* unk_3D8; + /* 0x03DC */ s32 unk_3DC; + /* 0x03E0 */ UNK_TYPE1 unk3E0[0x4]; + /* 0x03E4 */ s32 unk_3E4; + /* 0x03E8 */ s32 unk_3E8; + /* 0x03EC */ s32 unk_3EC; + /* 0x03F0 */ s32 unk_3F0; + /* 0x03F4 */ s32 unk_3F4; + /* 0x03F8 */ EnGoStruct unk_3F8[32]; } EnGo; // size = 0xB78 extern const ActorInit En_Go_InitVars; diff --git a/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c b/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c index 22ea6a953..3a74a8a5f 100644 --- a/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c +++ b/src/overlays/actors/ovl_En_Goroiwa/z_en_goroiwa.c @@ -1481,7 +1481,7 @@ void EnGoroiwa_Update(Actor* thisx, GlobalContext* globalCtx) { sp50.y = this->actor.floorHeight; sp50.z = this->actor.world.pos.z; sp4C = (((Rand_ZeroOne() * 36.0f) + 250.0f) * this->actor.scale.x) + 10.0f; - func_800AE930(&globalCtx->colCtx, Effect_GetParams(this->unk_248), &sp50, sp4C, + func_800AE930(&globalCtx->colCtx, Effect_GetByIndex(this->unk_248), &sp50, sp4C, this->actor.world.rot.y, this->actor.floorPoly, this->actor.floorBgId); } sp48 = false; @@ -1491,7 +1491,7 @@ void EnGoroiwa_Update(Actor* thisx, GlobalContext* globalCtx) { } if (sp48) { - func_800AEF44(Effect_GetParams(this->unk_248)); + func_800AEF44(Effect_GetByIndex(this->unk_248)); } this->actionFunc(this, globalCtx); @@ -1591,7 +1591,7 @@ void func_80942B1C(EnGoroiwa* this, GlobalContext* globalCtx) { sp80.z = ptr->unk_20; Matrix_SetStateRotationAndTranslation(ptr->unk_00.x, ptr->unk_00.y, ptr->unk_00.z, &sp80); - Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, 1); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); func_800BDFC0(globalCtx, phi_fp); if ((ptr->unk_28 != 0) && (ptr->unk_2C > 0)) { @@ -1605,7 +1605,7 @@ void func_80942B1C(EnGoroiwa* this, GlobalContext* globalCtx) { func_800C0094(ptr->unk_28, ptr->unk_00.x, ptr->unk_18, ptr->unk_00.z, &sp88); Matrix_SetCurrentState(&sp88); - Matrix_Scale(this->actor.scale.x * 7.5f, 1.0f, this->actor.scale.z * 7.5f, 1); + Matrix_Scale(this->actor.scale.x * 7.5f, 1.0f, this->actor.scale.z * 7.5f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); diff --git a/src/overlays/actors/ovl_En_Gs/z_en_gs.c b/src/overlays/actors/ovl_En_Gs/z_en_gs.c index 4b96987f7..b5199982f 100644 --- a/src/overlays/actors/ovl_En_Gs/z_en_gs.c +++ b/src/overlays/actors/ovl_En_Gs/z_en_gs.c @@ -15,7 +15,31 @@ void EnGs_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnGs_Update(Actor* thisx, GlobalContext* globalCtx); void EnGs_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80997D14(EnGs* this, GlobalContext* globalCtx); +void func_80997D38(EnGs* this, GlobalContext* globalCtx); +void func_80997E4C(EnGs* this, GlobalContext* globalCtx); +void func_80998040(EnGs* this, GlobalContext* globalCtx); +void func_8099807C(EnGs* this, GlobalContext* globalCtx); +void func_80998300(EnGs* this, GlobalContext* globalCtx); +void func_809984F4(EnGs* this, GlobalContext* globalCtx); +void func_809985B8(EnGs* this, GlobalContext* globalCtx); +void func_80998704(EnGs* this, GlobalContext* globalCtx); +void func_8099874C(EnGs* this, GlobalContext* globalCtx); +void func_809989B4(EnGs* this, GlobalContext* globalCtx); +void func_809989F4(EnGs* this, GlobalContext* globalCtx); +s32 func_80998A48(EnGs* this, GlobalContext* globalCtx); +s32 func_80998BBC(EnGs* this, GlobalContext* globalCtx); +s32 func_80998D44(EnGs* this, GlobalContext* globalCtx); +s32 func_80998F9C(EnGs* this, GlobalContext* globalCtx); +s32 func_809995A4(EnGs* this, GlobalContext* globalCtx); +void func_80999A8C(EnGs* this, GlobalContext* globalCtx); +void func_80999AC0(EnGs* this); + +extern Gfx gGameplayKeepDrawFlameDL[]; +extern Gfx D_06000950[]; +extern Gfx D_060009D0[]; +extern Gfx D_06000A60[]; + const ActorInit En_Gs_InitVars = { ACTOR_EN_GS, ACTORCAT_PROP, @@ -28,18 +52,29 @@ const ActorInit En_Gs_InitVars = { (ActorFunc)EnGs_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_8099A3A0 = { - { COLTYPE_METAL, AT_NONE, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_METAL, + AT_NONE, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 21, 48, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_8099A3CC = { 0, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 0, 0, 0, 0, MASS_IMMOVABLE }; -// static DamageTable sDamageTable = { -static DamageTable D_8099A3D8 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0xE), /* Deku Stick */ DMG_ENTRY(0, 0xF), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -74,78 +109,1001 @@ static DamageTable D_8099A3D8 = { /* Powder Keg */ DMG_ENTRY(0, 0xC), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_8099A404[] = { +s8 func_80997A90(s16 arg0, s16 arg1) { + s8 phi_v1; + + if ((arg0 == 0) || ((arg0 != 1) && (arg0 != 2) && (arg0 == 3))) { + phi_v1 = 0; + } else { + phi_v1 = (gSaveContext.roomInf[126][1] >> (arg1 * 3)) & 7; + } + return phi_v1; +} + +void func_80997AFC(s32 idx, Color_RGB8* arg1) { + static Color_RGB8 D_8099A3F8[] = { + { 255, 255, 255 }, + { 150, 255, 100 }, + { 255, 80, 40 }, + { 100, 150, 255 }, + }; + + *arg1 = D_8099A3F8[idx]; +} + +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -#endif +void EnGs_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnGs* this = THIS; -extern ColliderCylinderInit D_8099A3A0; -extern CollisionCheckInfoInit2 D_8099A3CC; -extern DamageTable D_8099A3D8; -extern InitChainEntry D_8099A404[]; + Actor_ProcessInitChain(&this->actor, sInitChain); + this->unk_208 = -1; + this->unk_204 = 1; + this->unk_198 = this->actor.world.rot.z; + this->unk_195 = ENGS_GET_1F(thisx); + this->unk_196 = ENGS_GET_FE0(thisx); + this->actor.params = ENGS_GET_F000(thisx); + this->actor.world.rot.z = 0; + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + this->actor.targetMode = 6; + this->unk_216 = 0; + this->unk_218 = 0; + this->unk_200 = 1.0f; + this->unk_194 = func_80997A90(this->actor.params, this->unk_198); -extern UNK_TYPE D_06000950; + func_80997AFC(this->unk_194, &this->unk_1FA); + this->unk_1F4 = this->unk_1FA; + Math_Vec3f_Copy(&this->unk_1B0[0], &D_801C5DB0); + Math_Vec3f_Copy(&this->unk_1B0[1], &D_801C5DB0); + func_8013E3B8(&this->actor, &this->unk_212, 2); + func_801A5080(0); + if (this->actor.params == ENGS_1) { + Actor_SetScale(&this->actor, 0.15f); + this->collider.dim.radius *= 1.5f; + this->collider.dim.height *= 1.5f; + } + func_80997D14(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80997A90.s") +void EnGs_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnGs* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80997AFC.s") + Collider_DestroyCylinder(globalCtx, &this->collider); + func_80165690(); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/EnGs_Init.s") +void func_80997D14(EnGs* this, GlobalContext* globalCtx) { + this->unk_19A &= ~0x200; + this->actionFunc = func_80997D38; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/EnGs_Destroy.s") +void func_80997D38(EnGs* this, GlobalContext* globalCtx) { + static f32 D_8099A408[] = { 40.0f, 60.0f, 40.0f, 40.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80997D14.s") + if (!func_80152498(&globalCtx->msgCtx)) { + if (this->actor.xzDistToPlayer <= D_8099A408[this->actor.params]) { + func_8013E8F8(&this->actor, globalCtx, D_8099A408[this->actor.params], D_8099A408[this->actor.params], 0, + 0x2000, 0x2000); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80997D38.s") + if (this->actor.params != ENGS_2) { + func_800B874C(&this->actor, globalCtx, 100.0f, 100.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80997DEC.s") +void func_80997DEC(EnGs* this, GlobalContext* globalCtx) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_TRUTH) { + this->unk_210 = 0x20D1; + } else { + this->unk_210 = 0x20D0; + } + this->unk_19A |= 0x200; + this->actionFunc = func_80997E4C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80997E4C.s") +void func_80997E4C(EnGs* this, GlobalContext* globalCtx) { + switch (func_80152498(&globalCtx->msgCtx)) { + case 0: + func_801518B0(globalCtx, this->unk_210, &this->actor); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80997FF0.s") + case 1: + case 2: + case 3: + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80998040.s") + case 4: + case 5: + case 6: + if (func_80147624(globalCtx)) { + switch (globalCtx->msgCtx.unk11F04) { + case 0x20D0: + func_80997D14(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_8099807C.s") + case 0x20D1: + switch (this->actor.params) { + case ENGS_0: + this->unk_210 = this->unk_195 + 0x20D3; + if (this->unk_210 >= 0x20D4) { + s32 temp_v1 = this->unk_210 - 0x20D4; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80998300.s") + if ((this->unk_210 < 0x20E8) && + ((temp_v1 + ITEM_MASK_TRUTH) == INV_CONTENT(temp_v1 + ITEM_MASK_TRUTH))) { + this->unk_210 = temp_v1 + 0x2103; + } + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80998334.s") + case ENGS_3: + this->unk_210 = this->unk_195 + 0x20B0; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_809984F4.s") + case ENGS_1: + this->unk_210 = this->unk_195 + 0x20F3; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_809985B8.s") + case ENGS_2: + this->unk_210 = this->unk_195 + 0x20F7; + break; + } + func_80151938(globalCtx, this->unk_210); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80998704.s") + default: + func_80997D14(this, globalCtx); + break; + } + } + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_8099874C.s") +void func_80997FF0(EnGs* this, GlobalContext* globalCtx) { + if (func_8013E2D4(&this->actor, globalCtx->unk_1879C[0], -1, 1)) { + func_80998040(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_809989B4.s") +void func_80998040(EnGs* this, GlobalContext* globalCtx) { + func_80152434(globalCtx, 1); + this->actionFunc = func_8099807C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_809989F4.s") +void func_8099807C(EnGs* this, GlobalContext* globalCtx) { + switch (globalCtx->msgCtx.unk1202A) { + case 3: + switch (globalCtx->msgCtx.unk1202E) { + case 7: + case 8: + if (!Flags_GetSwitch(globalCtx, this->unk_196)) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELF, this->actor.world.pos.x, + this->actor.world.pos.y + 40.0f, this->actor.world.pos.z, 0, 0, 0, 2); + Audio_PlayActorSound2(&this->actor, NA_SE_EV_BUTTERFRY_TO_FAIRY); + Actor_SetSwitchFlag(globalCtx, this->unk_196); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80998A48.s") + case 10: + if (!Flags_GetSwitch(globalCtx, this->unk_196)) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ELF, this->actor.world.pos.x, + this->actor.world.pos.y + 40.0f, this->actor.world.pos.z, 0, 0, 0, 7); + Audio_PlayActorSound2(&this->actor, NA_SE_EV_BUTTERFRY_TO_FAIRY); + Actor_SetSwitchFlag(globalCtx, this->unk_196); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80998BBC.s") + case 0: + if ((this->actor.params == ENGS_1) && (gSaveContext.playerForm == PLAYER_FORM_DEKU)) { + this->unk_194 = 1; + this->unk_19C = 5; + this->unk_19A |= 1; + func_80999AC0(this); + func_809984F4(this, globalCtx); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80998D44.s") + case 2: + if ((this->actor.params == ENGS_1) && (gSaveContext.playerForm == PLAYER_FORM_ZORA)) { + this->unk_194 = 3; + this->unk_19C = 5; + this->unk_19A |= 1; + func_80999AC0(this); + func_809984F4(this, globalCtx); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80998F9C.s") + case 1: + if ((this->actor.params == ENGS_1) && (gSaveContext.playerForm == PLAYER_FORM_GORON)) { + this->unk_194 = 2; + this->unk_19C = 5; + this->unk_19A |= 1; + func_80999AC0(this); + func_809984F4(this, globalCtx); + } + break; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80999584.s") + case 0: + case 4: + func_80998300(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_809995A4.s") + case 26: + func_80997D14(this, globalCtx); + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80999A8C.s") +void func_80998300(EnGs* this, GlobalContext* globalCtx) { + if (this->actor.cutscene != -1) { + ActorCutscene_Stop(globalCtx->unk_1879C[0]); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80999AC0.s") +f32 func_80998334(EnGs* this, GlobalContext* globalCtx, f32* arg2, f32* arg3, s16* arg4, f32 arg5, f32 arg6, f32 arg7, + s32 arg8, s32 arg9) { + f32 sp2C = Math_SmoothStepToF(arg2, *arg3, arg5, arg6, arg7); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80999B34.s") + if (arg9 == 0) { + sp2C = Math_SmoothStepToF(arg2, *arg3, arg5, arg6, arg7); + this->unk_1B0[0].x = (__sinf(DEGF_TO_RADF((*arg4 % arg8) * (1.0f / arg8) * 360.0f)) * *arg2) + 1.0f; + this->unk_1B0[0].y = 1.0f - (__sinf(DEGF_TO_RADF((*arg4 % arg8) * (1.0f / arg8) * 360.0f)) * *arg2); + (*arg4)++; + } + return sp2C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/func_80999BC8.s") +void func_809984F4(EnGs* this, GlobalContext* globalCtx) { + EnGs* gossipStone = NULL; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/EnGs_Update.s") + do { + gossipStone = (EnGs*)SubS_FindActor(globalCtx, &gossipStone->actor, ACTORCAT_PROP, ACTOR_EN_GS); + if (gossipStone != NULL) { + if ((this != gossipStone) && (this->unk_194 == gossipStone->unk_194)) { + gossipStone->unk_19A |= 1; + func_80999AC0(gossipStone); + gossipStone->unk_19C = 3; + func_80998704(gossipStone, globalCtx); + } + gossipStone = (EnGs*)gossipStone->actor.next; + } + } while (gossipStone != NULL); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Gs/EnGs_Draw.s") + func_800B7298(globalCtx, &this->actor, 7); + this->actionFunc = func_809985B8; +} + +void func_809985B8(EnGs* this, GlobalContext* globalCtx) { + EnGs* gossipStone; + Vec3f sp38; + + if (func_8013E2D4(&this->actor, this->unk_212, -1, 0)) { + Player* player = GET_PLAYER(globalCtx); + + Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_NEW); + Matrix_GetStateTranslationAndScaledZ(160.0f, &sp38); + Math_Vec3f_Sum(&player->actor.world.pos, &sp38, &player->actor.world.pos); + Math_Vec3f_Copy(&player->actor.prevPos, &player->actor.world.pos); + this->unk_200 = 0.0f; + gSaveContext.roomInf[126][1] = + (gSaveContext.roomInf[126][1] & ~(7 << (this->unk_198 * 3))) | ((this->unk_194 & 7) << (this->unk_198 * 3)); + gossipStone = NULL; + + do { + gossipStone = (EnGs*)SubS_FindActor(globalCtx, &gossipStone->actor, ACTORCAT_PROP, ACTOR_EN_GS); + if (gossipStone != NULL) { + if ((gossipStone != this) && (gossipStone->actor.params == ENGS_2) && + (gossipStone->unk_198 == this->unk_198)) { + gossipStone->unk_194 = this->unk_194; + gossipStone->unk_200 = 0.0f; + } + gossipStone = (EnGs*)gossipStone->actor.next; + } + } while (gossipStone != NULL); + + func_80998704(this, globalCtx); + } +} + +void func_80998704(EnGs* this, GlobalContext* globalCtx) { + this->unk_19D = 0; + this->unk_19A &= ~(0x100 | 0x4); + Audio_PlayActorSound2(&this->actor, NA_SE_EV_G_STONE_CHANGE_COLOR); + this->actionFunc = func_8099874C; +} + +void func_8099874C(EnGs* this, GlobalContext* globalCtx) { + s32 phi_v0 = 0; + + switch (this->unk_19C) { + case 0: + phi_v0 = func_80998A48(this, globalCtx); + break; + + case 1: + phi_v0 = func_80998BBC(this, globalCtx); + break; + + case 2: + phi_v0 = func_80998D44(this, globalCtx); + break; + + case 3: + case 5: + phi_v0 = func_80998F9C(this, globalCtx); + break; + + case 4: + phi_v0 = func_809995A4(this, globalCtx); + break; + } + + if (phi_v0 == 0) { + this->unk_216 = 0; + if ((this->unk_19C == 5) && (this->unk_194 != 0)) { + s32 i; + + ActorCutscene_Stop(this->unk_212); + phi_v0 = 1; + + for (i = 0; i < 4; i++) { + if (((gSaveContext.roomInf[126][1] >> (i * 3)) & 7) != (u32)this->unk_194) { + phi_v0 = 0; + } + } + + if (phi_v0 != 0) { + this->unk_20C = -1; + switch (this->unk_194) { + case 1: + if (!(gSaveContext.weekEventReg[77] & 8)) { + this->unk_20C = 6; + gSaveContext.weekEventReg[77] |= 8; + } + break; + + case 3: + if (!(gSaveContext.weekEventReg[77] & 0x10)) { + this->unk_20C = 6; + gSaveContext.weekEventReg[77] |= 0x10; + } + break; + + case 2: + if (!(gSaveContext.weekEventReg[77] & 0x20)) { + this->unk_20C = 6; + gSaveContext.weekEventReg[77] |= 0x20; + } + break; + } + + if (!(gSaveContext.weekEventReg[90] & 0x10)) { + gSaveContext.weekEventReg[90] |= 0x10; + this->unk_20C = 12; + } + + if (this->unk_20C > 0) { + func_809989B4(this, globalCtx); + } else { + func_80997D14(this, globalCtx); + } + } else { + func_80997D14(this, globalCtx); + } + } else { + func_80997D14(this, globalCtx); + } + } +} + +void func_809989B4(EnGs* this, GlobalContext* globalCtx) { + func_800B8A1C(&this->actor, globalCtx, this->unk_20C, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + this->actionFunc = func_809989F4; +} + +void func_809989F4(EnGs* this, GlobalContext* globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + func_80997D14(this, globalCtx); + } else { + func_800B8A1C(&this->actor, globalCtx, this->unk_20C, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + } +} + +s32 func_80998A48(EnGs* this, GlobalContext* globalCtx) { + s32 sp3C = -1; + + if (this->unk_19D == 0) { + this->unk_216 = 200; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_ATTACK); + + this->unk_1D4 = 0; + this->unk_19A |= 1; + this->unk_21C = 5; + this->unk_21E = 40; + this->unk_197++; + this->unk_197 &= 0xF; + this->unk_19D = 1; + + this->unk_1DC = 0.5f; + this->unk_1E0 = 0.0f; + } else if (this->unk_19D == 1) { + if (func_80998334(this, globalCtx, &this->unk_1DC, &this->unk_1E0, &this->unk_1D4, 0.8f, 0.007f, 0.001f, 7, + 0) == 0.0f) { + if ((this->actor.params != ENGS_0) && !func_801690CC(globalCtx) && !func_80152498(&globalCtx->msgCtx)) { + this->unk_216 = 0; + Audio_PlayActorSound2(&this->actor, NA_SE_EV_FAIVE_LUPY_COUNT); + func_801518B0(globalCtx, 0x20D2, NULL); + } + this->unk_19A &= ~1; + sp3C = 0; + } + } + return sp3C; +} + +s32 func_80998BBC(EnGs* this, GlobalContext* globalCtx) { + s32 sp34 = -1; + + if (this->unk_19D == 0) { + this->unk_216 = 200; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_ATTACK); + this->unk_1DC = 0.3f; + this->unk_1E0 = 0.0f; + + this->unk_1D4 = 0; + this->unk_19A |= 1; + this->unk_21C = 5; + this->unk_21E = 40; + this->unk_197--; + this->unk_197 &= 0xF; + this->unk_19D = 1; + } else if (this->unk_19D == 1) { + this->unk_19E[0].z = (this->unk_1D4 % 8) * 0.125f * 360.0f * (0x10000 / 360.0f); + this->unk_19E[1].z = -this->unk_19E[0].z; + if (func_80998334(this, globalCtx, &this->unk_1DC, &this->unk_1E0, &this->unk_1D4, 0.8f, 0.005f, 0.001f, 7, + 0) == 0.0f) { + this->unk_19A &= ~1; + sp34 = 0; + } + } + return sp34; +} + +s32 func_80998D44(EnGs* this, GlobalContext* globalCtx) { + s32 sp3C = -1; + f32 step; + + if (this->unk_19D == 0) { + this->unk_216 = 200; + this->unk_1DC = this->unk_1B0[0].y - 1.0f; + this->unk_1E0 = -0.8f; + Audio_PlayActorSound2(&this->actor, NA_SE_EV_G_STONE_CRUSH); + this->unk_19A |= 1; + this->unk_21C = 40; + this->unk_21E = 11; + this->unk_19D++; + } else if (this->unk_19D == 1) { + step = Math_SmoothStepToF(&this->unk_1DC, this->unk_1E0, 1.0f, 0.4f, 0.001f); + this->unk_1B0[0].y = this->unk_1DC + 1.0f; + if (step == 0.0f) { + this->unk_216 = 0; + this->unk_1D4 = 0; + this->unk_19D++; + } + } else if (this->unk_19D == 2) { + this->unk_1D4++; + if (this->unk_1D4 >= 100) { + this->unk_216 = 200; + this->unk_19D++; + this->unk_1DC = this->unk_1B0[0].y - 1.0f; + this->unk_1E0 = 0.0f; + } + } else if (this->unk_19D == 3) { + step = Math_SmoothStepToF(&this->unk_1DC, this->unk_1E0, 1.0f, 0.5f, 0.001f); + this->unk_1B0[0].y = this->unk_1DC + 1.0f; + if (step == 0.0f) { + this->unk_216 = 0; + this->unk_1E0 = 0.0f; + this->unk_1D4 = 0; + this->unk_21C = 10; + this->unk_21E = 10; + this->unk_1DC = 0.5f; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_ATTACK); + this->unk_19D += 1; + } + } else if ((this->unk_19D == 4) && (func_80998334(this, globalCtx, &this->unk_1DC, &this->unk_1E0, &this->unk_1D4, + 1.0f, 0.03f, 0.001f, 5, 0) == 0.0f)) { + this->unk_19A &= ~1; + sp3C = 0; + } + return sp3C; +} + +s32 func_80998F9C(EnGs* this, GlobalContext* globalCtx) { + s32 sp4C = -1; + f32 sp48; + f32 sp44; + f32 sp40; + s32 phi_v0_2; + u16 sp3A = this->unk_19E[0].y; + + if (this->unk_19D == 0) { + this->unk_1DC = 0; + this->unk_1E0 = 90.0f; + this->unk_1E4 = 0.1f; + this->unk_1E8 = 2.0f; + this->unk_1EC = 0.0f; + + this->unk_19D = 1; + this->unk_21C = 2; + this->unk_21E = 40; + this->unk_216 = 200; + } + + if (this->unk_19D == 1) { + Math_SmoothStepToF(&this->unk_1E4, this->unk_1E8, 1.0f, 0.1f, 0.001f); + sp48 = Math_SmoothStepToF(&this->unk_1DC, this->unk_1E0, 1.0f, this->unk_1E4, 0.001f); + this->unk_19E[0].y += (s32)(this->unk_1DC * (0x10000 / 360.0f)); + if (sp48 == 0.0f) { + this->unk_1D4 = 0; + this->unk_19D = 2; + } + } + + if (this->unk_19D == 2) { + this->unk_19E[0].y += (s32)(this->unk_1DC * (0x10000 / 360.0f)); + if ((this->unk_1D4++ <= 40) ^ 1) { + this->unk_1DC = this->unk_1B0[0].y - 1.0f; + this->unk_1E0 = 1.5f; + this->unk_1E4 = this->unk_1B0[1].y - 1.0f; + this->unk_1E8 = -0.3f; + Audio_PlayActorSound2(&this->actor, NA_SE_EV_STONE_GROW_UP); + this->unk_19D = 3; + } + } + + if (this->unk_19D == 3) { + this->unk_19E[0].y += 0x4000; + sp48 = Math_SmoothStepToF(&this->unk_1DC, this->unk_1E0, 0.8f, 0.2f, 0.001f); + Math_SmoothStepToF(&this->unk_1E4, this->unk_1E8, 0.8f, 0.2f, 0.001f); + this->unk_1B0[0].x = this->unk_1E4 + 1.0f; + this->unk_1B0[0].y = this->unk_1DC + 1.0f; + if (sp48 == 0.0f) { + this->unk_1DC = 2.0f * M_PI / 9.0000002; + this->unk_1E0 = M_PI / 9.0000002; + this->unk_19D = 4; + } + } + + if (this->unk_19D == 4) { + sp48 = Math_SmoothStepToF(&this->unk_1DC, this->unk_1E0, 0.8f, 16384.0f, 3640.0f); + this->unk_19E[0].y += (s16)this->unk_1DC; + if (sp48 == 0.0f) { + phi_v0_2 = this->unk_19E[0].y; + if (phi_v0_2 > 0) { + phi_v0_2 += 0xFFFF0000; + } + this->unk_1DC = phi_v0_2; + this->unk_1E0 = 0; + this->unk_19D = 5; + } + } + + if (this->unk_19D == 5) { + phi_v0_2 = this->unk_19E[0].y; + if (phi_v0_2 > 0) { + phi_v0_2 += 0xFFFF0001; + } + this->unk_1DC = phi_v0_2; + + sp48 = Math_SmoothStepToF(&this->unk_1DC, this->unk_1E0, 0.8f, 3640.0f, 0.001f); + this->unk_19E[0].y = (s32)this->unk_1DC; + if (sp48 == 0.0f) { + this->unk_19E[0].y = 0; + this->unk_1D4 = 0; + this->unk_1DC = this->unk_1B0[0].y - 1.0f; + this->unk_1E0 = 0.0f; + this->unk_1E4 = this->unk_1B0[0].x - 1.0f; + this->unk_1E8 = 0.0f; + this->unk_1F0 = 0.0f; + this->unk_1EC = 0.5f; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_ATTACK); + this->unk_21C = 20; + this->unk_21E = 2; + this->unk_19D = 6; + } + } + + if (this->unk_19D == 6) { + sp48 = Math_SmoothStepToF(&this->unk_1DC, this->unk_1E0, 0.8f, 0.1f, 0.001f); + sp44 = Math_SmoothStepToF(&this->unk_1E4, this->unk_1E8, 0.8f, 0.1f, 0.001f); + sp40 = Math_SmoothStepToF(&this->unk_1EC, this->unk_1F0, 0.8f, 0.02f, 0.001f); + this->unk_1B0[0].x = this->unk_1E4 + 1.0f; + this->unk_1B0[0].y = this->unk_1DC + 1.0f; + this->unk_1B0[0].x += __sinf(DEGF_TO_RADF((this->unk_1D4 % 10) * 0.1f * 360.0f)) * this->unk_1EC; + this->unk_1B0[0].y += __sinf(DEGF_TO_RADF((this->unk_1D4 % 10) * 0.1f * 360.0f)) * this->unk_1EC; + this->unk_1D4++; + if ((sp48 == 0.0f) && (sp44 == 0.0f) && (sp40 == 0.0f)) { + this->unk_216 = 0; + sp4C = 0; + } + } + + if ((u16)this->unk_19E[0].y < sp3A) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_STONE_ROLLING); + } + + return sp4C; +} + +void func_80999584(Color_RGB8* arg0, Color_RGB8* arg1) { + arg0->r = arg1->r; + arg0->g = arg1->g; + arg0->b = arg1->b; +} + +s32 func_809995A4(EnGs* this, GlobalContext* globalCtx) { + static Color_RGB8 flashColours[] = { + { 255, 50, 50 }, + { 50, 50, 255 }, + { 255, 255, 255 }, + }; + static Vec3f dustAccel = { 0.0f, -0.3f, 0.0f }; + static Color_RGBA8 dustPrim = { 200, 200, 200, 128 }; + static Color_RGBA8 dustEnv = { 100, 100, 100, 0 }; + static Vec3f bomb2Velocity = { 0.0f, 0.0f, 0.0f }; + static Vec3f bomb2Accel = { 0.0f, 0.0f, 0.0f }; + s32 sp7C = -1; + + if (this->unk_19D == 0) { + this->unk_19A |= 0x100; + this->unk_1D4 = 40; + this->unk_19D++; + } + + if (this->unk_19D == 1) { + if (this->unk_1D4-- == 0) { + this->unk_1D4 = 80; + this->unk_19A |= 4; + this->unk_19D++; + } + } + + if (this->unk_19D == 2) { + u8 pad; + + this->unk_1D4--; + func_80999584(&this->unk_1FA, &flashColours[2]); + if (this->unk_1D4 < 80) { + if ((this->unk_1D4 % 20) < 8) { + if (this->unk_1D4 < 20) { + if ((this->unk_1D4 % 20) == 7) { + func_80999584(&this->unk_1FA, &flashColours[0]); + this->unk_1F4 = this->unk_1FA; + play_sound(NA_SE_SY_WARNING_COUNT_E); + this->unk_200 = 0.0f; + } + } else if ((this->unk_1D4 % 20) == 7) { + func_80999584(&this->unk_1FA, &flashColours[1]); + this->unk_1F4 = this->unk_1FA; + play_sound(NA_SE_SY_WARNING_COUNT_N); + this->unk_200 = 0.0f; + } + } + } + + if (this->unk_1D4 <= 0) { + this->unk_19A &= ~4; + this->unk_21C = 3; + this->unk_21E = 40; + this->unk_1D4 = 0; + this->unk_19D++; + } + } + + if (this->unk_19D == 3) { + u8 i; + Vec3f sp6C; + Vec3f sp60; + + for (i = 0; i < 3; i++) { + sp60.x = randPlusMinusPoint5Scaled(15.0f); + sp60.y = Rand_ZeroFloat(-1.0f); + sp60.z = randPlusMinusPoint5Scaled(15.0f); + + sp6C.x = this->actor.world.pos.x + (2.0f * sp60.x); + sp6C.y = this->actor.world.pos.y + 7.0f; + sp6C.z = this->actor.world.pos.z + (2.0f * sp60.z); + + func_800B0EB0(globalCtx, &sp6C, &sp60, &dustAccel, &dustPrim, &dustEnv, Rand_ZeroFloat(50.0f) + 200.0f, 40, + 15); + } + + func_800B9010(&this->actor, NA_SE_EV_FIRE_PILLAR - SFX_FLAG); + + if ((this->unk_1D4++ < 40) ^ 1) { + this->unk_19A |= 0x10; + + this->actor.uncullZoneForward = 12000.0f; + this->actor.gravity = 0.3f; + this->unk_1DC = 0.0f; + + this->unk_19D++; + this->unk_21C = 5; + this->unk_21E = 20; + this->unk_19A |= 1; + this->unk_216 = 200; + this->unk_1E0 = (this->unk_197 >> 2) * 0x444; + } + } + + if (this->unk_19D == 4) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 20.0f, 60.0f, 3); + if (this->actor.bgCheckFlags & (0x10 | 0x8)) { + Vec3f sp54; + + sp54.x = this->actor.world.pos.x; + sp54.y = this->actor.world.pos.y; + sp54.z = this->actor.world.pos.z; + Audio_PlayActorSound2(&this->actor, NA_SE_IT_BOMB_EXPLOSION); + EffectSsBomb2_SpawnLayered(globalCtx, &sp54, &bomb2Velocity, &bomb2Accel, 100, 20); + this->unk_1D4 = 10; + this->unk_19A |= 8; + this->unk_216 = 0; + this->actionFunc = func_80999A8C; + } else { + func_800B9010(&this->actor, NA_SE_EV_STONE_LAUNCH - SFX_FLAG); + } + + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Math_SmoothStepToF(&this->unk_1DC, this->unk_1E0, 0.5f, 364.0f, 0.0f); + + this->unk_19E[1].y += (s16)this->unk_1DC; + + if ((this->actor.world.pos.y - this->actor.home.pos.y) >= 4000.0f) { + this->unk_216 = 0; + } + + if (this->actor.playerHeightRel < -12000.0f) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_BOM, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 0, this->actor.world.rot.y, 0, 0); + Actor_MarkForDeath(&this->actor); + sp7C = 0; + } + } + + return sp7C; +} + +void func_80999A8C(EnGs* this, GlobalContext* globalCtx) { + if (this->unk_1D4-- <= 0) { + Actor_MarkForDeath(&this->actor); + } +} + +void func_80999AC0(EnGs* this) { + static Vec3s D_8099A450 = { 0, 0, 0 }; + static Vec3f D_8099A458 = { 1.0f, 1.0f, 1.0f }; + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->unk_19E); i++) { + this->unk_19E[i] = D_8099A450; + } + + for (i = 0; i < ARRAY_COUNT(this->unk_1B0); i++) { + this->unk_1B0[i] = D_8099A458; + } +} + +void func_80999B34(EnGs* this) { + if (this->unk_216 > 0) { + if (this->unk_218 == 0) { + func_8016566C(this->unk_216); + this->unk_218 = this->unk_216; + } else { + func_80165658(this->unk_218); + } + } else if (this->unk_218 > 0) { + Math_StepToS(&this->unk_218, this->unk_216, 20); + func_80165658(this->unk_218); + if (this->unk_218 <= 0) { + func_80165690(); + } + } +} + +void func_80999BC8(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnGs* this = THIS; + s32 pad; + + if (this->actor.isTargeted && !func_801A5100()) { + this->unk_19D = 0; + this->unk_19A |= 1; + func_80999AC0(this); + this->unk_19C = 0; + func_80998704(this, globalCtx); + this->unk_208 = 0; + } + + if (this->actor.params == ENGS_1) { + Actor_SetHeight(&this->actor, 34.5f); + } else { + Actor_SetHeight(&this->actor, 23.0f); + } + + if (this->unk_21A > 0) { + this->unk_21A--; + if (this->unk_21A <= 0) { + this->unk_21A = 0; + } + } + + if (!(this->unk_19A & (0x200 | 0x10)) && (this->unk_21A == 0)) { + if (this->collider.base.acFlags & AC_HIT) { + this->unk_19D = 0; + this->collider.base.acFlags &= ~AC_HIT; + + switch (this->actor.colChkInfo.damageEffect) { + case 15: + this->unk_19A |= 1; + func_80999AC0(this); + this->unk_19C = 0; + func_80998704(this, globalCtx); + this->unk_21A = 5; + break; + + case 14: + this->unk_19A |= 1; + func_80999AC0(this); + this->unk_19C = 1; + func_80998704(this, globalCtx); + this->unk_21A = 5; + break; + + case 13: + func_80999AC0(this); + this->unk_19C = 2; + func_80998704(this, globalCtx); + this->unk_21A = 5; + break; + + case 12: + this->unk_19A |= 2; + func_80999AC0(this); + this->unk_19C = 4; + func_80998704(this, globalCtx); + this->unk_21A = 5; + break; + + case 11: + this->unk_19A |= 1; + func_80999AC0(this); + this->unk_19C = 3; + func_80998704(this, globalCtx); + this->unk_21A = 5; + break; + } + } + + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } else { + this->collider.base.acFlags &= ~AC_HIT; + } + + this->actionFunc(this, globalCtx); +} + +void EnGs_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnGs* this = THIS; + + if (func_800B84D0(&this->actor, globalCtx)) { + globalCtx->msgCtx.unk11F22 = 0; + globalCtx->msgCtx.unk11F10 = 0; + this->collider.base.acFlags &= ~AC_HIT; + func_80997DEC(this, globalCtx); + } else if (func_800B8718(&this->actor, globalCtx)) { + this->unk_19A |= 0x200; + this->collider.base.acFlags &= ~AC_HIT; + if (this->actor.cutscene != -1) { + this->actionFunc = func_80997FF0; + } else { + func_80998040(this, globalCtx); + } + } else { + s16 sp2E; + s16 sp2C; + + if ((this->actor.flags & 0x40) || (this->unk_19A & 0x100) || (this->unk_19A & 0x200)) { + func_80999BC8(&this->actor, globalCtx); + func_800B8898(globalCtx, &this->actor, &sp2E, &sp2C); + if ((this->actor.xyzDistToPlayerSq > SQ(400.0f)) || (sp2E < 0) || (sp2E > 320) || (sp2C < 0) || + (sp2C > 240)) { + this->unk_216 = 0; + } else if (this->unk_21C > 0) { + func_800BC848(&this->actor, globalCtx, this->unk_21C, this->unk_21E); + } + } else { + this->unk_216 = 0; + } + + if (this->unk_200 < 1.0f) { + if (this->unk_19A & 4) { + Math_StepToF(&this->unk_200, 1.0f, 0.06f); + } else { + Math_StepToF(&this->unk_200, 1.0f, 0.02f); + } + func_80997AFC(this->unk_194, &this->unk_1F7); + Lib_LerpRGB(&this->unk_1F4, &this->unk_1F7, this->unk_200, &this->unk_1FA); + if (this->unk_200 >= 1.0f) { + this->unk_1F4 = this->unk_1FA; + } + } + + if (this->unk_21C > 0) { + this->unk_21C = 0; + } + + func_80999B34(this); + } +} + +void EnGs_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnGs* this = THIS; + u32 frames; + + if (this->unk_19A & 8) { + return; + } + + OPEN_DISPS(globalCtx->state.gfxCtx); + + frames = globalCtx->gameplayFrames; + + func_8012C28C(globalCtx->state.gfxCtx); + Matrix_StatePush(); + + if (this->unk_19A & 1) { + Matrix_RotateY(this->unk_19E[0].y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->unk_19E[0].x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->unk_19E[0].z, MTXMODE_APPLY); + Matrix_Scale(this->unk_1B0[0].x, this->unk_1B0[0].y, this->unk_1B0[0].z, MTXMODE_APPLY); + Matrix_RotateY(this->unk_19E[1].y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->unk_19E[1].x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->unk_19E[1].z, MTXMODE_APPLY); + } + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, D_06000950); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, this->unk_1FA.r, this->unk_1FA.g, this->unk_1FA.b, 255); + gSPDisplayList(POLY_OPA_DISP++, D_060009D0); + gSPDisplayList(POLY_OPA_DISP++, D_06000A60); + + Matrix_StatePop(); + + if (this->unk_19A & 2) { + func_8012C2DC(globalCtx->state.gfxCtx); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + Matrix_Scale(0.05f, -0.05f, 1.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, -frames * 20, 0x20, 0x80)); + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, 255, 255, 0, 255); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 0, 0, 0); + gSPDisplayList(POLY_XLU_DISP++, gGameplayKeepDrawFlameDL); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Gs/z_en_gs.h b/src/overlays/actors/ovl_En_Gs/z_en_gs.h index 7b01d2c0a..8b10cb68d 100644 --- a/src/overlays/actors/ovl_En_Gs/z_en_gs.h +++ b/src/overlays/actors/ovl_En_Gs/z_en_gs.h @@ -5,9 +5,57 @@ struct EnGs; +typedef void (*EnGsActionFunc)(struct EnGs*, GlobalContext*); + +#define ENGS_GET_1F(thisx) ((thisx)->params & 0x1F) +#define ENGS_GET_FE0(thisx) (((thisx)->params >> 5) & 0x7F) +#define ENGS_GET_F000(thisx) (((thisx)->params >> 0xC) & 0xF) + +enum { + /* 0 */ ENGS_0, + /* 1 */ ENGS_1, + /* 2 */ ENGS_2, + /* 3 */ ENGS_3, +}; + typedef struct EnGs { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0xDC]; + /* 0x144 */ ColliderCylinder collider; + /* 0x190 */ EnGsActionFunc actionFunc; + /* 0x194 */ s8 unk_194; + /* 0x195 */ u8 unk_195; + /* 0x196 */ u8 unk_196; + /* 0x197 */ s8 unk_197; + /* 0x198 */ s16 unk_198; + /* 0x19A */ s16 unk_19A; + /* 0x19C */ s8 unk_19C; + /* 0x19D */ u8 unk_19D; + /* 0x19E */ Vec3s unk_19E[3]; + /* 0x1B0 */ Vec3f unk_1B0[2]; + /* 0x1C8 */ UNK_TYPE1 unk1C8[0xC]; + /* 0x1D4 */ s16 unk_1D4; + /* 0x1D6 */ UNK_TYPE1 unk1D6[0x6]; + /* 0x1DC */ f32 unk_1DC; + /* 0x1E0 */ f32 unk_1E0; + /* 0x1E4 */ f32 unk_1E4; + /* 0x1E8 */ f32 unk_1E8; + /* 0x1EC */ f32 unk_1EC; + /* 0x1F0 */ f32 unk_1F0; + /* 0x1F4 */ Color_RGB8 unk_1F4; + /* 0x1F7 */ Color_RGB8 unk_1F7; + /* 0x1FA */ Color_RGB8 unk_1FA; + /* 0x200 */ f32 unk_200; + /* 0x204 */ s32 unk_204; + /* 0x208 */ s32 unk_208; + /* 0x20C */ s32 unk_20C; + /* 0x210 */ u16 unk_210; + /* 0x212 */ s16 unk_212; + /* 0x214 */ UNK_TYPE1 unk214[2]; + /* 0x216 */ s16 unk_216; + /* 0x218 */ s16 unk_218; + /* 0x21A */ s16 unk_21A; + /* 0x21C */ s16 unk_21C; + /* 0x21E */ s16 unk_21E; } EnGs; // size = 0x220 extern const ActorInit En_Gs_InitVars; diff --git a/src/overlays/actors/ovl_En_Hakurock/z_en_hakurock.c b/src/overlays/actors/ovl_En_Hakurock/z_en_hakurock.c index 167180dab..0a0dccef7 100644 --- a/src/overlays/actors/ovl_En_Hakurock/z_en_hakurock.c +++ b/src/overlays/actors/ovl_En_Hakurock/z_en_hakurock.c @@ -351,7 +351,7 @@ void func_80B228F4(Actor* thisx, GlobalContext* globalCtx) { void EnHakurock_Draw(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C28C(globalCtx->state.gfxCtx); - Matrix_InsertTranslation(-100.0f, 0.0f, 0.0f, 1); + Matrix_InsertTranslation(-100.0f, 0.0f, 0.0f, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, D_06011100); gSPDisplayList(POLY_OPA_DISP++, D_06011178); diff --git a/src/overlays/actors/ovl_En_Heishi/z_en_heishi.c b/src/overlays/actors/ovl_En_Heishi/z_en_heishi.c index f25e8f790..229c1b65d 100644 --- a/src/overlays/actors/ovl_En_Heishi/z_en_heishi.c +++ b/src/overlays/actors/ovl_En_Heishi/z_en_heishi.c @@ -1,7 +1,7 @@ /* * File: z_en_heishi.c * Overlay: ovl_En_Heishi - * Description: Soldier + * Description: Soldier (Mayor's Residence only) */ #include "z_en_heishi.h" diff --git a/src/overlays/actors/ovl_En_Hgo/z_en_hgo.c b/src/overlays/actors/ovl_En_Hgo/z_en_hgo.c index a54b01861..179338401 100644 --- a/src/overlays/actors/ovl_En_Hgo/z_en_hgo.c +++ b/src/overlays/actors/ovl_En_Hgo/z_en_hgo.c @@ -1,7 +1,7 @@ /* * File: z_en_hgo.c * Overlay: ovl_En_Hgo - * Description: Pamela's Father As a Gibdo + * Description: Pamela's Father (Gibdo) */ #include "z_en_hgo.h" diff --git a/src/overlays/actors/ovl_En_Hit_Tag/z_en_hit_tag.c b/src/overlays/actors/ovl_En_Hit_Tag/z_en_hit_tag.c index 0e61a4937..3c7eac5ae 100644 --- a/src/overlays/actors/ovl_En_Hit_Tag/z_en_hit_tag.c +++ b/src/overlays/actors/ovl_En_Hit_Tag/z_en_hit_tag.c @@ -14,9 +14,8 @@ void EnHitTag_Init(Actor* thisx, GlobalContext* globalCtx); void EnHitTag_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnHitTag_Update(Actor* thisx, GlobalContext* globalCtx); -void func_80BE20E8(EnHitTag* this, GlobalContext* globalCtx); +void EnHitTag_WaitForHit(EnHitTag* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Hit_Tag_InitVars = { ACTOR_EN_HIT_TAG, ACTORCAT_ITEMACTION, @@ -29,21 +28,65 @@ const ActorInit En_Hit_Tag_InitVars = { (ActorFunc)NULL, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BE21F0 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 16, 32, 0, { 0, 0, 0 } }, }; -#endif +void EnHitTag_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnHitTag* this = THIS; -extern ColliderCylinderInit D_80BE21F0; + Actor_SetScale(&this->actor, 1.0f); + this->actionFunc = EnHitTag_WaitForHit; + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + Collider_UpdateCylinder(&this->actor, &this->collider); + if (Flags_GetSwitch(globalCtx, ENHITTAG_GET_SWITCHFLAG(thisx))) { + Actor_MarkForDeath(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hit_Tag/EnHitTag_Init.s") +void EnHitTag_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnHitTag* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hit_Tag/EnHitTag_Destroy.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hit_Tag/func_80BE20E8.s") +void EnHitTag_WaitForHit(EnHitTag* this, GlobalContext* globalCtx) { + Vec3f dropLocation; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Hit_Tag/EnHitTag_Update.s") + if (this->collider.base.acFlags & AC_HIT) { + play_sound(NA_SE_SY_GET_RUPY); + Actor_MarkForDeath(&this->actor); + dropLocation.x = this->actor.world.pos.x; + dropLocation.y = this->actor.world.pos.y; + dropLocation.z = this->actor.world.pos.z; + + for (i = 0; i < 3; i++) { + Item_DropCollectible(globalCtx, &dropLocation, ITEM00_RUPEE_GREEN); + } + } else { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} + +void EnHitTag_Update(Actor* thisx, GlobalContext* globalCtx) { + EnHitTag* this = THIS; + this->actionFunc(this, globalCtx); +} diff --git a/src/overlays/actors/ovl_En_Hit_Tag/z_en_hit_tag.h b/src/overlays/actors/ovl_En_Hit_Tag/z_en_hit_tag.h index 9af7edf1f..2117cb27d 100644 --- a/src/overlays/actors/ovl_En_Hit_Tag/z_en_hit_tag.h +++ b/src/overlays/actors/ovl_En_Hit_Tag/z_en_hit_tag.h @@ -7,9 +7,11 @@ struct EnHitTag; typedef void (*EnHitTagActionFunc)(struct EnHitTag*, GlobalContext*); +#define ENHITTAG_GET_SWITCHFLAG(thisx) (s32)(((thisx)->params & 0xFE00) >> 9) + typedef struct EnHitTag { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x4C]; + /* 0x0144 */ ColliderCylinder collider; /* 0x0190 */ EnHitTagActionFunc actionFunc; } EnHitTag; // size = 0x194 diff --git a/src/overlays/actors/ovl_En_Honotrap/z_en_honotrap.h b/src/overlays/actors/ovl_En_Honotrap/z_en_honotrap.h index 6207c5fc3..f9983e26a 100644 --- a/src/overlays/actors/ovl_En_Honotrap/z_en_honotrap.h +++ b/src/overlays/actors/ovl_En_Honotrap/z_en_honotrap.h @@ -10,7 +10,7 @@ typedef void (*EnHonotrapActionFunc)(struct EnHonotrap*, GlobalContext*); typedef struct EnHonotrap { /* 0x0000 */ Actor actor; /* 0x0144 */ EnHonotrapActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x17C]; + /* 0x0148 */ char unk_148[0x17C]; } EnHonotrap; // size = 0x2C4 extern const ActorInit En_Honotrap_InitVars; diff --git a/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c b/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c index 8eca23a7c..423acc7bf 100644 --- a/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c +++ b/src/overlays/actors/ovl_En_Horse_Game_Check/z_en_horse_game_check.c @@ -1,7 +1,7 @@ /* * File: z_en_horse_game_check.c * Overlay: ovl_En_Horse_Game_Check - * Description: + * Description: Dirt patches you can jump over on Gorman Race Track */ #include "z_en_horse_game_check.h" diff --git a/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c b/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c index 3bc939d74..7efec2c4d 100644 --- a/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c +++ b/src/overlays/actors/ovl_En_Hs2/z_en_hs2.c @@ -1,7 +1,7 @@ /* * File: z_en_hs2.c * Overlay: ovl_En_Hs2 - * Description: Blue Target Spot + * Description: Blue Target Spot (?) */ #include "z_en_hs2.h" diff --git a/src/overlays/actors/ovl_En_In/z_en_in.c b/src/overlays/actors/ovl_En_In/z_en_in.c index b69ba8bf1..0b9932e25 100644 --- a/src/overlays/actors/ovl_En_In/z_en_in.c +++ b/src/overlays/actors/ovl_En_In/z_en_in.c @@ -1,5 +1,5 @@ /* - * File z_en_in.c + * File: z_en_in.c * Overlay: ovl_En_In * Description: Gorman Bros */ @@ -214,11 +214,11 @@ s32 func_808F3178(EnIn* this, GlobalContext* globalCtx) { u8 tmp; this->unk260 = tmp = func_8013DB90(globalCtx, &this->unk248, -6.0f); - if (this->unk260 != 0 && prevUnk260 == 0 && tmp & 0xFF) { + if (this->unk260 != 0 && prevUnk260 == 0 && tmp) { Audio_PlayActorSound2(&this->actor, NA_SE_PL_WALK_CONCRETE); } this->unk261 = tmp = func_8013DB90(globalCtx, &this->unk254, -6.0f); - if (this->unk261 != 0 && prevUnk261 == 0 && tmp & 0xFF) { + if (this->unk261 != 0 && prevUnk261 == 0 && tmp) { Audio_PlayActorSound2(&this->actor, NA_SE_PL_WALK_CONCRETE); } return 0; @@ -369,7 +369,7 @@ void func_808F38F8(EnIn* this, GlobalContext* globalCtx) { this->unk4A4 = NULL; while (true) { //! @bug: Infinite loop if there is only one ACTOR_EN_IN - this->unk4A4 = (EnIn*)func_ActorCategoryIterateById(globalCtx, &this->unk4A4->actor, ACTORCAT_NPC, ACTOR_EN_IN); + this->unk4A4 = (EnIn*)SubS_FindActor(globalCtx, &this->unk4A4->actor, ACTORCAT_NPC, ACTOR_EN_IN); if (this->unk4A4 != NULL && this->unk4A4 != this) { break; } diff --git a/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c b/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c index 8a1feaf13..94a360df8 100644 --- a/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c +++ b/src/overlays/actors/ovl_En_Invadepoh/z_en_invadepoh.c @@ -1,5 +1,5 @@ /* - * File z_en_invadepoh.c + * File: z_en_invadepoh.c * Overlay: ovl_En_Invadepoh * Description: Ranch nighttime actors */ @@ -221,7 +221,6 @@ extern Gfx D_06000720[]; extern Gfx D_06000080[]; extern s32 D_801BDA9C; -extern Vec3s D_801D15BC; const ActorInit En_Invadepoh_InitVars = { ACTOR_EN_INVADEPOH, @@ -2568,7 +2567,7 @@ void func_80B48620(Actor* thisx, GlobalContext* globalCtx) { this->actor.update = func_80B4873C; SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06013928, &D_06009E58, this->jointTable, this->morphTable, 23); - func_80B45C04(&this->behaviorInfo, D_80B4EA90, 6, D_80B4EB00, 2, &D_801D15BC, 5000, 0.05f, 0.3f, 0.12f); + func_80B45C04(&this->behaviorInfo, D_80B4EA90, 6, D_80B4EB00, 2, &gZeroVec3s, 5000, 0.05f, 0.3f, 0.12f); Animation_PlayLoop(&this->skelAnime, &D_06009E58); func_80B482D4(this); } @@ -2636,7 +2635,7 @@ void func_80B48948(EnInvadepoh* this) { this->actionTimer = Rand_S16Offset(150, 150); if (rand < 0.5f) { this->rand = 0; - Math_Vec3s_Copy(&substruct->unk26, &D_801D15BC); + Math_Vec3s_Copy(&substruct->unk26, &gZeroVec3s); substruct->unk30 = 0.1f; substruct->unk2C = 1000; } else if (rand < 0.75f) { @@ -2702,7 +2701,7 @@ void func_80B48AD4(EnInvadepoh* this, GlobalContext* globalCtx) { if (temp_v1_3 != this->rand) { this->rand = temp_v1_3; if (this->rand == 0) { - Math_Vec3s_Copy(&substruct->unk26, &D_801D15BC); + Math_Vec3s_Copy(&substruct->unk26, &gZeroVec3s); substruct->unk30 = 0.07f; } else if (this->rand == 1) { substruct->unk26.x = Rand_S16Offset(1000, 1000); @@ -2772,7 +2771,7 @@ void func_80B48FB0(Actor* thisx, GlobalContext* globalCtx) { this->actor.textId = 0x3330; SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06013928, &D_06009E58, this->jointTable, this->morphTable, 23); - func_80B45C04(&this->behaviorInfo, D_80B4EA90, 6, D_80B4EB00, 2, &D_801D15BC, 100, 0.03, 0.3, 0.03); + func_80B45C04(&this->behaviorInfo, D_80B4EA90, 6, D_80B4EB00, 2, &gZeroVec3s, 100, 0.03, 0.3, 0.03); func_80B444F4(this, globalCtx); EnInvadepoh_SetPathPointToWorldPos(this, 0); func_800B4AEC(globalCtx, &this->actor, 50.0f); @@ -3124,7 +3123,7 @@ void func_80B49F88(Actor* thisx, GlobalContext* globalCtx) { func_80B44F58(); SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06013928, &D_06014088, this->jointTable, this->morphTable, 23); - func_80B45C04(&this->behaviorInfo, D_80B4EA90, 1, D_80B4EB00, 1, &D_801D15BC, 100, 0.03, 0.3, 0.03); + func_80B45C04(&this->behaviorInfo, D_80B4EA90, 1, D_80B4EB00, 1, &gZeroVec3s, 100, 0.03, 0.3, 0.03); func_80B44540(this, globalCtx); func_80B44570(this); func_80B44C24(this, globalCtx); @@ -3355,7 +3354,7 @@ void func_80B4A9C8(Actor* thisx, GlobalContext* globalCtx) { func_80B44F58(); SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06013928, &D_06014088, this->jointTable, this->morphTable, 23); - func_80B45C04(&this->behaviorInfo, D_80B4EA90, 1, D_80B4EB00, 1, &D_801D15BC, 100, 0.03f, 0.3f, 0.03f); + func_80B45C04(&this->behaviorInfo, D_80B4EA90, 1, D_80B4EB00, 1, &gZeroVec3s, 100, 0.03f, 0.3f, 0.03f); func_80B44620(this, globalCtx); if ((sp38 < CLOCK_TIME(2, 15)) || (sp38 >= CLOCK_TIME(6, 0))) { this->pathIndex = 0; @@ -3532,7 +3531,7 @@ void func_80B4B0C4(Actor* thisx, GlobalContext* globalCtx) { 23); Animation_MorphToLoop(&this->skelAnime, &D_06009E58, 0.0f); substruct = &this->behaviorInfo; - func_80B45C04(&this->behaviorInfo, D_80B4EA90, 1, D_80B4EB00, 3, &D_801D15BC, 2000, 0.08f, 0.3f, 0.03f); + func_80B45C04(&this->behaviorInfo, D_80B4EA90, 1, D_80B4EB00, 3, &gZeroVec3s, 2000, 0.08f, 0.3f, 0.03f); substruct->unk30 = 0.08f; substruct->unk2C = 0x7D0; func_800B4AEC(globalCtx, &this->actor, 50.0f); @@ -3685,7 +3684,7 @@ void func_80B4B8BC(Actor* thisx, GlobalContext* globalCtx) { Actor_SetObjectSegment(globalCtx, &this->actor); SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_060080F0, &D_060021C8, this->jointTable, this->morphTable, 13); - func_80B45C04(&this->behaviorInfo, 0, 0, 0, 0, &D_801D15BC, 3000, 0.1f, 0.0f, 0.0f); + func_80B45C04(&this->behaviorInfo, 0, 0, 0, 0, &gZeroVec3s, 3000, 0.1f, 0.0f, 0.0f); func_80B44664(this, globalCtx); EnInvadepoh_SetPathPointToWorldPos(this, 0); func_800B4AEC(globalCtx, &this->actor, 50.0f); @@ -3919,7 +3918,7 @@ void func_80B4C3A0(Actor* thisx, GlobalContext* globalCtx) { func_80B44FEC(); SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06015C28, &D_06016720, this->jointTable, this->morphTable, 22); - func_80B45C04(&this->behaviorInfo, D_80B4EBDC, 1, D_80B4EC08, 0, &D_801D15BC, 100, 0.03f, 0.3f, 0.03f); + func_80B45C04(&this->behaviorInfo, D_80B4EBDC, 1, D_80B4EC08, 0, &gZeroVec3s, 100, 0.03f, 0.3f, 0.03f); this->actor.textId = 0x33CD; if (currentTime < 0xD5A0) { this->unk304 = -0x8000; @@ -4140,7 +4139,7 @@ void func_80B4CE54(Actor* thisx, GlobalContext* globalCtx) { func_80B44F58(); SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06013928, &D_06014088, this->jointTable, this->morphTable, 23); - func_80B45C04(&this->behaviorInfo, D_80B4EA90, 1, D_80B4EB00, 3, &D_801D15BC, 100, 0.03f, 0.3f, 0.03f); + func_80B45C04(&this->behaviorInfo, D_80B4EA90, 1, D_80B4EB00, 3, &gZeroVec3s, 100, 0.03f, 0.3f, 0.03f); func_80B446D0(this, globalCtx); this->actor.world.rot.y = this->actor.shape.rot.y; func_80B44700(this); @@ -4480,7 +4479,7 @@ void func_80B4DB14(Actor* thisx, GlobalContext* globalCtx) { gSPSetOtherMode(gfx++, G_SETOTHERMODE_H, 4, 4, 0x00000080); gDPSetCombineLERP(gfx++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0); - Matrix_InsertMatrix(&globalCtx->mf_187FC, MTXMODE_NEW); + Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_NEW); Matrix_GetStateTranslationAndScaledZ(60.0f, &sp80); sp74.x = thisx->world.pos.x + sp80.x; sp74.y = thisx->world.pos.y + sp80.y + 68.0f; @@ -4572,14 +4571,14 @@ void func_80B4E3F0(Actor* thisx, GlobalContext* globalCtx) { Vec3f sp5C; Matrix_StatePush(); - Matrix_InsertMatrix(&globalCtx->mf_187FC, MTXMODE_NEW); + Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_NEW); Matrix_GetStateTranslationAndScaledZ(200.0f, &sp5C); Matrix_StatePop(); sp5C.x += thisx->world.pos.x; sp5C.y += thisx->world.pos.y; sp5C.z += thisx->world.pos.z; EnInvadepoh_SetSysMatrix(&sp5C); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_InsertZRotation_s(((EnInvadepoh*)thisx)->unk304, MTXMODE_APPLY); OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C2DC(globalCtx->state.gfxCtx); diff --git a/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.h b/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.h index d56546974..df29dbc60 100644 --- a/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.h +++ b/src/overlays/actors/ovl_En_Invadepoh_Demo/z_en_invadepoh_demo.h @@ -10,7 +10,7 @@ typedef void (*EnInvadepohDemoActionFunc)(struct EnInvadepohDemo*, GlobalContext typedef struct EnInvadepohDemo { /* 0x0000 */ Actor actor; /* 0x0144 */ EnInvadepohDemoActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x180]; + /* 0x0148 */ char unk_148[0x180]; } EnInvadepohDemo; // size = 0x2C8 extern const ActorInit En_Invadepoh_Demo_InitVars; diff --git a/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.c b/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.c index 24aa7d33b..f459fbf53 100644 --- a/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.c +++ b/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.c @@ -14,10 +14,10 @@ void EnInvisibleRuppe_Init(Actor* thisx, GlobalContext* globalCtx); void EnInvisibleRuppe_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnInvisibleRuppe_Update(Actor* thisx, GlobalContext* globalCtx); +void func_80C258A0(EnInvisibleRuppe* this, GlobalContext* globalCtx); void func_80C2590C(EnInvisibleRuppe* this, GlobalContext* globalCtx); void func_80C259E8(EnInvisibleRuppe* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Invisible_Ruppe_InitVars = { ACTOR_EN_INVISIBLE_RUPPE, ACTORCAT_NPC, @@ -30,25 +30,95 @@ const ActorInit En_Invisible_Ruppe_InitVars = { (ActorFunc)NULL, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80C25B50 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_NO_PUSH | OC1_TYPE_PLAYER, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK4, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_NO_PUSH | OC1_TYPE_PLAYER, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + + { + ELEMTYPE_UNK4, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, + { 10, 30, 0, { 0, 0, 0 } }, }; -#endif +void func_80C258A0(EnInvisibleRuppe* this, GlobalContext* globalCtx) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 32.0f, 30.0f, 0.0f, 4); +} -extern ColliderCylinderInit D_80C25B50; +void func_80C2590C(EnInvisibleRuppe* this, GlobalContext* globalCtx) { + if (this->collider.base.ocFlags1 & OC1_HIT) { + switch (INVISIBLERUPPE_GET_3(this)) { + case 0: + play_sound(NA_SE_SY_GET_RUPY); + Item_DropCollectible(globalCtx, &this->actor.world.pos, 0x8000 | ITEM00_RUPEE_GREEN); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invisible_Ruppe/func_80C258A0.s") + case 1: + play_sound(NA_SE_SY_GET_RUPY); + Item_DropCollectible(globalCtx, &this->actor.world.pos, 0x8000 | ITEM00_RUPEE_BLUE); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invisible_Ruppe/func_80C2590C.s") + case 2: + play_sound(NA_SE_SY_GET_RUPY); + Item_DropCollectible(globalCtx, &this->actor.world.pos, 0x8000 | ITEM00_RUPEE_RED); + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invisible_Ruppe/func_80C259E8.s") + if (this->unk_190 >= 0) { + Actor_SetSwitchFlag(globalCtx, this->unk_190); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invisible_Ruppe/EnInvisibleRuppe_Init.s") + this->actionFunc = func_80C259E8; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invisible_Ruppe/EnInvisibleRuppe_Destroy.s") +void func_80C259E8(EnInvisibleRuppe* this, GlobalContext* globalCtx) { + Actor_MarkForDeath(&this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Invisible_Ruppe/EnInvisibleRuppe_Update.s") +void EnInvisibleRuppe_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnInvisibleRuppe* this = THIS; + + this->unk_190 = INVISIBLERUPPE_GET_1FC(this); + + if (this->unk_190 == 0x7F) { + this->unk_190 = -1; + } + + if ((this->unk_190 >= 0) && Flags_GetSwitch(globalCtx, this->unk_190)) { + Actor_MarkForDeath(&this->actor); + return; + } + + Collider_InitCylinder(globalCtx, &this->collider); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + + this->actionFunc = func_80C2590C; +} + +void EnInvisibleRuppe_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnInvisibleRuppe* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void EnInvisibleRuppe_Update(Actor* thisx, GlobalContext* globalCtx) { + EnInvisibleRuppe* this = THIS; + + this->actionFunc(this, globalCtx); + func_80C258A0(this, globalCtx); +} diff --git a/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.h b/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.h index 66b42d520..eef1acbfe 100644 --- a/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.h +++ b/src/overlays/actors/ovl_En_Invisible_Ruppe/z_en_invisible_ruppe.h @@ -7,9 +7,14 @@ struct EnInvisibleRuppe; typedef void (*EnInvisibleRuppeActionFunc)(struct EnInvisibleRuppe*, GlobalContext*); +#define INVISIBLERUPPE_GET_3(thisx) ((thisx)->actor.params & 3) +#define INVISIBLERUPPE_GET_1FC(thisx) (((thisx)->actor.params & 0x1FC) >> 2) + typedef struct EnInvisibleRuppe { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x50]; + /* 0x0144 */ ColliderCylinder collider; + /* 0x0190 */ s16 unk_190; + /* 0x0192 */ s16 unk_192; /* 0x0194 */ EnInvisibleRuppeActionFunc actionFunc; } EnInvisibleRuppe; // size = 0x198 diff --git a/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c b/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c index 0843cb87b..e1ce0892f 100644 --- a/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c +++ b/src/overlays/actors/ovl_En_Ishi/z_en_ishi.c @@ -1,10 +1,13 @@ /* * File: z_en_ishi.c * Overlay: ovl_En_Ishi - * Description: Rock + * Description: Liftable rocks and silver boulders */ #include "z_en_ishi.h" +#include "objects/gameplay_field_keep/gameplay_field_keep.h" +#include "objects/gameplay_keep/gameplay_keep.h" +#include "objects/object_ishi/object_ishi.h" #define FLAGS 0x00800010 @@ -14,14 +17,31 @@ void EnIshi_Init(Actor* thisx, GlobalContext* globalCtx); void EnIshi_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnIshi_Update(Actor* thisx, GlobalContext* globalCtx); +void func_8095D804(Actor* thisx, GlobalContext* globalCtx); +void func_8095DABC(Actor* thisx, GlobalContext* globalCtx); +void func_8095DDA8(EnIshi* this, GlobalContext* globalCtx); +void func_8095DE9C(EnIshi* this, GlobalContext* globalCtx); +void func_8095E5AC(EnIshi* this); void func_8095E5C0(EnIshi* this, GlobalContext* globalCtx); +void func_8095E64C(EnIshi* this); void func_8095E660(EnIshi* this, GlobalContext* globalCtx); +void func_8095E934(EnIshi* this); void func_8095E95C(EnIshi* this, GlobalContext* globalCtx); +void func_8095EA70(EnIshi* this); void func_8095EBDC(EnIshi* this, GlobalContext* globalCtx); +void func_8095F060(EnIshi* this); void func_8095F0A4(EnIshi* this, GlobalContext* globalCtx); +void func_8095F180(EnIshi* this); void func_8095F194(EnIshi* this, GlobalContext* globalCtx); +void func_8095F210(EnIshi* this, GlobalContext* globalCtx); +void func_8095F36C(EnIshi* this, GlobalContext* globalCtx); +void func_8095F61C(Actor* thisx, GlobalContext* globalCtx); +void func_8095F654(Actor* thisx, GlobalContext* globalCtx); + +static s16 D_8095F690 = 0; + +static s16 D_8095F694 = 0; -#if 0 const ActorInit En_Ishi_InitVars = { ACTOR_EN_ISHI, ACTORCAT_PROP, @@ -34,109 +54,702 @@ const ActorInit En_Ishi_InitVars = { (ActorFunc)NULL, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_8095F6EC = { - { COLTYPE_HARD, AT_ON | AT_TYPE_PLAYER, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00400000, 0x00, 0x02 }, { 0x01C37FBE, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, - { 10, 18, -2, { 0, 0, 0 } }, +static f32 D_8095F6B8[] = { 0.1f, 0.4f }; + +static f32 D_8095F6C0[] = { 58.0f, 80.0f }; + +static f32 D_8095F6C8[] = { 0.0f, 0.005f }; + +static u16 D_8095F6D0[] = { NA_SE_EV_ROCK_BROKEN, NA_SE_EV_WALL_BROKEN }; + +static u8 D_8095F6D4[] = { 25, 40 }; + +static EnIshiUnkFunc2 D_8095F6D8[] = { func_8095D804, func_8095DABC }; + +static EnIshiUnkFunc D_8095F6E0[] = { func_8095DDA8, func_8095DE9C }; + +static s16 D_8095F6E8[] = { GAMEPLAY_FIELD_KEEP, OBJECT_ISHI }; + +static ColliderCylinderInit sCylinderInit[] = { + { + { + COLTYPE_HARD, + AT_ON | AT_TYPE_PLAYER, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00400000, 0x00, 0x02 }, + { 0x01C37FBE, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, + { 10, 18, -2, { 0, 0, 0 } }, + }, + { + { + COLTYPE_HARD, + AT_ON | AT_TYPE_PLAYER, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00400000, 0x00, 0x02 }, + { 0x01C37BB6, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, + { 55, 70, 0, { 0, 0, 0 } }, + }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_8095F718 = { - { COLTYPE_HARD, AT_ON | AT_TYPE_PLAYER, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00400000, 0x00, 0x02 }, { 0x01C37BB6, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, - { 55, 70, 0, { 0, 0, 0 } }, +static CollisionCheckInfoInit sColChkInfoInit = { 0, 12, 60, MASS_IMMOVABLE }; + +static s16 D_8095F74C[] = { 16, 13, 11, 9, 7, 5 }; + +static s16 D_8095F758[] = { 145, 135, 120, 100, 70, 50, 45, 40, 35 }; + +static s16 D_8095F76C[] = { -1, 1, 2, 20, 8, 0 }; + +static Vec3f D_8095F778 = { 0.0f, 1.0f, 0.0f }; + +static InitChainEntry sInitChain[][5] = { + { + ICHAIN_F32_DIV1000(gravity, -1200, ICHAIN_CONTINUE), + ICHAIN_F32_DIV1000(minVelocityY, -20000, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneForward, 1200, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_STOP), + }, + { + ICHAIN_F32_DIV1000(gravity, -2500, ICHAIN_CONTINUE), + ICHAIN_F32_DIV1000(minVelocityY, -20000, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneScale, 250, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_STOP), + }, }; -// sColChkInfoInit -static CollisionCheckInfoInit D_8095F744 = { 0, 12, 60, MASS_IMMOVABLE }; +static u16 D_8095F7AC[] = { NA_SE_PL_PULL_UP_ROCK, NA_SE_PL_PULL_UP_BIGROCK }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_8095F784[] = { - ICHAIN_F32_DIV1000(gravity, -1200, ICHAIN_CONTINUE), - ICHAIN_F32_DIV1000(minVelocityY, -20000, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneForward, 1200, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_STOP), -}; +static EnIshiUnkFunc D_8095F7B0[] = { func_8095F210, func_8095F36C }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_8095F798[] = { - ICHAIN_F32_DIV1000(gravity, -2500, ICHAIN_CONTINUE), - ICHAIN_F32_DIV1000(minVelocityY, -20000, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneScale, 250, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneDownward, 400, ICHAIN_STOP), -}; +void func_8095D6E0(Actor* thisx, GlobalContext* globalCtx) { + EnIshi* this = THIS; -#endif + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit[ENISHI_GET_1(&this->actor)]); + Collider_UpdateCylinder(&this->actor, &this->collider); +} -extern ColliderCylinderInit D_8095F6EC; -extern ColliderCylinderInit D_8095F718; -extern CollisionCheckInfoInit D_8095F744; -extern InitChainEntry D_8095F784[]; -extern InitChainEntry D_8095F798[]; +s32 func_8095D758(EnIshi* this, GlobalContext* globalCtx, f32 arg2) { + Vec3f sp24; + s32 sp20; -extern UNK_TYPE D_060009B0; + sp24.x = this->actor.world.pos.x; + sp24.y = this->actor.world.pos.y + 30.0f; + sp24.z = this->actor.world.pos.z; + this->actor.floorHeight = + BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &sp20, &this->actor, &sp24); + if (this->actor.floorHeight > BGCHECK_Y_MIN) { + this->actor.world.pos.y = this->actor.floorHeight + arg2; + Math_Vec3f_Copy(&this->actor.home.pos, &this->actor.world.pos); + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095D6E0.s") +void func_8095D804(Actor* thisx, GlobalContext* globalCtx) { + EnIshi* this = THIS; + s32 i; + s16 temp; + Gfx* phi_s4; + Vec3f spC4; + Vec3f spB8; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095D758.s") + if (!ENISHI_GET_8(&this->actor)) { + phi_s4 = gameplay_field_keep_DL_0066B0; + } else { + phi_s4 = object_ishi_DL_0009B0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095D804.s") + temp = D_8095F6E8[ENISHI_GET_8(&this->actor)]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095DABC.s") + for (i = 0; i < ARRAY_COUNT(D_8095F74C); i++) { + spB8.x = ((Rand_ZeroOne() - 0.5f) * 8.0f) + this->actor.world.pos.x; + spB8.y = (Rand_ZeroOne() * 5.0f) + this->actor.world.pos.y + 5.0f; + spB8.z = ((Rand_ZeroOne() - 0.5f) * 8.0f) + this->actor.world.pos.z; + Math_Vec3f_Copy(&spC4, &this->actor.velocity); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095DDA8.s") + if (this->actor.bgCheckFlags & 1) { + spC4.x *= 0.6f; + spC4.y *= -0.3f; + spC4.z *= 0.6f; + } else if (this->actor.bgCheckFlags & 8) { + spC4.x *= -0.5f; + spC4.y *= 0.5f; + spC4.z *= -0.5f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095DE9C.s") + spC4.x += (Rand_ZeroOne() - 0.5f) * 11.0f; + spC4.y += (Rand_ZeroOne() * 7.0f) + 6.0f; + spC4.z += (Rand_ZeroOne() - 0.5f) * 11.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095DF90.s") + EffectSsKakera_Spawn(globalCtx, &spB8, &spC4, &spB8, -420, (Rand_Next() > 0) ? 65 : 33, 30, 5, 0, D_8095F74C[i], + 3, 10, 40, -1, temp, phi_s4); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095DFF0.s") +void func_8095DABC(Actor* thisx, GlobalContext* globalCtx) { + EnIshi* this = THIS; + Vec3f spD8; + Vec3f spCC; + f32 temp_f20; + s16 temp_s1 = 0x1000; + s32 i; + s16 phi_v0; + s16 phi_v1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095E14C.s") + for (i = 0; i < ARRAY_COUNT(D_8095F758); i++) { + temp_s1 += 0x4E20; + temp_f20 = Rand_ZeroOne() * 10.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095E180.s") + spCC.x = (Math_SinS(temp_s1) * temp_f20) + this->actor.world.pos.x; + spCC.y = (Rand_ZeroOne() * 40.0f) + this->actor.world.pos.y + 5.0f; + spCC.z = (Math_CosS(temp_s1) * temp_f20) + this->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095E204.s") + Math_Vec3f_Copy(&spD8, &this->actor.velocity); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095E2B0.s") + if (this->actor.bgCheckFlags & 1) { + spD8.x *= 0.9f; + spD8.y *= -0.8f; + spD8.z *= 0.9f; + } else if (this->actor.bgCheckFlags & 8) { + spD8.x *= -0.9f; + spD8.y *= 0.8f; + spD8.z *= -0.9f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/EnIshi_Init.s") + temp_f20 = Rand_ZeroOne() * 10.0f; + spD8.x += temp_f20 * Math_SinS(temp_s1); + spD8.y += (Rand_ZeroOne() * 4.0f) + (Rand_ZeroOne() * i * 0.7f); + spD8.z += temp_f20 * Math_CosS(temp_s1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/EnIshi_Destroy.s") + if (i == 0) { + phi_v0 = 41; + phi_v1 = -450; + } else if (i < 4) { + phi_v0 = 37; + phi_v1 = -380; + } else { + phi_v0 = 69; + phi_v1 = -320; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095E5AC.s") + EffectSsKakera_Spawn(globalCtx, &spCC, &spD8, &this->actor.world.pos, phi_v1, phi_v0, 30, 5, 0, D_8095F758[i], + 5, 2, 70, 0, 2, gameplay_field_keep_DL_006420); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095E5C0.s") +void func_8095DDA8(EnIshi* this, GlobalContext* globalCtx) { + Vec3f sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095E64C.s") + Math_Vec3f_Copy(&sp2C, &this->actor.world.pos); + if (this->actor.bgCheckFlags & 1) { + sp2C.x += 2.0f * this->actor.velocity.x; + sp2C.y -= 2.0f * this->actor.velocity.y; + sp2C.z += 2.0f * this->actor.velocity.z; + } else if (this->actor.bgCheckFlags & 8) { + sp2C.x -= 2.0f * this->actor.velocity.x; + sp2C.y += 2.0f * this->actor.velocity.y; + sp2C.z -= 2.0f * this->actor.velocity.z; + } + func_800BBFB0(globalCtx, &sp2C, 60.0f, 3, 80, 60, 1); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095E660.s") +void func_8095DE9C(EnIshi* this, GlobalContext* globalCtx) { + Vec3f sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095E934.s") + Math_Vec3f_Copy(&sp2C, &this->actor.world.pos); + if (this->actor.bgCheckFlags & 1) { + sp2C.x += 2.0f * this->actor.velocity.x; + sp2C.y -= 2.0f * this->actor.velocity.y; + sp2C.z += 2.0f * this->actor.velocity.z; + } else if (this->actor.bgCheckFlags & 8) { + sp2C.x -= 2.0f * this->actor.velocity.x; + sp2C.y += 2.0f * this->actor.velocity.y; + sp2C.z -= 2.0f * this->actor.velocity.z; + } + func_800BBFB0(globalCtx, &sp2C, 140.0f, 10, 180, 90, 1); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095E95C.s") +void func_8095DF90(EnIshi* this, GlobalContext* globalCtx) { + if (!ENISHI_GET_1(&this->actor) && !ENISHI_GET_100(&this->actor)) { + Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.world.pos, ENISHI_GET_F0(&this->actor) * 0x10); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095EA70.s") +void func_8095DFF0(EnIshi* this, GlobalContext* globalCtx) { + s32 pad; + s32 temp = D_8095F76C[ENISHI_GET_70(&this->actor)]; + Actor* sp3C; + Vec3f sp30; + f32 sp2C; + f32 temp_f2; + s16 temp_v1_2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095EBDC.s") + if (temp >= 0) { + sp3C = Item_DropCollectible(globalCtx, &this->actor.world.pos, temp | (ENISHI_GET_FE00(&this->actor) << 8)); + if (sp3C != NULL) { + Matrix_StatePush(); + Matrix_RotateY(this->actor.shape.rot.y, 0); + Matrix_InsertXRotation_s(this->actor.shape.rot.x, 1); + Matrix_InsertZRotation_s(this->actor.shape.rot.z, 1); + Matrix_GetStateTranslationAndScaledY(1.0f, &sp30); + sp2C = Math3D_Parallel(&sp30, &D_8095F778); + if (sp2C < 0.707f) { + temp_v1_2 = Math_FAtan2F(sp30.z, sp30.x) - sp3C->world.rot.y; + if (ABS_ALT(temp_v1_2) > 0x4000) { + sp3C->world.rot.y = BINANG_ROT180(sp3C->world.rot.y); + } + temp_f2 = sp2C + 0.5f; + if (temp_f2 < 0.5f) { + temp_f2 = 0.5f; + } + sp3C->velocity.y *= temp_f2; + } + Matrix_StatePop(); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095F060.s") +void func_8095E14C(EnIshi* this) { + this->actor.velocity.y += this->actor.gravity; + if (this->actor.velocity.y < this->actor.minVelocityY) { + this->actor.velocity.y = this->actor.minVelocityY; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095F0A4.s") +void func_8095E180(Vec3f* arg0, f32 arg1) { + arg1 += ((Rand_ZeroOne() * 0.2f) - 0.1f) * arg1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095F180.s") + arg0->x -= arg0->x * arg1; + arg0->y -= arg0->y * arg1; + arg0->z -= arg0->z * arg1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095F194.s") +void func_8095E204(EnIshi* this, GlobalContext* globalCtx) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/EnIshi_Update.s") + for (i = 0; i < 3; i++) { + if (Actor_SpawnAsChildAndCutscene(&globalCtx->actorCtx, globalCtx, ACTOR_EN_INSECT, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 1, + this->actor.cutscene, this->actor.unk20, NULL) == NULL) { + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095F210.s") +s32 func_8095E2B0(EnIshi* this, GlobalContext* globalCtx) { + s32 pad; + WaterBox* sp30; + f32 sp2C; + s32 sp28; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095F36C.s") + if (WaterBox_GetSurfaceImpl(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, &sp2C, + &sp30, &sp28) && + (this->actor.world.pos.y < sp2C)) { + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095F61C.s") +void EnIshi_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnIshi* this = THIS; + s32 sp34 = ENISHI_GET_1(&this->actor); + s32 sp30 = ENISHI_GET_4(&this->actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ishi/func_8095F654.s") + if ((sp34 == 0) && (sp30 != 0)) { + this->unk_197 |= 2; + } + + Actor_ProcessInitChain(&this->actor, sInitChain[sp34]); + + if (globalCtx->csCtx.state != 0) { + this->actor.uncullZoneForward += 1000.0f; + } + + if ((this->actor.shape.rot.y == 0) && !(this->unk_197 & 2)) { + this->actor.shape.rot.y = this->actor.world.rot.y = (u32)Rand_Next() >> 0x10; + } + + Actor_SetScale(&this->actor, D_8095F6B8[sp34]); + func_8095D6E0(&this->actor, globalCtx); + + if ((sp34 == 1) && Flags_GetSwitch(globalCtx, ENISHI_GET_FE00(&this->actor))) { + Actor_MarkForDeath(&this->actor); + return; + } + + CollisionCheck_SetInfo(&this->actor.colChkInfo, NULL, &sColChkInfoInit); + + if (sp34 == 1) { + this->actor.shape.shadowDraw = func_800B3FC0; + this->actor.shape.shadowScale = 2.3f; + } else { + this->actor.shape.shadowScale = 2.4f; + this->actor.shape.shadowAlpha = 160; + } + + this->actor.shape.yOffset = D_8095F6C0[sp34]; + + if ((sp30 == 0) && !func_8095D758(this, globalCtx, 0)) { + Actor_MarkForDeath(&this->actor); + return; + } + + if (func_8095E2B0(this, globalCtx)) { + this->unk_197 |= 1; + } + + this->unk_196 = Object_GetIndex(&globalCtx->objectCtx, D_8095F6E8[ENISHI_GET_8(&this->actor)]); + if (this->unk_196 < 0) { + Actor_MarkForDeath(&this->actor); + return; + } + + func_8095E5AC(this); +} + +void EnIshi_Destroy(Actor* thisx, GlobalContext* globalCtx) { + Collider_DestroyCylinder(globalCtx, &THIS->collider); +} + +void func_8095E5AC(EnIshi* this) { + this->actionFunc = func_8095E5C0; +} + +void func_8095E5C0(EnIshi* this, GlobalContext* globalCtx) { + if (Object_IsLoaded(&globalCtx->objectCtx, this->unk_196)) { + this->actor.objBankIndex = this->unk_196; + this->actor.flags &= ~0x10; + if (!ENISHI_GET_8(&this->actor)) { + this->actor.draw = func_8095F61C; + } else { + this->actor.draw = func_8095F654; + } + func_8095E64C(this); + } +} + +void func_8095E64C(EnIshi* this) { + this->actionFunc = func_8095E660; +} + +void func_8095E660(EnIshi* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp38 = ENISHI_GET_1(&this->actor); + s32 sp34 = (this->collider.base.acFlags & AC_HIT) != 0; + s32 sp30 = this->unk_197 & 2; + + if (sp34) { + this->collider.base.acFlags &= ~AC_HIT; + } + + if (Actor_HasParent(&this->actor, globalCtx)) { + func_8095E934(this); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, D_8095F7AC[sp38]); + if (ENISHI_GET_2(&this->actor)) { + func_8095E204(this, globalCtx); + } + this->actor.shape.shadowDraw = func_800B3FC0; + return; + } + + if (sp34 && (sp38 == 0) && (this->collider.info.acHitInfo->toucher.dmgFlags & 0x508)) { + if (sp30 != 0) { + func_8095DFF0(this, globalCtx); + func_8095F060(this); + return; + } + func_8095DF90(this, globalCtx); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, D_8095F6D4[sp38], D_8095F6D0[sp38]); + D_8095F6D8[sp38](&this->actor, globalCtx); + D_8095F6E0[sp38](this, globalCtx); + Actor_MarkForDeath(&this->actor); + return; + } + + if (sp34) { + this->unk_195 = 5; + } + + if ((this->actor.xzDistToPlayer < 600.0f) || (sp30 != 0)) { + if (this->unk_195 > 0) { + this->unk_195--; + if (this->unk_195 == 0) { + this->collider.base.colType = sCylinderInit[sp38].base.colType; + } else { + this->collider.base.colType = COLTYPE_NONE; + } + } + + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + + if ((this->actor.xzDistToPlayer < 90.0f) && (sp30 == 0)) { + if (sp38 == 1) { + func_800B8A1C(&this->actor, globalCtx, 0, 80.0f, 20.0f); + } else { + func_800B8A1C(&this->actor, globalCtx, 0, 50.0f, 10.0f); + } + } + } +} + +void func_8095E934(EnIshi* this) { + this->actionFunc = func_8095E95C; + this->actor.room = -1; + this->actor.flags |= 0x10; +} + +void func_8095E95C(EnIshi* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp30; + s32 sp2C; + + if (Actor_HasNoParent(&this->actor, globalCtx)) { + this->actor.room = globalCtx->roomCtx.currRoom.num; + if (ENISHI_GET_1(&this->actor) == 1) { + Actor_SetSwitchFlag(globalCtx, ENISHI_GET_FE00(&this->actor)); + } + func_8095EA70(this); + func_8095E14C(this); + func_8095E180(&this->actor.velocity, D_8095F6C8[ENISHI_GET_1(&this->actor)]); + Actor_ApplyMovement(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 7.5f, 35.0f, 0.0f, 0xC5); + } else { + sp30.x = this->actor.world.pos.x; + sp30.y = this->actor.world.pos.y + 20.0f; + sp30.z = this->actor.world.pos.z; + this->actor.floorHeight = + BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &sp2C, &this->actor, &sp30); + } +} + +void func_8095EA70(EnIshi* this) { + f32 sp24; + + this->actor.velocity.x = Math_SinS(this->actor.world.rot.y) * this->actor.speedXZ; + this->actor.velocity.z = Math_CosS(this->actor.world.rot.y) * this->actor.speedXZ; + if (!ENISHI_GET_1(&this->actor)) { + sp24 = Rand_ZeroOne() - 0.9f; + D_8095F690 = sp24 * 11000.0f; + D_8095F694 = ((Rand_ZeroOne() - 0.5f) * 3000.0f) * (fabsf(sp24) + 0.1f); + } else { + sp24 = Rand_ZeroOne() - 0.5f; + D_8095F690 = sp24 * 6000.0f; + D_8095F694 = ((Rand_ZeroOne() - 0.5f) * 1200.0f) * (fabsf(sp24) + 0.5f); + } + this->actor.colChkInfo.mass = 200; + this->unk_194 = 100; + this->actionFunc = func_8095EBDC; +} + +void func_8095EBDC(EnIshi* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp70 = ENISHI_GET_1(&this->actor); + s16 temp_s0; + s32 i; + s16 phi_s0; + Vec3f sp58; + s32 temp_v0 = (this->collider.base.atFlags & AT_HIT) != 0; + + if (temp_v0) { + this->collider.base.atFlags &= ~AT_HIT; + } + + this->unk_194--; + + if ((this->actor.bgCheckFlags & 9) || temp_v0 || (this->unk_194 <= 0)) { + func_8095DF90(this, globalCtx); + D_8095F6D8[sp70](&this->actor, globalCtx); + + if (!(this->actor.bgCheckFlags & 0x20)) { + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, D_8095F6D4[sp70], D_8095F6D0[sp70]); + D_8095F6E0[sp70](this, globalCtx); + } + + if (sp70 == 1) { + s16 quake = Quake_Add(GET_ACTIVE_CAM(globalCtx), 3); + + Quake_SetSpeed(quake, 0x4350); + Quake_SetQuakeValues(quake, 3, 0, 0, 0); + Quake_SetCountdown(quake, 7); + func_8013ECE0(this->actor.xyzDistToPlayerSq, 255, 20, 150); + } + + Actor_MarkForDeath(&this->actor); + return; + } + + if (this->actor.bgCheckFlags & 0x40) { + if (sp70 == 0) { + sp58.x = this->actor.world.pos.x; + sp58.y = this->actor.world.pos.y + this->actor.depthInWater; + sp58.z = this->actor.world.pos.z; + EffectSsGSplash_Spawn(globalCtx, &sp58, NULL, NULL, 0, 350); + EffectSsGRipple_Spawn(globalCtx, &sp58, 150, 650, 0); + } else { + sp58.y = this->actor.world.pos.y + this->actor.depthInWater; + + for (phi_s0 = 0, i = 0; i < 11; i++, phi_s0 += 0x1746) { + sp58.x = (Math_SinS((s32)(Rand_ZeroOne() * 2000.0f) + phi_s0) * 50.0f) + this->actor.world.pos.x; + sp58.z = (Math_CosS((s32)(Rand_ZeroOne() * 2000.0f) + phi_s0) * 50.0f) + this->actor.world.pos.z; + EffectSsGSplash_Spawn(globalCtx, &sp58, NULL, NULL, 0, 350); + } + + sp58.x = this->actor.world.pos.x; + sp58.z = this->actor.world.pos.z; + EffectSsGRipple_Spawn(globalCtx, &sp58, 500, 900, 4); + } + + this->actor.minVelocityY = -6.0f; + this->actor.velocity.x *= 0.12f; + this->actor.velocity.y *= 0.4f; + this->actor.velocity.z *= 0.12f; + this->actor.gravity *= 0.5f; + + D_8095F690 >>= 2; + D_8095F694 >>= 2; + + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L); + this->actor.bgCheckFlags &= ~0x40; + } + + Math_StepToF(&this->actor.shape.yOffset, 0.0f, 2.0f); + func_8095E14C(this); + func_8095E180(&this->actor.velocity, D_8095F6C8[sp70]); + Actor_ApplyMovement(&this->actor); + this->actor.shape.rot.x += D_8095F690; + this->actor.shape.rot.y += D_8095F694; + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 7.5f, 35.0f, 0.0f, 0xC5); + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void func_8095F060(EnIshi* this) { + this->actor.flags |= 0x10; + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + this->actionFunc = func_8095F0A4; +} + +void func_8095F0A4(EnIshi* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp28 = ENISHI_GET_1(&this->actor); + + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, D_8095F6D4[sp28], D_8095F6D0[sp28]); + D_8095F6D8[sp28](&this->actor, globalCtx); + D_8095F6E0[sp28](this, globalCtx); + this->actor.draw = NULL; + func_8095F180(this); + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } +} + +void func_8095F180(EnIshi* this) { + this->actionFunc = func_8095F194; +} + +void func_8095F194(EnIshi* this, GlobalContext* globalCtx) { + if (this->actor.cutscene < 0) { + Actor_MarkForDeath(&this->actor); + } else if (ActorCutscene_GetCurrentIndex() != this->actor.cutscene) { + Actor_MarkForDeath(&this->actor); + } +} + +void EnIshi_Update(Actor* thisx, GlobalContext* globalCtx) { + EnIshi* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void func_8095F210(EnIshi* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp28; + + if ((this->actor.projectedPos.z <= 1200.0f) || ((this->unk_197 & 1) && (this->actor.projectedPos.z < 1300.0f))) { + func_800BDFC0(globalCtx, gameplay_field_keep_DL_0066B0); + return; + } + + if (this->actor.projectedPos.z < 1300.0f) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + sp28 = (1300.0f - this->actor.projectedPos.z) * 2.55f; + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (s32)sp28); + gSPDisplayList(POLY_XLU_DISP++, gameplay_field_keep_DL_006760); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void func_8095F36C(EnIshi* this, GlobalContext* globalCtx) { + s32 pad; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if ((this->actor.projectedPos.z <= 2150.0f) || ((this->unk_197 & 1) && (this->actor.projectedPos.z < 2250.0f))) { + this->actor.shape.shadowAlpha = 160; + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, D_801AEFA0); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0, 255, 255, 255, 255); + gSPDisplayList(POLY_OPA_DISP++, gameplay_field_keep_DL_0061E8); + } else if (this->actor.projectedPos.z < 2250.0f) { + f32 sp20 = (2250.0f - this->actor.projectedPos.z) * 2.55f; + + this->actor.shape.shadowAlpha = sp20 * 0.627451f; + + func_8012C2DC(globalCtx->state.gfxCtx); + + gSPSegment(POLY_XLU_DISP++, 0x08, D_801AEF88); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (s32)sp20); + gSPDisplayList(POLY_XLU_DISP++, gameplay_field_keep_DL_0061E8); + } else { + this->actor.shape.shadowAlpha = 0; + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_8095F61C(Actor* thisx, GlobalContext* globalCtx) { + EnIshi* this = THIS; + + D_8095F7B0[ENISHI_GET_1(&this->actor)](this, globalCtx); +} + +void func_8095F654(Actor* thisx, GlobalContext* globalCtx) { + func_800BDFC0(globalCtx, object_ishi_DL_0009B0); +} diff --git a/src/overlays/actors/ovl_En_Ishi/z_en_ishi.h b/src/overlays/actors/ovl_En_Ishi/z_en_ishi.h index f68667c7d..404fec2b1 100644 --- a/src/overlays/actors/ovl_En_Ishi/z_en_ishi.h +++ b/src/overlays/actors/ovl_En_Ishi/z_en_ishi.h @@ -6,12 +6,26 @@ struct EnIshi; typedef void (*EnIshiActionFunc)(struct EnIshi*, GlobalContext*); +typedef void (*EnIshiUnkFunc)(struct EnIshi*, GlobalContext*); +typedef void (*EnIshiUnkFunc2)(Actor*, GlobalContext*); + +#define ENISHI_GET_1(thisx) ((thisx)->params & 1) +#define ENISHI_GET_2(thisx) (((thisx)->params >> 1) & 1) +#define ENISHI_GET_4(thisx) (((thisx)->params >> 2) & 1) +#define ENISHI_GET_8(thisx) (((thisx)->params >> 3) & 1) +#define ENISHI_GET_70(thisx) (((thisx)->params >> 4) & 7) +#define ENISHI_GET_F0(thisx) (((thisx)->params >> 4) & 0xF) +#define ENISHI_GET_100(thisx) (((thisx)->params >> 8) & 1) +#define ENISHI_GET_FE00(thisx) (((thisx)->params >> 9) & 0x7F) typedef struct EnIshi { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x4C]; + /* 0x0144 */ ColliderCylinder collider; /* 0x0190 */ EnIshiActionFunc actionFunc; - /* 0x0194 */ char unk_194[0x4]; + /* 0x0194 */ s8 unk_194; + /* 0x0195 */ s8 unk_195; + /* 0x0196 */ s8 unk_196; + /* 0x0197 */ u8 unk_197; } EnIshi; // size = 0x198 extern const ActorInit En_Ishi_InitVars; diff --git a/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c b/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c index 631fc26e5..be3fe843d 100644 --- a/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c +++ b/src/overlays/actors/ovl_En_Kakasi/z_en_kakasi.c @@ -1157,8 +1157,7 @@ void EnKakasi_LimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec EnKakasi* this = (EnKakasi*)actor; if (limbIndex == 4) { - // what is D_801D15B0 ? we didn't have to define it, we store the output though - Matrix_MultiplyVector3fByState(&D_801D15B0, &this->unk1BC); + Matrix_MultiplyVector3fByState(&gZeroVec3f, &this->unk1BC); } } diff --git a/src/overlays/actors/ovl_En_Kame/z_en_kame.c b/src/overlays/actors/ovl_En_Kame/z_en_kame.c index c8cceba61..71482f79f 100644 --- a/src/overlays/actors/ovl_En_Kame/z_en_kame.c +++ b/src/overlays/actors/ovl_En_Kame/z_en_kame.c @@ -5,6 +5,7 @@ */ #include "z_en_kame.h" +#include "objects/object_tl/object_tl.h" #define FLAGS 0x00000405 @@ -15,21 +16,31 @@ void EnKame_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnKame_Update(Actor* thisx, GlobalContext* globalCtx); void EnKame_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80AD70A0(EnKame* this); void func_80AD70EC(EnKame* this, GlobalContext* globalCtx); +void func_80AD71B4(EnKame* this); void func_80AD7254(EnKame* this, GlobalContext* globalCtx); +void func_80AD73A8(EnKame* this); void func_80AD7424(EnKame* this, GlobalContext* globalCtx); +void func_80AD76CC(EnKame* this); void func_80AD7798(EnKame* this, GlobalContext* globalCtx); +void func_80AD792C(EnKame* this); void func_80AD7948(EnKame* this, GlobalContext* globalCtx); +void func_80AD7B18(EnKame* this); void func_80AD7B90(EnKame* this, GlobalContext* globalCtx); void func_80AD7D40(EnKame* this, GlobalContext* globalCtx); +void func_80AD7DA4(EnKame* this); void func_80AD7E0C(EnKame* this, GlobalContext* globalCtx); +void func_80AD7EC0(EnKame* this); void func_80AD7F10(EnKame* this, GlobalContext* globalCtx); void func_80AD7FF8(EnKame* this, GlobalContext* globalCtx); void func_80AD810C(EnKame* this, GlobalContext* globalCtx); +void func_80AD8148(EnKame* this, GlobalContext* globalCtx); void func_80AD825C(EnKame* this, GlobalContext* globalCtx); +void func_80AD8364(EnKame* this); void func_80AD8388(EnKame* this, GlobalContext* globalCtx); +void func_80AD8D64(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit En_Kame_InitVars = { ACTOR_EN_KAME, ACTORCAT_ENEMY, @@ -42,18 +53,29 @@ const ActorInit En_Kame_InitVars = { (ActorFunc)EnKame_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80AD8DE0 = { - { COLTYPE_HARD, AT_NONE | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x04 }, { 0xF7CF7FFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_HARD, + AT_NONE | AT_TYPE_ENEMY, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0xF7CF7FFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 35, 40, 0, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit D_80AD8E0C = { 3, 15, 30, 80 }; +static CollisionCheckInfoInit sColChkInfoInit = { 3, 15, 30, 80 }; -// static DamageTable sDamageTable = { -static DamageTable D_80AD8E14 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x1), /* Deku Stick */ DMG_ENTRY(1, 0x0), /* Horse trample */ DMG_ENTRY(1, 0x0), @@ -88,107 +110,733 @@ static DamageTable D_80AD8E14 = { /* Powder Keg */ DMG_ENTRY(1, 0xF), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80AD8E44[] = { +static TexturePtr D_80AD8E34[] = { object_tl_Tex_0055A0, object_tl_Tex_0057A0, object_tl_Tex_0059A0, + object_tl_Tex_0057A0 }; + +static InitChainEntry sInitChain[] = { ICHAIN_S8(hintId, 1, ICHAIN_CONTINUE), ICHAIN_F32(gravity, -1, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 3500, ICHAIN_STOP), }; -#endif +static s32 D_80AD8E50 = false; -extern ColliderCylinderInit D_80AD8DE0; -extern CollisionCheckInfoInit D_80AD8E0C; -extern DamageTable D_80AD8E14; -extern InitChainEntry D_80AD8E44[]; +void EnKame_Init(Actor* thisx, GlobalContext* globalCtx) { + EnKame* this = THIS; -extern UNK_TYPE D_060008B4; -extern UNK_TYPE D_06000AF4; -extern UNK_TYPE D_06001C68; -extern UNK_TYPE D_06002510; -extern UNK_TYPE D_060027D8; -extern UNK_TYPE D_06002F88; -extern UNK_TYPE D_060031DC; -extern UNK_TYPE D_060035EC; -extern UNK_TYPE D_06004210; -extern UNK_TYPE D_0600823C; + Actor_ProcessInitChain(&this->actor, sInitChain); + SkelAnime_InitFlex(globalCtx, &this->skelAnime1, &object_tl_Skel_007C70, &object_tl_Anim_004210, this->jointTable1, + this->morphTable1, 13); + SkelAnime_InitFlex(globalCtx, &this->skelAnime2, &object_tl_Skel_001A50, &object_tl_Anim_000B30, this->jointTable2, + this->morphTable2, 4); + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 55.0f); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/EnKame_Init.s") + if (!D_80AD8E50) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/EnKame_Destroy.s") + for (i = 0; i < ARRAY_COUNT(D_80AD8E34); i++) { + D_80AD8E34[i] = Lib_SegmentedToVirtual(D_80AD8E34[i]); + } + D_80AD8E50 = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD6F34.s") + func_80AD70A0(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD6F9C.s") +void EnKame_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnKame* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7018.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD70A0.s") +void func_80AD6F34(EnKame* this) { + if (this->unk_29C != 0) { + this->unk_29C++; + if (this->unk_29C == 4) { + this->unk_29C = 0; + } + } else if (Rand_ZeroOne() < 0.05f) { + this->unk_29C = 1; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD70EC.s") +void func_80AD6F9C(EnKame* this) { + this->unk_29D = 10; + this->unk_2B4 = 0.6f; + this->unk_2B8 = 0.90000004f; + this->unk_2B0 = 1.0f; + this->collider.base.colType = COLTYPE_HIT3; + this->unk_2A2 = 80; + this->actor.flags &= ~0x400; + func_800BCB70(&this->actor, 0x4000, 255, 0, 80); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD71B4.s") +void func_80AD7018(EnKame* this, GlobalContext* globalCtx) { + if (this->unk_29D == 10) { + this->unk_29D = 0; + this->collider.base.colType = COLTYPE_HIT6; + this->unk_2B0 = 0.0f; + func_800BF7CC(globalCtx, &this->actor, this->unk_2C8, 10, 2, 0.3f, 0.2f); + this->actor.flags |= 0x400; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7254.s") +void func_80AD70A0(EnKame* this) { + Animation_MorphToPlayOnce(&this->skelAnime1, &object_tl_Anim_004210, -5.0f); + this->actor.speedXZ = 0.0f; + this->actionFunc = func_80AD70EC; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD73A8.s") +void func_80AD70EC(EnKame* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7424.s") + if (Animation_OnFrame(&this->skelAnime1, 10.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PAMET_VOICE); + this->unk_2A0 = 40; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7568.s") + if ((Player_GetMask(globalCtx) != PLAYER_MASK_STONE) && !(player->stateFlags1 & 0x800000) && + (this->actor.xzDistToPlayer < 240.0f)) { + func_80AD73A8(this); + } else if (SkelAnime_Update(&this->skelAnime1)) { + func_80AD71B4(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD75A8.s") +void func_80AD71B4(EnKame* this) { + Animation_MorphToLoop(&this->skelAnime1, &object_tl_Anim_00823C, -5.0f); + this->actor.speedXZ = 0.5f; + this->unk_29E = Animation_GetLastFrame(&object_tl_Anim_00823C) * ((s32)Rand_ZeroFloat(5.0f) + 3); + this->unk_2A4 = this->actor.shape.rot.y; + this->collider.base.acFlags |= (AC_HARD | AC_ON); + this->collider.base.colType = COLTYPE_HARD; + this->actionFunc = func_80AD7254; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD76CC.s") +void func_80AD7254(EnKame* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7798.s") + if ((Player_GetMask(globalCtx) != PLAYER_MASK_STONE) && !(player->stateFlags1 & 0x800000) && + (this->actor.xzDistToPlayer < 240.0f)) { + func_80AD73A8(this); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD792C.s") + SkelAnime_Update(&this->skelAnime1); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7948.s") + if (this->unk_2A4 != this->actor.shape.rot.y) { + Math_ScaledStepToS(&this->actor.shape.rot.y, this->unk_2A4, 0x100); + this->actor.world.rot.y = this->actor.shape.rot.y; + } else if (Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) > 40.0f) { + this->unk_2A4 = Actor_YawToPoint(&this->actor, &this->actor.home.pos) + (Rand_Next() >> 0x14); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7B18.s") + this->unk_29E--; + if (this->unk_29E == 0) { + func_80AD70A0(this); + } else if (Animation_OnFrame(&this->skelAnime1, 0.0f) || Animation_OnFrame(&this->skelAnime1, 15.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PAMET_WALK); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7B90.s") +void func_80AD73A8(EnKame* this) { + Animation_MorphToPlayOnce(&this->skelAnime1, &object_tl_Anim_001C68, -3.0f); + this->unk_29E = 0; + this->unk_2AC = 1.0f; + this->unk_2A8 = 1.0f; + this->actor.speedXZ = 0.0f; + if (this->unk_2A0 == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PAMET_VOICE); + } + this->actionFunc = func_80AD7424; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7C54.s") +void func_80AD7424(EnKame* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7D40.s") + if (SkelAnime_Update(&this->skelAnime1)) { + if ((Player_GetMask(globalCtx) != PLAYER_MASK_STONE) && !(player->stateFlags1 & 0x800000) && + ((this->unk_29E == 0) || (this->actor.xzDistToPlayer < 120.0f))) { + func_80AD76CC(this); + } else { + this->unk_29E--; + if (this->unk_29E == 0) { + func_80AD7B18(this); + } + } + } else if (this->skelAnime1.curFrame > 2.0f) { + this->unk_2AC = 1.5f - ((this->skelAnime1.curFrame - 2.0f) * (7.0f / 30)); + this->unk_2A8 = 1.5f - ((this->skelAnime1.curFrame - 2.0f) * (1.0f / 12)); + } else { + f32 frame = this->skelAnime1.curFrame; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7DA4.s") + this->unk_2AC = (0.25f * frame) + 1.0f; + this->unk_2A8 = (0.25f * frame) + 1.0f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7E0C.s") +void func_80AD7568(EnKame* this) { + this->actor.speedXZ = this->unk_2A6 * (5.0f / 7552); + this->actor.shape.rot.z = this->unk_2A6 * 0.11016949f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7EC0.s") +void func_80AD75A8(EnKame* this, GlobalContext* globalCtx) { + static Color_RGBA8 D_80AD8E54 = { 250, 250, 250, 255 }; + static Color_RGBA8 D_80AD8E58 = { 180, 180, 180, 255 }; + static Vec3f D_80AD8E5C = { 0.0f, 0.75f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7F10.s") + if ((this->actor.bgCheckFlags & 1) && (this->actor.speedXZ >= 3.0f)) { + if ((globalCtx->gameplayFrames % 2) == 0) { + u32 temp_v0 = func_800C9BB8(&globalCtx->colCtx, this->actor.floorPoly, this->actor.floorBgId); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7FA4.s") + if ((temp_v0 == 0) || (temp_v0 == 1)) { + func_800B1210(globalCtx, &this->actor.world.pos, &D_80AD8E5C, &gZeroVec3f, 550, 100); + } else if (temp_v0 == 14) { + func_800B0DE0(globalCtx, &this->actor.world.pos, &D_80AD8E5C, &gZeroVec3f, &D_80AD8E54, &D_80AD8E58, + 550, 100); + } + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD7FF8.s") + if (this->unk_2A6 > 0x1200) { + func_800B9010(&this->actor, NA_SE_EN_PAMET_ROLL - SFX_FLAG); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD8060.s") +void func_80AD76CC(EnKame* this) { + if (this->actor.draw == EnKame_Draw) { + this->actor.draw = func_80AD8D64; + this->unk_2A6 = 0x3B00; + this->unk_2AC = 0.5f; + func_80AD7568(this); + this->unk_29E = 15; + this->actor.speedXZ = 0.0f; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PAMET_CUTTER_ON); + this->unk_2BC.y = this->actor.home.pos.y - 100.0f; + } else { + this->actor.world.rot.y = Actor_YawToPoint(&this->actor, &this->actor.home.pos); + Math_Vec3f_Copy(&this->unk_2BC, &this->actor.home.pos); + this->unk_29E = 0; + } + this->actor.flags |= 0x10; + this->actionFunc = func_80AD7798; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD810C.s") +void func_80AD7798(EnKame* this, GlobalContext* globalCtx) { + if (this->unk_29E == 15) { + this->unk_2AC += 0.2f; + if (this->unk_2AC > 1.1f) { + this->unk_29E--; + this->collider.base.atFlags |= AT_ON; + this->unk_2AC = 1.0f; + } + } else if (this->unk_29E > 0) { + this->unk_29E--; + } else if (Math_ScaledStepToS(&this->unk_2A6, 0x3B00, (s32)(this->unk_2A6 * 0.09f) + 45)) { + if (this->unk_2BC.y < this->actor.home.pos.y) { + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + this->unk_2BC.x = (Math_SinS(this->actor.world.rot.y) * 360.0f) + this->actor.world.pos.x; + this->unk_2BC.z = (Math_CosS(this->actor.world.rot.y) * 360.0f) + this->actor.world.pos.z; + } + func_80AD792C(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD8148.s") + this->actor.shape.rot.y += this->unk_2A6; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD825C.s") + if (!(this->unk_2BC.y < this->actor.home.pos.y) || (this->actionFunc != func_80AD7798)) { + func_80AD7568(this); + } + func_80AD75A8(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD8364.s") +void func_80AD792C(EnKame* this) { + this->unk_29E = -1; + this->actionFunc = func_80AD7948; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD8388.s") +void func_80AD7948(EnKame* this, GlobalContext* globalCtx) { + s32 temp_v1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD84C0.s") + this->actor.shape.rot.y += this->unk_2A6; + func_80AD75A8(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/EnKame_Update.s") + if (this->unk_29E == -1) { + s16 temp_v0 = Actor_YawToPoint(&this->actor, &this->unk_2BC) - this->actor.world.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD8A48.s") + temp_v1 = ABS_ALT(temp_v0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD8AF8.s") + if ((this->actor.bgCheckFlags & 8) || (temp_v1 > 0x3000) || + (Actor_XZDistanceToPoint(&this->actor, &this->unk_2BC) < 50.0f)) { + s8 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/EnKame_Draw.s") + if (this->unk_2BC.y < this->actor.home.pos.y) { + this->unk_29E = 0x300; + } else { + this->unk_29E = 0; + } + } + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD8CEC.s") + if (Math_ScaledStepToS(&this->unk_2A6, this->unk_29E, (s32)(this->unk_2A6 * 0.09f) + 45)) { + if (this->unk_29E == 0) { + if (this->unk_2AC >= 1.0f) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PAMET_CUTTER_OFF); + } + this->unk_2AC -= 0.1f; + this->collider.base.atFlags &= ~AT_ON; + if (this->unk_2AC < 0.5f) { + this->actor.flags &= ~0x10; + func_80AD7B18(this); + } + } else { + func_80AD76CC(this); + } + } + func_80AD7568(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kame/func_80AD8D64.s") +void func_80AD7B18(EnKame* this) { + this->actor.draw = EnKame_Draw; + Animation_MorphToPlayOnce(&this->skelAnime1, &object_tl_Anim_0031DC, -3.0f); + this->actor.speedXZ = 0.0f; + this->unk_2AC = 0.1f; + this->unk_2A8 = 1.0f; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actionFunc = func_80AD7B90; +} + +void func_80AD7B90(EnKame* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime1)) { + func_80AD71B4(this); + } else if (this->skelAnime1.curFrame > 7.0f) { + this->unk_2AC = 1.5f - ((this->skelAnime1.curFrame - 7.0f) * (1.0f / 6)); + this->unk_2A8 = 1.5f - ((this->skelAnime1.curFrame - 7.0f) * (1.0f / 6)); + } else { + f32 frame = this->skelAnime1.curFrame; + + this->unk_2AC = (0.2f * frame) + 0.1f; + this->unk_2A8 = ((1.0f / 14) * frame) + 1.0f; + } +} + +void func_80AD7C54(EnKame* this) { + if (this->actionFunc == func_80AD7E0C) { + Animation_MorphToPlayOnce(&this->skelAnime1, &object_tl_Anim_0035EC, -3.0f); + this->unk_29E = 1; + this->collider.info.bumper.dmgFlags &= ~0x8000; + } else { + Animation_MorphToPlayOnce(&this->skelAnime1, &object_tl_Anim_0039C0, -3.0f); + this->unk_29E = 0; + this->collider.info.bumper.dmgFlags |= 0x8000; + } + + this->actor.draw = EnKame_Draw; + this->actor.speedXZ = 0.0f; + this->collider.base.acFlags &= ~AC_ON; + this->collider.base.atFlags &= ~AT_ON; + this->collider.base.atFlags &= ~(AT_BOUNCED | AT_HIT); + this->actor.flags &= ~0x10; + this->actor.shape.rot.z = 0; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PAMET_REVERSE); + this->actionFunc = func_80AD7D40; +} + +void func_80AD7D40(EnKame* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime1)) { + if (this->unk_29E == 1) { + func_80AD71B4(this); + } else { + this->unk_29E = 200; + func_80AD7DA4(this); + } + } +} + +void func_80AD7DA4(EnKame* this) { + Animation_MorphToPlayOnce(&this->skelAnime1, &object_tl_Anim_0027D8, -3.0f); + this->collider.base.acFlags |= AC_ON; + this->collider.base.acFlags &= ~AC_HARD; + this->collider.base.colType = COLTYPE_HIT6; + this->actor.speedXZ = 0.0f; + this->actionFunc = func_80AD7E0C; +} + +void func_80AD7E0C(EnKame* this, GlobalContext* globalCtx) { + if (this->unk_29E > 0) { + this->unk_29E--; + if (SkelAnime_Update(&this->skelAnime1)) { + if (Rand_ZeroOne() > 0.5f) { + Animation_PlayOnce(&this->skelAnime1, &object_tl_Anim_0027D8); + } else { + Animation_PlayOnce(&this->skelAnime1, &object_tl_Anim_002F88); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PAMET_ROAR); + } + } + } else { + func_80AD7EC0(this); + } +} + +void func_80AD7EC0(EnKame* this) { + Animation_MorphToPlayOnce(&this->skelAnime1, &object_tl_Anim_002510, -3.0f); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PAMET_WAKEUP); + this->actionFunc = func_80AD7F10; +} + +void func_80AD7F10(EnKame* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime1)) { + this->actor.shape.shadowDraw = func_800B3FC0; + func_80AD71B4(this); + } else if (this->skelAnime1.curFrame >= 10.0f) { + this->actor.shape.shadowDraw = NULL; + this->collider.base.acFlags &= ~AC_ON; + this->collider.info.bumper.dmgFlags &= ~0x8000; + } +} + +void func_80AD7FA4(EnKame* this) { + this->actor.speedXZ = 0.0f; + if (this->actor.velocity.y > 0.0f) { + this->actor.velocity.y = 0.0f; + } + func_800BE504(&this->actor, &this->collider); + this->actionFunc = func_80AD7FF8; +} + +void func_80AD7FF8(EnKame* this, GlobalContext* globalCtx) { + if (this->unk_2A2 != 0) { + this->unk_2A2--; + } + + if (this->unk_2A2 == 0) { + func_80AD7018(this, globalCtx); + if (this->actor.colChkInfo.health == 0) { + func_80AD8148(this, NULL); + } else { + this->actor.world.rot.y = this->actor.shape.rot.y; + func_80AD7DA4(this); + } + } +} + +void func_80AD8060(EnKame* this) { + s16 sp36 = Animation_GetLastFrame(&object_tl_Anim_0008B4); + + Animation_Change(&this->skelAnime1, &object_tl_Anim_0008B4, 1.0f, 0.0f, sp36, 2, -3.0f); + func_800BCB70(&this->actor, 0x4000, 255, 0, sp36); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PAMET_DAMAGE); + this->collider.base.acFlags &= ~AC_ON; + this->actionFunc = func_80AD810C; +} + +void func_80AD810C(EnKame* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime1)) { + func_80AD7DA4(this); + } +} + +void func_80AD8148(EnKame* this, GlobalContext* globalCtx) { + Animation_PlayLoop(&this->skelAnime1, &object_tl_Anim_000AF4); + func_800BCB70(&this->actor, 0x4000, 255, 0, 20); + this->collider.base.acFlags &= ~AC_ON; + this->collider.base.atFlags &= ~AT_ON; + this->collider.base.atFlags &= ~(AC_HARD | AC_HIT); + this->actor.velocity.y = 15.0f; + this->actor.speedXZ = 1.5f; + if (globalCtx != NULL) { + Enemy_StartFinishingBlow(globalCtx, &this->actor); + if (this->actor.draw == func_80AD8D64) { + this->actor.draw = EnKame_Draw; + } else { + func_800BE504(&this->actor, &this->collider); + } + } + this->actor.bgCheckFlags &= ~0x1; + this->actor.flags &= ~0x1; + this->actor.flags |= 0x10; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PAMET_DEAD); + this->unk_29E = 0; + this->actionFunc = func_80AD825C; +} + +void func_80AD825C(EnKame* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime1); + if ((this->actor.bgCheckFlags & 1) && (this->actor.velocity.y < 0.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_HIPLOOP_LAND); + func_80AD8364(this); + } else { + if (this->unk_29E == 1) { + this->actor.colorFilterTimer = 100; + } else if (this->actor.colorFilterTimer == 0) { + func_800BCB70(&this->actor, 0xC000, 255, 0, 100); + } + this->actor.shape.rot.x += Rand_S16Offset(0x700, 0x1400); + this->actor.shape.rot.y += (s16)Rand_ZeroFloat(5120.0f); + this->actor.shape.rot.z += Rand_S16Offset(0x700, 0x1400); + } +} + +void func_80AD8364(EnKame* this) { + this->unk_29E = 20; + this->actor.speedXZ = 0.0f; + this->actionFunc = func_80AD8388; +} + +void func_80AD8388(EnKame* this, GlobalContext* globalCtx) { + Vec3f sp34; + + SkelAnime_Update(&this->skelAnime1); + this->actor.colorFilterTimer = 100; + if (this->unk_29E > 0) { + this->unk_29E--; + if (this->unk_29E == 0) { + func_800F0590(globalCtx, &this->actor.world.pos, 21, NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG); + } + } else { + this->actor.scale.x -= 0.001f; + if (this->actor.scale.x <= 0.0f) { + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x60); + Actor_MarkForDeath(&this->actor); + } else { + this->actor.scale.y = this->actor.scale.x; + this->actor.scale.z = this->actor.scale.x; + } + sp34.x = randPlusMinusPoint5Scaled(40.0f) + this->actor.world.pos.x; + sp34.y = this->actor.world.pos.y + 15.0f; + sp34.z = randPlusMinusPoint5Scaled(40.0f) + this->actor.world.pos.z; + func_800B3030(globalCtx, &sp34, &gZeroVec3f, &gZeroVec3f, 100, 0, 2); + } +} + +void func_80AD84C0(EnKame* this, GlobalContext* globalCtx) { + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + + func_800BE258(&this->actor, &this->collider.info); + if ((this->unk_29D == 10) && (this->collider.info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) { + return; + } + + func_80AD7018(this, globalCtx); + if (this->actor.colChkInfo.damageEffect == 13) { + return; + } + + if (this->actor.colChkInfo.damageEffect == 14) { + func_80AD8148(this, globalCtx); + } else if (this->actor.colChkInfo.damageEffect == 15) { + if (this->collider.base.acFlags & AC_HARD) { + func_80AD7C54(this); + } else if (!Actor_ApplyDamage(&this->actor)) { + func_80AD8148(this, globalCtx); + } else { + func_80AD8060(this); + } + } else if ((this->actionFunc == func_80AD70EC) || (this->actionFunc == func_80AD7254)) { + func_80AD73A8(this); + this->unk_29E = 21; + } else if (!(this->collider.base.acFlags & AC_HARD)) { + if (this->actor.colChkInfo.damageEffect == 5) { + this->unk_2A2 = 40; + func_800BCB70(&this->actor, 0, 255, 0, 40); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->unk_2B4 = 0.6f; + this->unk_2B0 = 2.0f; + this->unk_29D = 30; + func_80AD7FA4(this); + } else if (this->actor.colChkInfo.damageEffect == 1) { + this->unk_2A2 = 40; + func_800BCB70(&this->actor, 0, 255, 0, 40); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + func_80AD7FA4(this); + } else if (this->actor.colChkInfo.damageEffect == 3) { + func_80AD6F9C(this); + if (!Actor_ApplyDamage(&this->actor)) { + this->unk_2A2 = 3; + this->collider.base.acFlags &= ~AC_ON; + } + func_80AD7FA4(this); + } else { + if (this->actor.colChkInfo.damageEffect == 2) { + this->unk_2B4 = 0.6f; + this->unk_2B0 = 4.0f; + this->unk_29D = 0; + } else if (this->actor.colChkInfo.damageEffect == 4) { + this->unk_2B4 = 0.6f; + this->unk_2B0 = 4.0f; + this->unk_29D = 20; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, + this->collider.info.bumper.hitPos.x, this->collider.info.bumper.hitPos.y, + this->collider.info.bumper.hitPos.z, 0, 0, 0, CLEAR_TAG_LARGE_LIGHT_RAYS); + } + + if (!Actor_ApplyDamage(&this->actor)) { + func_80AD8148(this, globalCtx); + } else { + func_80AD8060(this); + } + } + } + } + + if ((globalCtx->actorCtx.unk2 != 0) && (this->actor.xyzDistToPlayerSq < 40000.0f) && + (this->collider.base.acFlags & AC_ON)) { + func_80AD7018(this, globalCtx); + func_80AD7C54(this); + } +} + +void EnKame_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnKame* this = THIS; + + func_80AD6F34(this); + + if (this->unk_2A0 != 0) { + this->unk_2A0--; + } + + func_80AD84C0(this, globalCtx); + + if ((this->collider.base.atFlags & AT_HIT) && (this->collider.base.atFlags & AT_BOUNCED)) { + this->collider.base.atFlags &= ~(AT_BOUNCED | AT_HIT); + func_80AD76CC(this); + if (Actor_XZDistanceToPoint(&this->actor, &this->unk_2BC) < 50.0f) { + this->collider.base.atFlags &= ~AT_ON; + } + this->unk_2A6 = 0x3B00; + func_80AD7568(this); + } + + this->actionFunc(this, globalCtx); + + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 40.0f, 60.0f, 40.0f, 0x1F); + + if (this->actor.shape.shadowDraw != NULL) { + Actor_SetHeight(&this->actor, 25.0f); + Collider_UpdateCylinder(&this->actor, &this->collider); + } + + if (this->collider.base.atFlags & AT_ON) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + if (this->collider.base.acFlags & AC_ON) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + + if (this->unk_2B0 > 0.0f) { + if (this->unk_29D != 10) { + Math_StepToF(&this->unk_2B0, 0.0f, 0.05f); + this->unk_2B4 = (this->unk_2B0 + 1.0f) * 0.3f; + if (this->unk_2B4 > 0.6f) { + this->unk_2B4 = 0.6f; + } else { + this->unk_2B4 = this->unk_2B4; + } + } else if (!Math_StepToF(&this->unk_2B8, 0.6f, 0.015000001f)) { + func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } + } +} + +s32 func_80AD8A48(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnKame* this = THIS; + + if ((this->actionFunc == func_80AD7424) || (this->actionFunc == func_80AD7B90)) { + if (limbIndex == 2) { + Matrix_Scale(this->unk_2A8, this->unk_2AC, this->unk_2A8, MTXMODE_APPLY); + } else if ((limbIndex == 11) || (limbIndex == 9) || (limbIndex == 7) || (limbIndex == 5)) { + Matrix_Scale(this->unk_2A8, this->unk_2AC, this->unk_2AC, MTXMODE_APPLY); + } + } + return false; +} + +void func_80AD8AF8(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Vec3f D_80AD8E68[] = { + { 1500.0f, 0.0f, -2000.0f }, { 1500.0f, 0.0f, 2000.0f }, { 1500.0f, 2000.0f, 0.0f }, + { 1500.0f, -2000.0f, 0.0f }, { 2500.0f, 0.0f, 0.0f }, + }; + static s8 D_80AD8EA4[] = { -1, -1, -1, 0, -1, -1, 1, -1, 2, -1, 3, -1, 4 }; + EnKame* this = THIS; + + if (D_80AD8EA4[limbIndex] != -1) { + Matrix_GetStateTranslation(&this->unk_2C8[D_80AD8EA4[limbIndex]]); + } + + if (limbIndex == 1) { + s32 i; + Vec3f* ptr; + Vec3f* ptr2; + + if (this->actor.shape.shadowDraw == NULL) { + Matrix_GetStateTranslation(&this->actor.world.pos); + } + + ptr2 = D_80AD8E68; + ptr = &this->unk_2C8[5]; + for (i = 0; i < ARRAY_COUNT(D_80AD8E68); i++) { + Matrix_MultiplyVector3fByState(ptr2, ptr); + ptr2++; + ptr++; + } + } +} + +void EnKame_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnKame* this = THIS; + Vec3f sp40; + + if (this->actor.shape.shadowDraw == 0) { + Math_Vec3f_Copy(&sp40, &this->actor.world.pos); + } + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, D_80AD8E34[this->unk_29C]); + + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime1.skeleton, this->skelAnime1.jointTable, + this->skelAnime1.dListCount, func_80AD8A48, func_80AD8AF8, &this->actor); + func_800BE680(globalCtx, &this->actor, this->unk_2C8, 10, this->unk_2B4, this->unk_2B8, this->unk_2B0, + this->unk_29D); + + if (this->actor.shape.shadowDraw == NULL) { + func_800B3FC0(&this->actor, NULL, globalCtx); + Actor_SetHeight(&this->actor, 25.0f); + Collider_UpdateCylinder(&this->actor, &this->collider); + Math_Vec3f_Copy(&this->actor.world.pos, &sp40); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +s32 Enkame_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnKame* this = THIS; + + if (limbIndex == 1) { + pos->y -= 700.0f; + } + + if ((this->unk_2AC != 1.0f) && (limbIndex == 3)) { + Matrix_Scale(1.0f, this->unk_2AC, this->unk_2AC, MTXMODE_APPLY); + } + return false; +} + +void func_80AD8D64(Actor* thisx, GlobalContext* globalCtx) { + EnKame* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime2.skeleton, this->skelAnime2.jointTable, + this->skelAnime2.dListCount, Enkame_OverrideLimbDraw, NULL, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Kame/z_en_kame.h b/src/overlays/actors/ovl_En_Kame/z_en_kame.h index efdff3812..115bf137f 100644 --- a/src/overlays/actors/ovl_En_Kame/z_en_kame.h +++ b/src/overlays/actors/ovl_En_Kame/z_en_kame.h @@ -9,9 +9,28 @@ typedef void (*EnKameActionFunc)(struct EnKame*, GlobalContext*); typedef struct EnKame { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x154]; + /* 0x0144 */ SkelAnime skelAnime1; + /* 0x0188 */ Vec3s jointTable1[13]; + /* 0x01D6 */ Vec3s morphTable1[13]; + /* 0x0224 */ SkelAnime skelAnime2; + /* 0x0268 */ Vec3s jointTable2[4]; + /* 0x0280 */ Vec3s morphTable2[4]; /* 0x0298 */ EnKameActionFunc actionFunc; - /* 0x029C */ char unk_29C[0xF0]; + /* 0x029C */ u8 unk_29C; + /* 0x029D */ u8 unk_29D; + /* 0x029E */ s16 unk_29E; + /* 0x02A0 */ s16 unk_2A0; + /* 0x02A2 */ s16 unk_2A2; + /* 0x02A4 */ s16 unk_2A4; + /* 0x02A6 */ s16 unk_2A6; + /* 0x02A8 */ f32 unk_2A8; + /* 0x02AC */ f32 unk_2AC; + /* 0x02B0 */ f32 unk_2B0; + /* 0x02B4 */ f32 unk_2B4; + /* 0x02B8 */ f32 unk_2B8; + /* 0x02BC */ Vec3f unk_2BC; + /* 0x02C8 */ Vec3f unk_2C8[10]; + /* 0x0340 */ ColliderCylinder collider; } EnKame; // size = 0x38C extern const ActorInit En_Kame_InitVars; diff --git a/src/overlays/actors/ovl_En_Kanban/z_en_kanban.h b/src/overlays/actors/ovl_En_Kanban/z_en_kanban.h index 1ac436704..40eeb1060 100644 --- a/src/overlays/actors/ovl_En_Kanban/z_en_kanban.h +++ b/src/overlays/actors/ovl_En_Kanban/z_en_kanban.h @@ -10,6 +10,8 @@ typedef struct EnKanban { /* 0x144 */ char unk_144[0xAC]; } EnKanban; // size = 0x1F0 +#define ENKANBAN_FISHING 0x300 + extern const ActorInit En_Kanban_InitVars; #endif // Z_EN_KANBAN_H diff --git a/src/overlays/actors/ovl_En_Kgy/z_en_kgy.c b/src/overlays/actors/ovl_En_Kgy/z_en_kgy.c index be9d78aed..db4363228 100644 --- a/src/overlays/actors/ovl_En_Kgy/z_en_kgy.c +++ b/src/overlays/actors/ovl_En_Kgy/z_en_kgy.c @@ -401,7 +401,7 @@ s32 func_80B41528(GlobalContext* globalCtx) { } void func_80B415A8(GlobalContext* globalCtx, Vec3f* arg1) { - static EffShieldParticleInit D_80B43298 = { + static EffectShieldParticleInit D_80B43298 = { 16, { 0, 0, 0 }, { 0, 200, 255, 255 }, @@ -426,7 +426,7 @@ void func_80B415A8(GlobalContext* globalCtx, Vec3f* arg1) { D_80B43298.lightPoint.y = D_80B43298.position.y; D_80B43298.lightPoint.z = D_80B43298.position.z; - Effect_Add(globalCtx, &effectIndex, 3, 0, 1, &D_80B43298); + Effect_Add(globalCtx, &effectIndex, EFFECT_SHIELD_PARTICLE, 0, 1, &D_80B43298); } void func_80B4163C(EnKgy* this, GlobalContext* globalCtx) { diff --git a/src/overlays/actors/ovl_En_Kujiya/z_en_kujiya.h b/src/overlays/actors/ovl_En_Kujiya/z_en_kujiya.h index b34679bd3..72aeb93b7 100644 --- a/src/overlays/actors/ovl_En_Kujiya/z_en_kujiya.h +++ b/src/overlays/actors/ovl_En_Kujiya/z_en_kujiya.h @@ -10,7 +10,7 @@ typedef void (*EnKujiyaActionFunc)(struct EnKujiya*, GlobalContext*); typedef struct EnKujiya { /* 0x0000 */ Actor actor; /* 0x0144 */ EnKujiyaActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x4]; + /* 0x0148 */ char unk_148[0x4]; } EnKujiya; // size = 0x14C extern const ActorInit En_Kujiya_InitVars; diff --git a/src/overlays/actors/ovl_En_Kusa/z_en_kusa.h b/src/overlays/actors/ovl_En_Kusa/z_en_kusa.h index e3756a4d2..612f7b2ef 100644 --- a/src/overlays/actors/ovl_En_Kusa/z_en_kusa.h +++ b/src/overlays/actors/ovl_En_Kusa/z_en_kusa.h @@ -10,7 +10,7 @@ typedef void (*EnKusaActionFunc)(struct EnKusa*, GlobalContext*); typedef struct EnKusa { /* 0x0000 */ Actor actor; /* 0x0144 */ EnKusaActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x54]; + /* 0x0148 */ char unk_148[0x54]; } EnKusa; // size = 0x19C extern const ActorInit En_Kusa_InitVars; diff --git a/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.c b/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.c index c46ed7728..df691b0df 100644 --- a/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.c +++ b/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.c @@ -1,7 +1,7 @@ /* * File: z_en_kusa2.c * Overlay: ovl_En_Kusa2 - * Description: Keaton grass? + * Description: Keaton grass */ #include "z_en_kusa2.h" @@ -15,18 +15,42 @@ void EnKusa2_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnKusa2_Update(Actor* thisx, GlobalContext* globalCtx); void EnKusa2_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80A5C70C(EnKusa2UnkBssSubStruct* arg0); +void func_80A5CF44(EnKusa2* this); +void func_80A5D5E0(EnKusa2* this); void func_80A5D5F4(EnKusa2* this, GlobalContext* globalCtx); +void func_80A5D618(EnKusa2* this); void func_80A5D62C(EnKusa2* this, GlobalContext* globalCtx); +void func_80A5D6B0(EnKusa2* this); void func_80A5D6C4(EnKusa2* this, GlobalContext* globalCtx); +void func_80A5D754(EnKusa2* this); void func_80A5D794(EnKusa2* this, GlobalContext* globalCtx); +void func_80A5D7A4(EnKusa2* this); void func_80A5D7C4(EnKusa2* this, GlobalContext* globalCtx); +void func_80A5D964(EnKusa2* this); void func_80A5D9C8(EnKusa2* this, GlobalContext* globalCtx); +void func_80A5DC70(EnKusa2* this); void func_80A5DC98(EnKusa2* this, GlobalContext* globalCtx); +void func_80A5DE18(EnKusa2* this); void func_80A5DEB4(EnKusa2* this, GlobalContext* globalCtx); +void func_80A5E1D8(EnKusa2* this); void func_80A5E210(EnKusa2* this, GlobalContext* globalCtx); +void func_80A5E418(EnKusa2* this); void func_80A5E4BC(EnKusa2* this, GlobalContext* globalCtx); +void func_80A5E604(Actor* thisx, GlobalContext* globalCtx); +void func_80A5E6F0(Actor* thisx, GlobalContext* globalCtx); +void func_80A5E9B4(Actor* thisx, GlobalContext* globalCtx); +void func_80A5EA48(Actor* thisx, GlobalContext* globalCtx); + +static EnKusa2UnkBssStruct D_80A5F1C0; +static u32 D_80A60900; +static MtxF D_80A60908[8]; +static s16 D_80A60B08; +static s16 D_80A60B0A; +static s16 D_80A60B0C; +static s16 D_80A60B0E; +static s16 D_80A60B10; -#if 0 const ActorInit En_Kusa2_InitVars = { ACTOR_EN_KUSA2, ACTORCAT_PROP, @@ -39,146 +63,1320 @@ const ActorInit En_Kusa2_InitVars = { (ActorFunc)EnKusa2_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A5EAC0 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_PLAYER | OC1_TYPE_2, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x0580C71C, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_PLAYER | OC1_TYPE_2, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x0580C71C, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 6, 44, 0, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80A5EB50[] = { - ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_CONTINUE), - ICHAIN_F32_DIV1000(minVelocityY, -17000, ICHAIN_CONTINUE), - ICHAIN_VEC3F_DIV1000(scale, 400, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneForward, 1200, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_STOP), +static u8 D_80A5EAEC = 1; +static s16 D_80A5EAF0 = 0; +static Vec3s D_80A5EAF4 = { 0, 0, 0 }; +static Vec3s D_80A5EAFC = { 0, 0, 0 }; +static Vec3s D_80A5EB04 = { 0, 0, 0 }; + +void func_80A5B160(EnKusa2* this, GlobalContext* globalCtx) { + s32 i; + s16 temp_s1; + EnKusa2** ptr; + EnKusa2* actor; + + if (this->unk_194[0] == NULL) { + ptr = this->unk_194; + actor = (EnKusa2*)Actor_SpawnAsChildAndCutscene( + &globalCtx->actorCtx, globalCtx, ACTOR_EN_KUSA2, this->actor.world.pos.x, this->actor.world.pos.y, + this->actor.world.pos.z, 0, (u32)Rand_Next() >> 0x10, 0, 1, this->actor.cutscene, this->actor.unk20, NULL); + *ptr = actor; + + if (*ptr != NULL) { + (*ptr)->actor.room = this->actor.room; + (*ptr)->unk_1C0 = this; + } + } + + for (i = 1; i < ARRAY_COUNT(this->unk_194); i++) { + temp_s1 = (i << 0xD) - 0x2000; + if (this->unk_194[i] == NULL) { + ptr = &this->unk_194[i]; + actor = (EnKusa2*)Actor_SpawnAsChildAndCutscene( + &globalCtx->actorCtx, globalCtx, ACTOR_EN_KUSA2, (Math_SinS(temp_s1) * 80.0f) + this->actor.world.pos.x, + this->actor.world.pos.y, (Math_CosS(temp_s1) * 80.0f) + this->actor.world.pos.z, 0, + (u32)Rand_Next() >> 0x10, 0, 1, this->actor.cutscene, this->actor.unk20, NULL); + *ptr = actor; + if (*ptr != NULL) { + (*ptr)->actor.room = this->actor.room; + (*ptr)->unk_1C0 = this; + } + } + } +} + +void func_80A5B334(EnKusa2* this, GlobalContext* globalCtx) { + s32 i; + EnKusa2** ptr; + + for (i = 0; i < ARRAY_COUNT(this->unk_194); i++) { + ptr = &this->unk_194[i]; + + if (*ptr != NULL) { + if (!Actor_HasParent(&(*ptr)->actor, globalCtx)) { + Actor_MarkForDeath(&(*ptr)->actor); + } + *ptr = NULL; + } + } +} + +void func_80A5B3BC(EnKusa2* this) { + s32 i; + EnKusa2** ptr; + + for (i = 0; i < ARRAY_COUNT(this->unk_194); i++) { + ptr = &this->unk_194[i]; + if ((*ptr != NULL) && ((*ptr)->actor.update == NULL)) { + *ptr = NULL; + } + } +} + +void func_80A5B490(EnKusa2* this, GlobalContext* globalCtx) { + Actor_SpawnAsChildAndCutscene(&globalCtx->actorCtx, globalCtx, ACTOR_EN_KITAN, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, + ENKUSA2_GET_7F00(&this->actor) << 9, this->actor.cutscene, this->actor.unk20, NULL); +} + +void func_80A5B508(void) { + s32 i; + s32 pad; + f32 spB4; + f32* ptr; + f32 spAC; + f32 spA8; + f32 tempf1; + f32 tempf2; + f32 tempf3; + f32 tempf4; + f32 tempf5; + f32 sp74[8]; + f32 temp_f20; + f32 temp_f22; + f32 temp_f24; + f32 temp_f26; + f32 temp_f28; + f32 temp_f2; + f32 temp_f30; + + D_80A60B08 += 70; + D_80A60B0A += 300; + D_80A60B0C += 700; + D_80A60B0E += 1300; + D_80A60B10 += 8900; + temp_f28 = Math_SinS(D_80A60B08); + spB4 = Math_SinS(D_80A60B0A); + temp_f30 = Math_SinS(D_80A60B0C); + spAC = Math_SinS(D_80A60B0E) * 1.2f; + spA8 = Math_SinS(D_80A60B10) * 1.5f; + temp_f26 = Math_CosS(D_80A60B08); + temp_f20 = Math_CosS(D_80A60B0A); + temp_f22 = Math_CosS(D_80A60B0C); + temp_f24 = Math_CosS(D_80A60B0E) * 1.3f; + temp_f2 = Math_CosS(D_80A60B10) * 1.7f; + + sp74[0] = (temp_f28 - temp_f20) * temp_f30 * temp_f26 * temp_f28; + sp74[1] = (spB4 - temp_f22) * spAC * temp_f20 * temp_f28; + sp74[2] = (temp_f30 - temp_f24) * temp_f22 * temp_f28 * temp_f26; + sp74[3] = (spAC - temp_f20) * temp_f24 * spB4 * temp_f26; + sp74[4] = (temp_f28 - temp_f22) * temp_f28 * spB4 * spA8; + sp74[5] = (spB4 - temp_f24) * temp_f30 * spAC * spA8; + sp74[6] = (temp_f30 - temp_f26) * temp_f26 * temp_f20 * temp_f2; + sp74[7] = (spAC - temp_f20) * temp_f22 * temp_f24 * temp_f2; + + for (i = 0; i < ARRAY_COUNT(D_80A60908); i++) { + ptr = (f32*)&D_80A60908[i].mf[0]; + + tempf1 = sp74[(i + 0) & 7]; + tempf2 = sp74[(i + 1) & 7]; + tempf3 = sp74[(i + 2) & 7]; + tempf4 = sp74[(i + 3) & 7]; + tempf5 = sp74[(i + 4) & 7]; + + ptr[0] = sp74[1] * 0.2f; + ptr[1] = tempf1; + ptr[2] = tempf2; + ptr[3] = 0.0f; + + ptr[4] = tempf3; + ptr[5] = sp74[0]; + ptr[6] = tempf3; + ptr[7] = 0.0f; + + ptr[8] = tempf4; + ptr[9] = tempf5; + ptr[10] = sp74[3] * 0.2f; + ptr[11] = 0.0f; + + ptr[12] = 0.0f; + ptr[13] = 0.0f; + ptr[14] = 0.0f; + ptr[15] = 0.0f; + } +} + +void func_80A5B954(MtxF* matrix, f32 arg1) { + s32 i; + MtxF* temp = Matrix_GetCurrentState(); + f32* tmp = (f32*)&temp->mf[0]; + f32* tmp2 = (f32*)&matrix->mf[0]; + + for (i = 0; i < 16; i++) { + *tmp++ += *tmp2++ * arg1; + } +} + +s32 func_80A5BA58(EnKusa2* this, GlobalContext* globalCtx) { + Vec3f sp24; + s32 sp20; + + sp24.x = this->actor.world.pos.x; + sp24.y = this->actor.world.pos.y + 30.0f; + sp24.z = this->actor.world.pos.z; + this->actor.floorHeight = + BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &sp20, &this->actor, &sp24); + if (this->actor.floorHeight > BGCHECK_Y_MIN) { + this->actor.floorBgId = sp20; + this->actor.world.pos.y = this->actor.floorHeight; + Math_Vec3f_Copy(&this->actor.home.pos, &this->actor.world.pos); + return true; + } + return false; +} + +void func_80A5BAFC(EnKusa2* this, GlobalContext* globalCtx) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 15.0f, 35.0f, 0.0f, 0x45); +} + +void func_80A5BB40(EnKusa2* this, GlobalContext* globalCtx, s32 arg2) { + static Vec3f D_80A5EB0C = { 0.0f, 0.3f, 0.0f }; + static Vec3f D_80A5EB18 = { 0.0f, 0.0f, 0.0f }; + s32 pad; + s32 i; + Vec3f sp84; + f32 temp_f20; + f32 temp_f22; + f32 temp_f24; + s16 temp_s0; + + if (this->actor.flags & 0x40) { + for (i = 0; i <= arg2; i++) { + temp_s0 = Rand_S16Offset(-16000, 32000) + this->actor.world.rot.y; + temp_f20 = Math_SinS(temp_s0); + temp_f22 = Math_CosS(temp_s0); + temp_f24 = Rand_ZeroOne() * -12.0f; + + sp84.x = (temp_f20 * temp_f24) + this->actor.world.pos.x; + sp84.y = (Rand_ZeroOne() * 8.0f) + 2.0f + this->actor.world.pos.y; + sp84.z = (temp_f22 * temp_f24) + this->actor.world.pos.z; + + D_80A5EB18.x = temp_f20 * -0.9f; + D_80A5EB18.z = temp_f22 * -0.9f; + + D_80A5EB0C.x = D_80A5EB18.x * -0.09f; + D_80A5EB0C.z = D_80A5EB18.z * -0.09f; + + func_800B1210(globalCtx, &sp84, &D_80A5EB18, &D_80A5EB0C, 10, 50); + } + } +} + +void func_80A5BD14(EnKusa2* this, GlobalContext* globalCtx, s32 arg2) { + static s32 D_80A5EB24[] = { + ITEM00_RUPEE_GREEN, ITEM00_RUPEE_GREEN, ITEM00_RUPEE_GREEN, ITEM00_RUPEE_GREEN, ITEM00_RUPEE_GREEN, + ITEM00_RUPEE_GREEN, ITEM00_RUPEE_GREEN, ITEM00_RUPEE_GREEN, ITEM00_RUPEE_RED, + }; + EnKusa2* kusa2 = this->unk_1C0; + + if (kusa2 != NULL) { + if (kusa2->unk_1BC > 8) { + kusa2->unk_1BC = 8; + } + Item_DropCollectible(globalCtx, &this->actor.world.pos, D_80A5EB24[kusa2->unk_1BC]); + kusa2->unk_1BC += arg2; + } +} + +void func_80A5BD94(EnKusa2* this) { + if (this->unk_1C0 != NULL) { + this->unk_1C0->unk_1BE = 1; + } +} + +void func_80A5BDB0(EnKusa2* this, GlobalContext* globalCtx) { + s32 pad[2]; + s32 i; + Vec3f sp50; + s16 phi_s0; + + sp50.y = this->actor.world.pos.y + this->actor.depthInWater; + + for (phi_s0 = 0, i = 0; i < 4; i++, phi_s0 += 0x4000) { + sp50.x = (Math_SinS((s32)(Rand_ZeroOne() * 7200.0f) + phi_s0) * 15.0f) + this->actor.world.pos.x; + sp50.z = (Math_CosS((s32)(Rand_ZeroOne() * 7200.0f) + phi_s0) * 15.0f) + this->actor.world.pos.z; + EffectSsGSplash_Spawn(globalCtx, &sp50, NULL, NULL, 0, 190); + } + + sp50.x = this->actor.world.pos.x; + sp50.z = this->actor.world.pos.z; + EffectSsGSplash_Spawn(globalCtx, &sp50, NULL, NULL, 0, 280); + EffectSsGRipple_Spawn(globalCtx, &sp50, 300, 700, 0); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L); +} + +void func_80A5BF38(EnKusa2* this, s32 arg1) { + this->actor.shape.shadowAlpha += (u8)arg1; + if (this->actor.shape.shadowAlpha > 60) { + this->actor.shape.shadowAlpha = 60; + } +} + +void func_80A5BF60(EnKusa2* this, s32 arg1) { + s32 alpha = this->actor.shape.shadowAlpha; + + alpha -= arg1; + if (alpha > 0) { + this->actor.shape.shadowAlpha = alpha; + } else { + this->actor.shape.shadowAlpha = 0; + } +} + +void func_80A5BF84(EnKusa2* this, GlobalContext* globalCtx) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +s32 func_80A5BFD8(EnKusa2* this, GlobalContext* globalCtx) { + if (this->collider.base.acFlags & 2) { + s32 pad; + + func_80A5CF44(this); + func_80A5BD14(this, globalCtx, (this->collider.info.acHitInfo->toucher.dmgFlags & 0x1000000) ? 1 : 0); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_PLANT_BROKEN); + func_80A5BD94(this); + Actor_MarkForDeath(&this->actor); + return true; + } + return false; +} + +EnKusa2UnkBssSubStruct* func_80A5C074(EnKusa2UnkBssStruct* arg0) { + s32 i; + EnKusa2UnkBssSubStruct* phi_v1 = &arg0->unk_0000[0]; + + for (i = 1; i < ARRAY_COUNT(D_80A5F1C0.unk_0000); i++) { + if (!(phi_v1->unk_26 <= arg0->unk_0000[i].unk_26)) { + phi_v1 = &arg0->unk_0000[i]; + if (phi_v1->unk_26 <= 0) { + break; + } + } + } + + return phi_v1; +} + +EnKusa2UnkBssSubStruct2* func_80A5C0B8(EnKusa2UnkBssStruct* arg0) { + s32 i; + EnKusa2UnkBssSubStruct2* phi_v1 = &arg0->unk_0480[0]; + + for (i = 1; i < ARRAY_COUNT(D_80A5F1C0.unk_0480); i++) { + if (!(phi_v1->unk_2C <= arg0->unk_0480[i].unk_2C)) { + phi_v1 = &arg0->unk_0480[i]; + if (1) {} + if (phi_v1->unk_2C <= 0) { + break; + } + } + } + + return phi_v1; +} + +EnKusa2UnkBssSubStruct* func_80A5C104(EnKusa2UnkBssStruct* arg0, Vec3f* arg1, f32 arg2, f32 arg3, s16 arg4, s16 arg5) { + static s32 D_80A5EB48 = 0; + EnKusa2UnkBssSubStruct* ptr = func_80A5C074(arg0); + f32 sp20; + f32 temp_f6; + + Math_Vec3f_Copy(&ptr->unk_00, arg1); + Math_Vec3f_Copy(&ptr->unk_0C, &gZeroVec3f); + + ptr->unk_18 = arg2; + ptr->unk_1C = arg3; + ptr->unk_20 = arg4; + ptr->unk_22 = arg5; + + D_80A5EB48++; + if (D_80A5EB48 >= 3) { + D_80A5EB48 = 0; + ptr->unk_26 = Rand_S16Offset(40, 40); + } else { + ptr->unk_26 = Rand_S16Offset(30, 20); + } + + ptr->unk_24 = ptr->unk_26 - 20; + sp20 = 1.0f / ptr->unk_24; + ptr->unk_28 = func_80A5C70C; + ptr->unk_2C = 0.0f; + ptr->unk_30 = 0.0f; + temp_f6 = Rand_ZeroOne() * 60.0f; + ptr->unk_34 = (temp_f6 + 20.0f) * 0.05f; + ptr->unk_38 = (temp_f6 + 20.0f) * sp20; + ptr->unk_3C = 40.0f; + ptr->unk_40 = -1.5f; + ptr->unk_44 = -50.0f * sp20; + ptr->unk_48 = 140.0f; + ptr->unk_4C = SQ(140.0f); + ptr->unk_50 = 819.2f; + ptr->unk_54 = 327.68f; + ptr->unk_58 = 2.5f; + ptr->unk_5C = 0.05f; + ptr->unk_60 = 3.5f * sp20; + ptr->unk_64 = 0.35f; + ptr->unk_68 = 0.0875f; + ptr->unk_6C = 160.0f; + ptr->unk_70 = SQ(160.0f); + ptr->unk_74 = 204.8f; + ptr->unk_78 = 100.0f; + ptr->unk_7C = 327.68f; + return ptr; +} + +EnKusa2UnkBssSubStruct2* func_80A5C2FC(EnKusa2UnkBssStruct* arg0, f32 arg1, Vec3f* arg2, Vec3f* arg3, Vec3s* arg4, + Vec3s* arg5) { + Vec3f* temp_a0; + EnKusa2UnkBssSubStruct2* temp_s0; + f32 phi_f8; + + temp_s0 = func_80A5C0B8(arg0); + temp_s0->unk_00 = arg1; + Math_Vec3f_Copy(&temp_s0->unk_04, arg2); + Math_Vec3f_Copy(&temp_s0->unk_10, arg3); + + if (arg1 >= 0.35f) { + temp_s0->unk_1C = (6.0f / 7); + } else if (arg1 <= 0.1f) { + temp_s0->unk_1C = 1.0f; + } else { + temp_s0->unk_1C = (0.02f / arg1) + 0.8f; + } + + temp_s0->unk_20 = *arg4; + temp_s0->unk_26 = *arg5; + temp_s0->unk_2C = Rand_S16Offset(65, 30); + + return temp_s0; +} + +void func_80A5C410(EnKusa2UnkBssStruct* arg0, EnKusa2UnkBssSubStruct2* arg1, Vec3f* arg2) { + s32 i; + Vec3f sp98; + EnKusa2UnkBssSubStruct* s; + s32 pad; + + Math_Vec3f_Copy(arg2, &gZeroVec3f); + + for (i = 0; i < ARRAY_COUNT(D_80A5F1C0.unk_0000); i++) { + s = &arg0->unk_0000[i]; + + if (s->unk_26 > 0) { + f32 temp_f0; + s32 phi_v0 = true; + s32 phi_s2 = true; + + Math_Vec3f_Diff(&arg1->unk_04, &s->unk_00, &sp98); + temp_f0 = Math3D_LengthSquared(&sp98); + + phi_v0 = false; + if (temp_f0 <= s->unk_4C) { + phi_v0 = true; + } + + phi_s2 = false; + if (temp_f0 <= s->unk_70) { + phi_s2 = true; + } + + if (phi_v0 || phi_s2) { + f32 phi_f22; + + if (temp_f0 < SQ(0.01f)) { + phi_f22 = 0.0f; + } else { + phi_f22 = sqrtf(temp_f0); + } + + if (phi_v0) { + f32 phi_f2; + f32 phi_f20; + + if (phi_f22 > 1.0f) { + phi_f20 = 1.0f / phi_f22; + } else { + phi_f20 = 1.0f; + } + + if (phi_f22 < s->unk_3C) { + phi_f2 = Math_SinS(s->unk_50 * phi_f22) * -s->unk_2C; + } else { + phi_f2 = (Math_CosS(s->unk_54 * (phi_f22 - s->unk_3C)) + 1.0f) * s->unk_30; + } + + arg2->x += sp98.x * -(phi_f20 * phi_f2); + arg2->z += sp98.z * -(phi_f20 * phi_f2); + + if (phi_s2) { + arg2->x += phi_f20 * sp98.z * s->unk_58; + arg2->z -= phi_f20 * sp98.x * s->unk_58; + } + } + + if (phi_s2 && (fabsf(sp98.y) < s->unk_78)) { + arg2->y += + s->unk_68 * (Math_CosS(s->unk_74 * phi_f22) + 1.0f) * (Math_CosS(s->unk_7C * sp98.y) + 1.0f); + } + } + } + } + + arg2->y -= 0.5f; +} + +void func_80A5C70C(EnKusa2UnkBssSubStruct* arg0) { +} + +void func_80A5C718(EnKusa2UnkBssSubStruct* arg0) { + Math_ScaledStepToS(&arg0->unk_20, arg0->unk_22, 1200); + + if ((arg0->unk_1C > 0.0f) && (Rand_ZeroOne() < 0.05f)) { + arg0->unk_1C = -arg0->unk_1C; + } + + arg0->unk_0C.x = Math_SinS(arg0->unk_22) * arg0->unk_18; + arg0->unk_0C.y += arg0->unk_1C; + arg0->unk_0C.z = Math_CosS(arg0->unk_22) * arg0->unk_18; + + arg0->unk_00.x += arg0->unk_0C.x; + arg0->unk_00.y += arg0->unk_0C.y; + arg0->unk_00.z += arg0->unk_0C.z; +} + +void func_80A5C7F0(EnKusa2UnkBssStruct* arg0, EnKusa2UnkBssSubStruct* arg1) { + if (arg1->unk_26 > 0) { + arg1->unk_26--; + arg1->unk_28(arg1); + if (arg1->unk_26 >= arg1->unk_24) { + arg1->unk_2C += arg1->unk_34; + arg1->unk_3C += arg1->unk_40; + arg1->unk_58 += arg1->unk_5C; + } else { + arg1->unk_2C -= arg1->unk_38; + if (arg1->unk_2C < 0.0f) { + arg1->unk_2C = 0.0f; + } + arg1->unk_3C -= arg1->unk_44; + arg1->unk_58 -= arg1->unk_60; + if (arg1->unk_58 < 0.0f) { + arg1->unk_58 = 0.0f; + } + } + arg1->unk_30 = arg1->unk_2C * 0.5f; + arg1->unk_50 = 0x8000 / arg1->unk_3C; + arg1->unk_54 = 0x8000 / (arg1->unk_48 - arg1->unk_3C); + } +} + +void func_80A5C918(EnKusa2UnkBssStruct* arg0, EnKusa2UnkBssSubStruct2* arg1) { + Vec3f sp4C; + s32 pad; + s32 pad2; + Vec3f sp38; + Vec3f sp2C; + f32 phi_f0; + + if (arg1->unk_2C > 0) { + arg1->unk_2C--; + + func_80A5C410(arg0, arg1, &sp4C); + + arg1->unk_10.x += sp4C.x; + arg1->unk_10.y += sp4C.y; + arg1->unk_10.z += sp4C.z; + + sp38.x = arg1->unk_10.x * (arg1->unk_1C * 0.06f); + sp38.x = arg1->unk_10.x * (arg1->unk_1C * 0.06f); + sp38.y = arg1->unk_10.y * (arg1->unk_1C * 0.06f); + sp38.z = arg1->unk_10.z * (arg1->unk_1C * 0.06f); + + sp2C.x = SQ(arg1->unk_10.x) * (arg1->unk_1C * 0.004f); + sp2C.y = SQ(arg1->unk_10.y) * (arg1->unk_1C * 0.004f); + sp2C.z = SQ(arg1->unk_10.z) * (arg1->unk_1C * 0.004f); + + if (arg1->unk_10.x > 0.0f) { + phi_f0 = sp2C.x; + } else { + phi_f0 = -sp2C.x; + } + arg1->unk_10.x -= sp38.x + phi_f0; + + if (arg1->unk_10.y > 0.0f) { + phi_f0 = sp2C.y; + } else { + phi_f0 = -sp2C.y; + } + arg1->unk_10.y -= sp38.y + phi_f0; + + if (arg1->unk_10.z > 0.0f) { + phi_f0 = sp2C.z; + } else { + phi_f0 = -sp2C.z; + } + arg1->unk_10.z -= sp38.z + phi_f0; + + arg1->unk_04.x += arg1->unk_10.x; + arg1->unk_04.y += arg1->unk_10.y; + arg1->unk_04.z += arg1->unk_10.z; + arg1->unk_20.x += arg1->unk_26.x; + arg1->unk_20.y += arg1->unk_26.y; + arg1->unk_20.z += arg1->unk_26.z; + } +} + +void func_80A5CAD4(EnKusa2UnkBssStruct* arg0) { + bzero(arg0, sizeof(EnKusa2UnkBssStruct)); +} + +void func_80A5CAF4(EnKusa2UnkBssStruct* arg0) { + s32 i; + + for (i = 0; i < ARRAY_COUNT(D_80A5F1C0.unk_0000); i++) { + func_80A5C7F0(arg0, &arg0->unk_0000[i]); + } + + for (i = 0; i < ARRAY_COUNT(D_80A5F1C0.unk_0480); i++) { + func_80A5C918(arg0, &arg0->unk_0480[i]); + } +} + +void func_80A5CB74(EnKusa2* this) { + static s8 D_80A5EB4C = 0; + s32 pad; + Vec3f sp40; + s16 sp3E; + s16 sp3C; + f32 sp38; + s16 sp36; + f32 temp_f0; + + sp40.x = this->actor.world.pos.x; + sp40.y = this->actor.world.pos.y + 20.0f; + sp40.z = this->actor.world.pos.z; + sp3E = Rand_S16Offset(-10000, 20000) + this->actor.world.rot.y; + + if (this->unk_1C0 != NULL) { + sp36 = Actor_YawBetweenActors(&this->actor, &this->unk_1C0->actor); + sp3C = Rand_S16Offset(-4000, 8000) + sp36; + } else { + sp3C = 0; + } + + D_80A5EB4C++; +label: + D_80A5EB4C &= 0x7; + + temp_f0 = Rand_ZeroOne(); + if (D_80A5EB4C == 0) { + sp38 = temp_f0 * 0.70000005f; + } else { + sp38 = SQ(temp_f0) * 0.4f; + } + this->unk_1B8 = func_80A5C104(&D_80A5F1C0, &sp40, (Rand_ZeroOne() * 3.5f) + 4.0f, sp38, sp3E, sp3C); +} + +void func_80A5CCD4(EnKusa2* this) { + if (this->unk_1B8 != NULL) { + EnKusa2UnkBssSubStruct* ptr = this->unk_1B8; + + ptr->unk_00.x = this->actor.world.pos.x; + ptr->unk_00.y = this->actor.world.pos.y + 20.0f; + ptr->unk_00.z = this->actor.world.pos.z; + } +} + +void func_80A5CD0C(EnKusa2* this) { + s32 i; + Vec3f spA8; + Vec3f sp9C; + Vec3s sp94; + Vec3s sp8C; + f32 temp_f20; + s16 temp_s0; + s32 pad; + + for (i = 0; i < 2; i++) { + temp_s0 = (u32)Rand_Next() & 0xFFFF; + temp_f20 = Rand_ZeroOne() * 30.0f; + + spA8.x = Math_SinS(temp_s0) * temp_f20; + spA8.y = Rand_ZeroOne() * 30.0f; + spA8.z = Math_CosS(temp_s0) * temp_f20; + + sp9C.x = ((Rand_ZeroOne() * 4.0f) - 2.0f) + (spA8.x * 0.18f); + sp9C.y = (Rand_ZeroOne() * 8.0f) + 3.0f; + sp9C.z = ((Rand_ZeroOne() * 4.0f) - 2.0f) + (spA8.z * 0.18f); + + spA8.x += this->actor.world.pos.x; + spA8.y += this->actor.world.pos.y; + spA8.z += this->actor.world.pos.z; + + sp94.x = (u32)Rand_Next() & 0xFFFF; + sp94.y = (u32)Rand_Next() & 0xFFFF; + sp94.z = (u32)Rand_Next() & 0xFFFF; + + sp8C.x = ((u32)Rand_Next() % 0x4000) - 0x1FFF; + sp8C.y = ((u32)Rand_Next() % 0x2000) - 0xFFF; + sp8C.z = ((u32)Rand_Next() % 0x4000) - 0x1FFF; + + func_80A5C2FC(&D_80A5F1C0, (Rand_ZeroOne() * 0.4f) + 0.02f, &spA8, &sp9C, &sp94, &sp8C); + } +} + +void func_80A5CF44(EnKusa2* this) { + s32 i; + Vec3f spA8; + Vec3f sp9C; + Vec3s sp94; + Vec3s sp8C; + f32 temp_f20; + s16 temp_s0; + s32 phi_s2; + + for (i = 0, phi_s2 = 0; i < 8; i++, phi_s2 += 0x2000) { + temp_s0 = ((u32)Rand_Next() % 0x2000) + phi_s2; + temp_f20 = Rand_ZeroOne() * 30.0f; + + spA8.x = Math_SinS(temp_s0) * temp_f20; + spA8.y = Rand_ZeroOne() * 30.0f; + spA8.z = Math_CosS(temp_s0) * temp_f20; + + sp9C.x = ((Rand_ZeroOne() * 6.0f) - 3.0f) + (spA8.x * 0.19f); + sp9C.y = (Rand_ZeroOne() * 9.0f) + 3.0f; + sp9C.z = ((Rand_ZeroOne() * 6.0f) - 3.0f) + (spA8.z * 0.19f); + + spA8.x += this->actor.world.pos.x; + spA8.y += this->actor.world.pos.y; + spA8.z += this->actor.world.pos.z; + + sp94.x = Rand_Next() & 0xFFFF; + sp94.y = Rand_Next() & 0xFFFF; + sp94.z = Rand_Next() & 0xFFFF; + + sp8C.x = ((u32)Rand_Next() % 0x4000) - 0x1FFF; + sp8C.y = ((u32)Rand_Next() % 0x2000) - 0xFFF; + sp8C.z = ((u32)Rand_Next() % 0x4000) - 0x1FFF; + + func_80A5C2FC(&D_80A5F1C0, (Rand_ZeroOne() * 0.45f) + 0.04f, &spA8, &sp9C, &sp94, &sp8C); + } +} + +void func_80A5D178(EnKusa2* this) { + s32 i; + Vec3f spB0; + Vec3f spA4; + Vec3s sp9C; + Vec3s sp94; + f32 temp_f20; + f32 temp_f22; + f32 temp_f24; + s16 temp_s0; + s32 pad; + + for (i = 0; i < 8; i++) { + temp_s0 = (u32)Rand_Next(); + temp_f22 = Math_SinS(temp_s0); + temp_f20 = Math_CosS(temp_s0); + temp_f24 = (Rand_ZeroOne() * 40.0f) + 10.0f; + + spB0.x = temp_f24 * temp_f22; + spB0.y = Rand_ZeroOne() * 30.0f; + spB0.z = temp_f24 * temp_f20; + + spA4.x = ((Rand_ZeroOne() * 6.0f) - 3.0f) + ((temp_f20 * 6.0f) + (spB0.x * 0.1f)); + spA4.y = (Rand_ZeroOne() * 3.0f) + 1.0f; + spA4.z = ((Rand_ZeroOne() * 6.0f) - 3.0f) + ((temp_f22 * -6.0f) + (spB0.z * 0.1f)); + + spB0.x += this->actor.world.pos.x; + spB0.y += this->actor.world.pos.y; + spB0.z += this->actor.world.pos.z; + + sp9C.x = (u32)Rand_Next() & 0xFFFF; + sp9C.y = (u32)Rand_Next() & 0xFFFF; + sp9C.z = (u32)Rand_Next() & 0xFFFF; + + sp94.x = Rand_S16Offset(-12000, 24000); + sp94.y = ((u32)Rand_Next() % 0x4000) - 0x1FFF; + sp94.z = Rand_S16Offset(-12000, 24000); + func_80A5C2FC(&D_80A5F1C0, (Rand_ZeroOne() * 0.38f) + 0.02f, &spB0, &spA4, &sp9C, &sp94); + } +} + +static InitChainEntry sInitChain[] = { + ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(minVelocityY, -17000, ICHAIN_CONTINUE), + ICHAIN_VEC3F_DIV1000(scale, 400, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 1200, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_STOP), }; -#endif +void EnKusa2_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnKusa2* this = THIS; -extern ColliderCylinderInit D_80A5EAC0; -extern InitChainEntry D_80A5EB50[]; + Actor_ProcessInitChain(&this->actor, sInitChain); + if (!ENKUSA2_GET_1(&this->actor)) { + this->actor.update = func_80A5E604; + this->actor.draw = NULL; + this->actor.flags |= 0x20; + func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, 1); + this->unk_1BE = 0; + if (D_80A5EAEC != 0) { + D_80A5EAEC = 0; + D_80A60900 = globalCtx->gameplayFrames; + func_80A5CAD4(&D_80A5F1C0); + D_80A60B08 = (u32)Rand_Next() >> 0x10; + D_80A60B0A = (u32)Rand_Next() >> 0x10; + D_80A60B0C = (u32)Rand_Next() >> 0x10; + D_80A60B0E = (u32)Rand_Next() >> 0x10; + D_80A60B10 = (u32)Rand_Next() >> 0x10; + func_80A5B508(); + } + func_80A5D5E0(this); + } else { + Collider_InitCylinder(globalCtx, &this->collider); + if (!func_80A5BA58(this, globalCtx)) { + Actor_MarkForDeath(&this->actor); + } else { + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + Collider_UpdateCylinder(&this->actor, &this->collider); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->unk_1CE = D_80A5EAF0 & 7; + D_80A5EAF0++; + this->actor.shape.shadowAlpha = 0; + this->unk_1CF = 255; + this->actor.shape.shadowScale = 1.0f; + func_80A5D7A4(this); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5B160.s") +void EnKusa2_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnKusa2* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5B334.s") + if (ENKUSA2_GET_1(&this->actor) == 1) { + Collider_DestroyCylinder(globalCtx, &this->collider); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5B3BC.s") +void func_80A5D5E0(EnKusa2* this) { + this->actionFunc = func_80A5D5F4; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5B490.s") +void func_80A5D5F4(EnKusa2* this, GlobalContext* globalCtx) { + func_80A5D618(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5B508.s") +void func_80A5D618(EnKusa2* this) { + this->actionFunc = func_80A5D62C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5B954.s") +void func_80A5D62C(EnKusa2* this, GlobalContext* globalCtx) { + if (this->unk_1BE != 0) { + func_80A5B490(this, globalCtx); + func_80A5D754(this); + } else if (Math3D_XZLengthSquared(this->actor.projectedPos.x, this->actor.projectedPos.z) < SQ(1600.0f)) { + func_80A5B160(this, globalCtx); + func_80A5D6B0(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5BA58.s") +void func_80A5D6B0(EnKusa2* this) { + this->actionFunc = func_80A5D6C4; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5BAFC.s") +void func_80A5D6C4(EnKusa2* this, GlobalContext* globalCtx) { + func_80A5B3BC(this); + if (this->unk_1BE != 0) { + func_80A5B490(this, globalCtx); + func_80A5D754(this); + } else if (Math3D_XZLengthSquared(this->actor.projectedPos.x, this->actor.projectedPos.z) > SQ(1750.0f)) { + func_80A5B334(this, globalCtx); + func_80A5D618(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5BB40.s") +void func_80A5D754(EnKusa2* this) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5BD14.s") + for (i = 0; i < ARRAY_COUNT(this->unk_194); i++) { + this->unk_194[i] = NULL; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5BD94.s") + this->actionFunc = func_80A5D794; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5BDB0.s") +void func_80A5D794(EnKusa2* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5BF38.s") +void func_80A5D7A4(EnKusa2* this) { + this->actor.draw = EnKusa2_Draw; + this->actionFunc = func_80A5D7C4; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5BF60.s") +void func_80A5D7C4(EnKusa2* this, GlobalContext* globalCtx) { + EnKusa2* this2 = this; + s16 sp2A; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5BF84.s") + if (Actor_HasParent(&this->actor, globalCtx)) { + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, NA_SE_PL_PULL_UP_PLANT); + this->actor.shape.shadowDraw = func_800B3FC0; + this->actor.shape.shadowAlpha = 60; + this->actor.room = -1; + func_80A5BD94(this); + func_80A5D964(this); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5BFD8.s") + if (!func_80A5BFD8(this, globalCtx)) { + if ((this->unk_1C0 != NULL) && (this->unk_1C0->unk_1BE != 0)) { + this->actor.shape.shadowDraw = func_800B3FC0; + if (this2->unk_1C0 != NULL) { + sp2A = Actor_YawBetweenActors(&this->unk_1C0->actor, &this->actor); + this->actor.home.rot.y = Rand_S16Offset(-1500, 3000) + sp2A; + } + this->unk_1C8 = Rand_S16Offset(72, 16); + this->actor.velocity.y = 8.8f; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_WALK); + func_80A5DC70(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5C074.s") + if (this->actor.xzDistToPlayer < 600.0f) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + if (this->actor.xzDistToPlayer < 400.0f) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + if (this->actor.xzDistToPlayer < 100.0f) { + func_800B8BB0(&this->actor, globalCtx); + } + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5C0B8.s") +void func_80A5D964(EnKusa2* this) { + this->actor.draw = func_80A5E9B4; + this->actionFunc = func_80A5D9C8; + D_80A5EAF4.x = 0; + D_80A5EAF4.y = 0; + D_80A5EAF4.z = 0; + D_80A5EAFC.x = 0; + D_80A5EAFC.y = 0; + D_80A5EAFC.z = 0; + D_80A5EB04.x = 0; + D_80A5EB04.y = 0; + D_80A5EB04.z = 0; + this->unk_1D0 = 30; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5C104.s") +void func_80A5D9C8(EnKusa2* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp30; + s32 sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5C2FC.s") + D_80A5EAF4.x += 11000; + D_80A5EAF4.y += 17000; + D_80A5EAF4.z += 9000; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5C410.s") + this->actor.scale.x = (Math_SinS(D_80A5EAF4.x) * 0.020000001f) + 0.4f; + this->actor.scale.y = (Math_SinS(D_80A5EAF4.y) * 0.020000001f) + 0.4f; + this->actor.scale.z = (Math_SinS(D_80A5EAF4.z) * 0.020000001f) + 0.4f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5C70C.s") + D_80A5EB04.x += 18000; + D_80A5EB04.y += 17000; + D_80A5EB04.z += 16000; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5C718.s") + D_80A5EAFC.x = Math_SinS(D_80A5EB04.x) * 1000.0f; + D_80A5EAFC.y = Math_SinS(D_80A5EB04.y) * 1000.0f; + D_80A5EAFC.z = Math_SinS(D_80A5EB04.z) * 1000.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5C7F0.s") + if (Actor_HasNoParent(&this->actor, globalCtx)) { + this->actor.room = globalCtx->roomCtx.currRoom.num; + this->actor.colChkInfo.mass = 80; + this->actor.home.rot.y = this->actor.world.rot.y; + this->actor.velocity.y = 12.5f; + this->actor.speedXZ += 3.0f; + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + func_80A5BAFC(this, globalCtx); + func_80A5CD0C(this); + this->unk_1C8 = 30; + func_80A5DC70(this); + } else { + sp30.x = this->actor.world.pos.x; + sp30.y = this->actor.world.pos.y + 20.0f; + sp30.z = this->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5C918.s") + if ((u32)Rand_Next() < 0xFFFFFFF) { + func_80A5CD0C(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5CAD4.s") + this->unk_1D0--; + if (this->unk_1D0 <= 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KUSAMUSHI_VIBE); + this->unk_1D0 = ((u32)Rand_Next() >> 0x1D) + 14; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5CAF4.s") + this->actor.floorHeight = + BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &sp2C, &this->actor, &sp30); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5CB74.s") +void func_80A5DC70(EnKusa2* this) { + this->actionFunc = func_80A5DC98; + this->actor.draw = func_80A5EA48; + this->unk_1CA = 80; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5CCD4.s") +void func_80A5DC98(EnKusa2* this, GlobalContext* globalCtx) { + if (!func_80A5BFD8(this, globalCtx)) { + if (this->actor.velocity.y > 1.0f) { + Math_StepToF(&this->actor.scale.y, 0.3f, 0.060000002f); + Math_StepToF(&this->actor.scale.x, 0.328f, 0.040000003f); + } else { + Math_StepToF(&this->actor.scale.y, 0.48000002f, 0.080000006f); + Math_StepToF(&this->actor.scale.x, 0.28f, 0.032f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5CD0C.s") + this->actor.scale.z = this->actor.scale.x; + Math_StepToF(&this->actor.gravity, -7.0f, 1.8f); + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + func_80A5BAFC(this, globalCtx); + func_80A5BF38(this, 4); + func_80A5BF84(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5CF44.s") + if (this->actor.bgCheckFlags & 1) { + func_80A5CD0C(this); + func_80A5BB40(this, globalCtx, 1); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_NUTS_WALK); + func_80A5DE18(this); + } else if (this->actor.bgCheckFlags & 0x20) { + func_80A5BDB0(this, globalCtx); + func_80A5E418(this); + } else if (this->unk_1CA > 0) { + this->unk_1CA--; + } else { + Actor_MarkForDeath(&this->actor); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D178.s") +void func_80A5DE18(EnKusa2* this) { + this->actionFunc = func_80A5DEB4; + this->actor.draw = func_80A5EA48; + this->actor.gravity = -2.0f; + this->unk_1D0 = (s32)(Rand_ZeroOne() * 3.0f); + this->unk_1D1 = (s32)(Rand_ZeroOne() * 8.0f) + 7; + this->unk_1CA = Rand_S16Offset(19, 2); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/EnKusa2_Init.s") +void func_80A5DEB4(EnKusa2* this, GlobalContext* globalCtx) { + s32 pad; + s32 pad2; + s16 sp24; + s32 sp20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/EnKusa2_Destroy.s") + if (!func_80A5BFD8(this, globalCtx)) { + if (this->unk_1D0 > 0) { + this->unk_1D0--; + if (this->unk_1D0 == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KUSAMUSHI_VIBE); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D5E0.s") + if (this->unk_1D1 > 0) { + this->unk_1D1--; + if (this->unk_1D1 == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KUSAMUSHI_VIBE); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D5F4.s") + Math_StepToF(&this->actor.scale.y, 0.4f, 0.032f); + Math_StepToF(&this->actor.scale.x, 0.4f, 0.032f); + this->unk_1C4 += 0x4650; + this->actor.scale.z = this->actor.scale.x; + this->actor.speedXZ = fabsf(Math_CosS(this->unk_1C4) + 0.5f) * 1.5f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D618.s") + if (this->actor.speedXZ < 0.0f) { + this->actor.speedXZ = 0.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D62C.s") + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D6B0.s") + this->actor.world.rot.y = (s32)(Math_SinS(this->unk_1C4) * 3000.0f) + this->actor.home.rot.y; + this->actor.shape.rot.y = this->actor.world.rot.y; + this->actor.shape.rot.x = (s32)(fabsf(Math_SinS(this->unk_1C4)) * 4000.0f) - 0x6A4; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D6C4.s") + func_80A5BAFC(this, globalCtx); + func_80A5BF38(this, 4); + func_80A5BF84(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D754.s") + if ((u32)Rand_Next() < 0xFFFFFFF) { + func_80A5CD0C(this); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D794.s") + if (this->actor.bgCheckFlags & 0x20) { + func_80A5BDB0(this, globalCtx); + func_80A5E418(this); + } else { + this->unk_1C8--; + if (this->unk_1C8 <= 0) { + func_80A5CD0C(this); + func_80A5BB40(this, globalCtx, 4); + this->actor.speedXZ += 4.0f; + this->actor.velocity.y = (Rand_ZeroOne() * 4.0f) + 15.0f; + func_80A5E1D8(this); + } else if (this->actor.bgCheckFlags & 1) { + this->unk_1CA--; + if (this->unk_1CA <= 0) { + func_80A5CD0C(this); + func_80A5BB40(this, globalCtx, 2); + this->actor.velocity.y = (Rand_ZeroOne() * 6.0f) + 7.0f; + this->actor.speedXZ += 2.0f; + if (this->actor.yawTowardsPlayer < this->actor.world.rot.y) { + sp20 = 10000; + } else { + sp20 = -10000; + } + sp24 = sp20 + Rand_S16Offset(-3000, 6000); + this->actor.home.rot.y += sp24; + this->actor.world.rot.y = this->actor.home.rot.y; + func_80A5DC70(this); + } + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D7A4.s") +void func_80A5E1D8(EnKusa2* this) { + this->actionFunc = func_80A5E210; + this->actor.draw = func_80A5EA48; + this->unk_1CC = 0; + func_80A5CB74(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D7C4.s") +void func_80A5E210(EnKusa2* this, GlobalContext* globalCtx) { + Math_StepToF(&this->actor.gravity, -4.0f, 0.5f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D964.s") + if (this->actor.bgCheckFlags & 1) { + this->actor.speedXZ *= 0.4f; + if (this->actor.bgCheckFlags & 2) { + func_80A5D178(this); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_KUSAMUSHI_HIDE); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5D9C8.s") + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + func_80A5BAFC(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5DC70.s") + if (this->actor.velocity.y > 0.01f) { + func_80A5BF38(this, 4); + this->unk_1CC += 1000; + } else { + func_80A5BF60(this, 10); + this->unk_1CF -= 20; + this->unk_1CC += 5000; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5DC98.s") + if (this->unk_1CC > 20000) { + this->unk_1CC = 20000; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5DE18.s") + this->actor.shape.rot.y += this->unk_1CC; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5DEB4.s") + if (this->actor.velocity.y > 1.0f) { + Math_StepToF(&this->actor.scale.y, 0.24000001f, 0.080000006f); + Math_StepToF(&this->actor.scale.x, 0.32000002f, 0.040000003f); + } else if (this->actor.bgCheckFlags & 1) { + Math_StepToF(&this->actor.scale.y, 0.0f, 0.120000005f); + Math_StepToF(&this->actor.scale.x, 0.48000002f, 0.120000005f); + } else { + Math_StepToF(&this->actor.scale.y, 0.56f, 0.1f); + Math_StepToF(&this->actor.scale.x, 0.24000001f, 0.1f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5E1D8.s") + this->actor.scale.z = this->actor.scale.x; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5E210.s") + if (this->unk_1CF <= 20) { + if (this->unk_1B8 != NULL) { + this->unk_1B8->unk_28 = func_80A5C718; + } + Actor_MarkForDeath(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5E418.s") +void func_80A5E418(EnKusa2* this) { + this->actor.minVelocityY = -4.0f; + this->actor.velocity.x *= 0.1f; + this->actor.velocity.y *= 0.25f; + this->actor.velocity.z *= 0.1f; + this->actor.draw = func_80A5EA48; + this->actor.speedXZ *= 0.1f; + this->actor.gravity *= 0.25f; + this->unk_1CC = Rand_S16Offset(-800, 1600); + this->actionFunc = func_80A5E4BC; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5E4BC.s") +void func_80A5E4BC(EnKusa2* this, GlobalContext* globalCtx) { + Math_StepToF(&this->actor.scale.y, 0.4f, 0.032f); + Math_StepToF(&this->actor.scale.x, 0.4f, 0.032f); + this->actor.scale.z = this->actor.scale.x; + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + func_80A5BAFC(this, globalCtx); + func_80A5BF60(this, 6); + this->actor.shape.rot.x -= 0x5DC; + this->actor.shape.rot.y += this->unk_1CC; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5E604.s") + if ((this->actor.bgCheckFlags & 0x20) && (this->actor.depthInWater > 5.0f) && (Rand_ZeroOne() < 0.8f)) { + EffectSsBubble_Spawn(globalCtx, &this->actor.world.pos, 20.0f, 10.0f, 20.0f, (Rand_ZeroOne() * 0.08f) + 0.04f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/EnKusa2_Update.s") + this->unk_1CF -= 15; + if (this->unk_1CF <= 15) { + Actor_MarkForDeath(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5E6F0.s") +void func_80A5E604(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnKusa2* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5E80C.s") + this->actionFunc(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/EnKusa2_Draw.s") + if (D_80A60900 == globalCtx->gameplayFrames) { + this->actor.draw = NULL; + } else { + this->actor.draw = func_80A5E6F0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5E9B4.s") + if (globalCtx->roomCtx.currRoom.unk3 == 0) { + func_80A5B508(); + } + func_80A5CAF4(&D_80A5F1C0); + D_80A60900 = globalCtx->gameplayFrames; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Kusa2/func_80A5EA48.s") +void EnKusa2_Update(Actor* thisx, GlobalContext* globalCtx) { + EnKusa2* this = THIS; + + if ((this->unk_1C0 != NULL) && (this->unk_1C0->actor.update == NULL)) { + this->unk_1C0 = NULL; + } + + this->actionFunc(this, globalCtx); + + func_80A5CCD4(this); +} + +void func_80A5E6F0(Actor* thisx, GlobalContext* globalCtx) { + static Gfx* D_80A5EB68[] = { + D_040528B0, + D_040527F0, + }; + EnKusa2* this = THIS; + s32 i; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + for (i = 0; i < ARRAY_COUNT(D_80A5F1C0.unk_0480); i++) { + EnKusa2UnkBssSubStruct2* s = &D_80A5F1C0.unk_0480[i]; + + if (s->unk_2C > 0) { + Matrix_SetStateRotationAndTranslation(s->unk_04.x, s->unk_04.y, s->unk_04.z, &s->unk_20); + Matrix_Scale(s->unk_00, s->unk_00, s->unk_00, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, D_80A5EB68[i & 1]); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80A5E80C(GlobalContext* globalCtx, s32 arg1) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, arg1); + gSPDisplayList(POLY_XLU_DISP++, D_05007938); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnKusa2_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnKusa2* this = THIS; + + if (this->actor.projectedPos.z <= 1200.0f) { + if ((globalCtx->roomCtx.currRoom.unk3 == 0) && (this->actor.projectedPos.z > -150.0f) && + (this->actor.projectedPos.z < 400.0f)) { + func_80A5B954(&D_80A60908[this->unk_1CE], 0.0015f); + } + func_800BDFC0(globalCtx, D_050078A0); + } else if (this->actor.projectedPos.z < 1300.0f) { + func_80A5E80C(globalCtx, (1300.0f - this->actor.projectedPos.z) * 2.55f); + } +} + +void func_80A5E9B4(Actor* thisx, GlobalContext* globalCtx) { + Vec3s sp18; + + sp18.x = thisx->shape.rot.x + D_80A5EAFC.x; + sp18.y = thisx->shape.rot.y + D_80A5EAFC.y; + sp18.z = thisx->shape.rot.z + D_80A5EAFC.z; + Matrix_SetStateRotationAndTranslation(thisx->world.pos.x, thisx->world.pos.y, thisx->world.pos.z, &sp18); + Matrix_Scale(thisx->scale.x, thisx->scale.y, thisx->scale.z, MTXMODE_APPLY); + func_800BDFC0(globalCtx, D_050078A0); +} + +void func_80A5EA48(Actor* thisx, GlobalContext* globalCtx) { + EnKusa2* this = THIS; + + if (this->unk_1CF == 0xFF) { + func_800BDFC0(globalCtx, D_050078A0); + } else { + func_80A5E80C(globalCtx, this->unk_1CF); + } +} diff --git a/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.h b/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.h index 409c0c813..f18c1a6a7 100644 --- a/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.h +++ b/src/overlays/actors/ovl_En_Kusa2/z_en_kusa2.h @@ -4,14 +4,81 @@ #include "global.h" struct EnKusa2; +struct EnKusa2UnkBssSubStruct; typedef void (*EnKusa2ActionFunc)(struct EnKusa2*, GlobalContext*); +typedef void (*EnKusa2BssFunc)(struct EnKusa2UnkBssSubStruct*); + +#define ENKUSA2_GET_1(thisx) (((thisx)->params) & 1) +#define ENKUSA2_GET_7F00(thisx) (u8)((((thisx)->params) >> 8) & 0x7F) + +typedef struct EnKusa2UnkBssSubStruct { + /* 0x00 */ Vec3f unk_00; + /* 0x0C */ Vec3f unk_0C; + /* 0x18 */ f32 unk_18; + /* 0x1C */ f32 unk_1C; + /* 0x20 */ s16 unk_20; + /* 0x22 */ s16 unk_22; + /* 0x24 */ s16 unk_24; + /* 0x26 */ s16 unk_26; + /* 0x28 */ EnKusa2BssFunc unk_28; + /* 0x2C */ f32 unk_2C; + /* 0x30 */ f32 unk_30; + /* 0x34 */ f32 unk_34; + /* 0x38 */ f32 unk_38; + /* 0x3C */ f32 unk_3C; + /* 0x40 */ f32 unk_40; + /* 0x44 */ f32 unk_44; + /* 0x48 */ f32 unk_48; + /* 0x4C */ f32 unk_4C; + /* 0x50 */ f32 unk_50; + /* 0x54 */ f32 unk_54; + /* 0x58 */ f32 unk_58; + /* 0x5C */ f32 unk_5C; + /* 0x60 */ f32 unk_60; + /* 0x64 */ f32 unk_64; + /* 0x68 */ f32 unk_68; + /* 0x6C */ f32 unk_6C; + /* 0x70 */ f32 unk_70; + /* 0x74 */ f32 unk_74; + /* 0x78 */ f32 unk_78; + /* 0x7C */ f32 unk_7C; +} EnKusa2UnkBssSubStruct; // size = 0x80 + +typedef struct { + /* 0x00 */ f32 unk_00; + /* 0x04 */ Vec3f unk_04; + /* 0x10 */ Vec3f unk_10; + /* 0x1C */ f32 unk_1C; + /* 0x20 */ Vec3s unk_20; + /* 0x26 */ Vec3s unk_26; + /* 0x2C */ s16 unk_2C; + /* 0x2C */ UNK_TYPE1 unk2E[0x2]; +} EnKusa2UnkBssSubStruct2; // size = 0x30 + +typedef struct { + /* 0x0000 */ EnKusa2UnkBssSubStruct unk_0000[9]; + /* 0x0480 */ EnKusa2UnkBssSubStruct2 unk_0480[100]; +} EnKusa2UnkBssStruct; // size = 0x1740 typedef struct EnKusa2 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x4C]; + /* 0x0144 */ ColliderCylinder collider; /* 0x0190 */ EnKusa2ActionFunc actionFunc; - /* 0x0194 */ char unk_194[0x40]; + /* 0x0194 */ struct EnKusa2* unk_194[9]; + /* 0x01B8 */ EnKusa2UnkBssSubStruct* unk_1B8; + /* 0x01BC */ s16 unk_1BC; + /* 0x01BE */ s8 unk_1BE; + /* 0x01C0 */ struct EnKusa2* unk_1C0; + /* 0x01C4 */ s16 unk_1C4; + /* 0x01C6 */ UNK_TYPE1 unk1C6[0x2]; + /* 0x01C8 */ s16 unk_1C8; + /* 0x01CA */ s16 unk_1CA; + /* 0x01CC */ s16 unk_1CC; + /* 0x01CE */ s8 unk_1CE; + /* 0x01CF */ u8 unk_1CF; + /* 0x01D0 */ s8 unk_1D0; + /* 0x01D1 */ s8 unk_1D1; } EnKusa2; // size = 0x1D4 extern const ActorInit En_Kusa2_InitVars; diff --git a/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.c b/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.c index 395dcbeed..4a21cdefd 100644 --- a/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.c +++ b/src/overlays/actors/ovl_En_M_Thunder/z_en_m_thunder.c @@ -1,7 +1,7 @@ /* * File: z_en_m_thunder.c * Overlay: ovl_En_M_Thunder - * Description: Spin attack effect + * Description: Spin attack and sword beams */ #include "z_en_m_thunder.h" diff --git a/src/overlays/actors/ovl_En_Ma_Yto/z_en_ma_yto.c b/src/overlays/actors/ovl_En_Ma_Yto/z_en_ma_yto.c index d89ed4582..6b55a48a7 100644 --- a/src/overlays/actors/ovl_En_Ma_Yto/z_en_ma_yto.c +++ b/src/overlays/actors/ovl_En_Ma_Yto/z_en_ma_yto.c @@ -1140,7 +1140,7 @@ void EnMaYto_DefaultStartDialogue(EnMaYto* this, GlobalContext* globalCtx) { this->textId = 0x235E; break; - case PLAYER_MASK_KAFEI: + case PLAYER_MASK_KAFEIS_MASK: EnMaYto_SetFaceExpression(this, 1, 2); func_801518B0(globalCtx, 0x235F, &this->actor); this->textId = 0x235F; @@ -1198,7 +1198,7 @@ void EnMaYto_DinnerStartDialogue(EnMaYto* this, GlobalContext* globalCtx) { this->textId = 0x235E; break; - case PLAYER_MASK_KAFEI: + case PLAYER_MASK_KAFEIS_MASK: func_801518B0(globalCtx, 0x235F, &this->actor); this->textId = 0x235F; break; diff --git a/src/overlays/actors/ovl_En_Maruta/z_en_maruta.h b/src/overlays/actors/ovl_En_Maruta/z_en_maruta.h index 4ed2d7f6e..df53fbe49 100644 --- a/src/overlays/actors/ovl_En_Maruta/z_en_maruta.h +++ b/src/overlays/actors/ovl_En_Maruta/z_en_maruta.h @@ -10,7 +10,7 @@ typedef void (*EnMarutaActionFunc)(struct EnMaruta*, GlobalContext*); typedef struct EnMaruta { /* 0x0000 */ Actor actor; /* 0x0144 */ EnMarutaActionFunc actionFunc; - /* 0x0148 */ char unk_144[0xDC]; + /* 0x0148 */ char unk_148[0xDC]; } EnMaruta; // size = 0x224 extern const ActorInit En_Maruta_InitVars; diff --git a/src/overlays/actors/ovl_En_Minideath/z_en_minideath.c b/src/overlays/actors/ovl_En_Minideath/z_en_minideath.c index eb3a02eb3..6750c81da 100644 --- a/src/overlays/actors/ovl_En_Minideath/z_en_minideath.c +++ b/src/overlays/actors/ovl_En_Minideath/z_en_minideath.c @@ -1,7 +1,7 @@ /* * File: z_en_minideath.c * Overlay: ovl_En_Minideath - * Description: Bats Surrounding Gomess? + * Description: Gomess's bats */ #include "z_en_minideath.h" diff --git a/src/overlays/actors/ovl_En_Minideath/z_en_minideath.h b/src/overlays/actors/ovl_En_Minideath/z_en_minideath.h index 854589854..7ac4dee6c 100644 --- a/src/overlays/actors/ovl_En_Minideath/z_en_minideath.h +++ b/src/overlays/actors/ovl_En_Minideath/z_en_minideath.h @@ -10,7 +10,7 @@ typedef void (*EnMinideathActionFunc)(struct EnMinideath*, GlobalContext*); typedef struct EnMinideath { /* 0x0000 */ Actor actor; /* 0x0144 */ EnMinideathActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x164]; + /* 0x0148 */ char unk_148[0x164]; } EnMinideath; // size = 0x2AC extern const ActorInit En_Minideath_InitVars; diff --git a/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c b/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c index 9095d702b..4b5585086 100644 --- a/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c +++ b/src/overlays/actors/ovl_En_Minifrog/z_en_minifrog.c @@ -622,7 +622,7 @@ void EnMinifrog_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLis if ((limbIndex == 7) || (limbIndex == 8)) { OPEN_DISPS(globalCtx->state.gfxCtx); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, *dList); CLOSE_DISPS(globalCtx->state.gfxCtx); diff --git a/src/overlays/actors/ovl_En_Minislime/z_en_minislime.c b/src/overlays/actors/ovl_En_Minislime/z_en_minislime.c index 831e6a4b9..bb7fd235e 100644 --- a/src/overlays/actors/ovl_En_Minislime/z_en_minislime.c +++ b/src/overlays/actors/ovl_En_Minislime/z_en_minislime.c @@ -215,7 +215,7 @@ void EnMinislime_AddIceSmokeEffect(EnMinislime* this, GlobalContext* globalCtx) vel.x = randPlusMinusPoint5Scaled(1.5f); vel.z = randPlusMinusPoint5Scaled(1.5f); vel.y = 2.0f; - EffectSsIceSmoke_Spawn(globalCtx, &pos, &vel, &D_801D15B0, 500); + EffectSsIceSmoke_Spawn(globalCtx, &pos, &vel, &gZeroVec3f, 500); } void EnMinislime_SetupDisappear(EnMinislime* this) { diff --git a/src/overlays/actors/ovl_En_Mkk/z_en_mkk.c b/src/overlays/actors/ovl_En_Mkk/z_en_mkk.c index 73e2fc62d..1bedf7901 100644 --- a/src/overlays/actors/ovl_En_Mkk/z_en_mkk.c +++ b/src/overlays/actors/ovl_En_Mkk/z_en_mkk.c @@ -1,7 +1,7 @@ /* * File: z_en_mkk.c * Overlay: ovl_En_Mkk - * Description: Makkurokurosuke / Black and White Boe + * Description: Black and White Boe (Name origin: Makkurokurosuke) */ #include "z_en_mkk.h" diff --git a/src/overlays/actors/ovl_En_Mkk/z_en_mkk.h b/src/overlays/actors/ovl_En_Mkk/z_en_mkk.h index 0bc603748..c80fc7a20 100644 --- a/src/overlays/actors/ovl_En_Mkk/z_en_mkk.h +++ b/src/overlays/actors/ovl_En_Mkk/z_en_mkk.h @@ -10,7 +10,7 @@ typedef void (*EnMkkActionFunc)(struct EnMkk*, GlobalContext*); typedef struct EnMkk { /* 0x0000 */ Actor actor; /* 0x0144 */ EnMkkActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x8C]; + /* 0x0148 */ char unk_148[0x8C]; } EnMkk; // size = 0x1D4 extern const ActorInit En_Mkk_InitVars; diff --git a/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c b/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c index 69823ad0e..4bc8d8378 100644 --- a/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c +++ b/src/overlays/actors/ovl_En_Mm2/z_en_mm2.c @@ -15,10 +15,9 @@ void EnMm2_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnMm2_Update(Actor* thisx, GlobalContext* globalCtx); void EnMm2_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_809A2080(EnMm2* this, GlobalContext* globalCtx); -void func_809A20FC(EnMm2* this, GlobalContext* globalCtx); +void EnMm2_Reading(EnMm2* this, GlobalContext* globalCtx); +void EnMm2_WaitForRead(EnMm2* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Mm2_InitVars = { ACTOR_EN_MM2, ACTORCAT_ITEMACTION, @@ -31,16 +30,59 @@ const ActorInit En_Mm2_InitVars = { (ActorFunc)EnMm2_Draw, }; -#endif +#include "overlays/ovl_En_Mm2/ovl_En_Mm2.c" -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm2/EnMm2_Init.s") +void EnMm2_Init(Actor* thisx, GlobalContext* globalCtx) { + EnMm2* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm2/EnMm2_Destroy.s") + Actor_SetScale(&this->actor, 0.015f); + this->actionFunc = EnMm2_WaitForRead; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm2/func_809A2080.s") +void EnMm2_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm2/func_809A20FC.s") +/** + * Action function whilst Link is reading the letter. + */ +void EnMm2_Reading(EnMm2* this, GlobalContext* globalCtx) { + u8 talkState = func_80152498(&globalCtx->msgCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm2/EnMm2_Update.s") + if (talkState != 2) { + if (talkState == 5 && func_80147624(globalCtx)) { + func_801477B4(globalCtx); + this->actionFunc = EnMm2_WaitForRead; + } + } else { + this->actionFunc = EnMm2_WaitForRead; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Mm2/EnMm2_Draw.s") +/** + * Action function that awaits Link to read the letter, changing the A button to "Check" when he is within range to do + * so (and facing the letter). + */ +void EnMm2_WaitForRead(EnMm2* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + func_801518B0(globalCtx, 0x277B, &this->actor); + this->actionFunc = EnMm2_Reading; + } else if ((this->actor.xzDistToPlayer < 60.0f) && (Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx))) { + func_800B8614(&this->actor, globalCtx, 110.0f); + } +} + +void EnMm2_Update(Actor* thisx, GlobalContext* globalCtx) { + EnMm2* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void EnMm2_Draw(Actor* thisx, GlobalContext* globalCtx) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, sEnMm2DL); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Ms/z_en_ms.c b/src/overlays/actors/ovl_En_Ms/z_en_ms.c index e9a779376..efc0ea175 100644 --- a/src/overlays/actors/ovl_En_Ms/z_en_ms.c +++ b/src/overlays/actors/ovl_En_Ms/z_en_ms.c @@ -1,7 +1,7 @@ /* * File: z_en_ms.c * Overlay: ovl_En_Ms - * Description: Bean salesman + * Description: Bean Seller */ #include "z_en_ms.h" @@ -15,7 +15,11 @@ void EnMs_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnMs_Update(Actor* thisx, GlobalContext* globalCtx); void EnMs_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void EnMs_Wait(EnMs* this, GlobalContext* globalCtx); +void EnMs_Talk(EnMs* this, GlobalContext* globalCtx); +void EnMs_Sell(EnMs* this, GlobalContext* globalCtx); +void EnMs_TalkAfterPurchase(EnMs* this, GlobalContext* globalCtx); + const ActorInit En_Ms_InitVars = { ACTOR_EN_MS, ACTORCAT_NPC, @@ -28,38 +32,156 @@ const ActorInit En_Ms_InitVars = { (ActorFunc)EnMs_Draw, }; -// static ColliderCylinderInitType1 sCylinderInit = { -static ColliderCylinderInitType1 D_80952BA0 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInitType1 sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 22, 37, 0, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80952BCC[] = { +static InitChainEntry sInitChain[] = { ICHAIN_U8(targetMode, 2, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 500, ICHAIN_STOP), }; -#endif +extern AnimationHeader D_060005EC; +extern FlexSkeletonHeader D_06003DC0; -extern ColliderCylinderInit D_80952BA0; -extern InitChainEntry D_80952BCC[]; +void EnMs_Init(Actor* thisx, GlobalContext* globalCtx) { + EnMs* this = THIS; -extern UNK_TYPE D_060005EC; + Actor_ProcessInitChain(thisx, sInitChain); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06003DC0, &D_060005EC, this->jointTable, this->morphTable, 9); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinderType1(globalCtx, &this->collider, &this->actor, &sCylinderInit); + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 35.0f); + Actor_SetScale(&this->actor, 0.015f); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; // Eating Magic Beans all day will do that to you + this->actionFunc = EnMs_Wait; + this->actor.speedXZ = 0.0f; + this->actor.velocity.y = 0.0f; + this->actor.gravity = -1.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/EnMs_Init.s") +void EnMs_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnMs* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/EnMs_Destroy.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/func_80952734.s") +void EnMs_Wait(EnMs* this, GlobalContext* globalCtx) { + s16 yawDiff = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/func_809527F8.s") + if (gSaveContext.inventory.items[SLOT_MAGIC_BEANS] == ITEM_NONE) { + this->actor.textId = 0x92E; // "[...] You're the first customer [...]" + } else { + this->actor.textId = 0x932; // "[...] So you liked my Magic Beans [...]" + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/func_809529AC.s") + if (func_800B84D0(&this->actor, globalCtx) != 0) { + this->actionFunc = EnMs_Talk; + } else if ((this->actor.xzDistToPlayer < 90.0f) && (ABS_ALT(yawDiff) < 0x2000)) { + func_800B8614(&this->actor, globalCtx, 90.0f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/func_80952A1C.s") +void EnMs_Talk(EnMs* this, GlobalContext* globalCtx) { + switch (func_80152498(&globalCtx->msgCtx)) { + case 6: + if (func_80147624(globalCtx) != 0) { + this->actionFunc = EnMs_Wait; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/EnMs_Update.s") + case 5: + if (func_80147624(globalCtx) != 0) { + func_801477B4(globalCtx); + func_800B8A1C(&this->actor, globalCtx, GI_MAGIC_BEANS, this->actor.xzDistToPlayer, + this->actor.playerHeightRel); + this->actionFunc = EnMs_Sell; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ms/EnMs_Draw.s") + case 4: + if (func_80147624(globalCtx) != 0) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: // yes + func_801477B4(globalCtx); + if (gSaveContext.rupees < 10) { + play_sound(NA_SE_SY_ERROR); + func_80151938(globalCtx, 0x935); // "[...] You don't have enough Rupees." + } else if (AMMO(ITEM_MAGIC_BEANS) >= 20) { + play_sound(NA_SE_SY_ERROR); + func_80151938(globalCtx, 0x937); // "[...] You can't carry anymore." + } else { + func_8019F208(); + func_800B8A1C(&this->actor, globalCtx, GI_MAGIC_BEANS, 90.0f, 10.0f); + func_801159EC(-10); + this->actionFunc = EnMs_Sell; + } + break; + + case 1: // no + default: + func_8019F230(); + func_80151938(globalCtx, 0x934); // "[...] Well, if your mood changes [...]" + break; + } + } + break; + default: + break; + } +} + +void EnMs_Sell(EnMs* this, GlobalContext* globalCtx) { + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.textId = 0; + func_800B8500(&this->actor, globalCtx, this->actor.xzDistToPlayer, this->actor.playerHeightRel, 0); + this->actionFunc = EnMs_TalkAfterPurchase; + } else { + func_800B8A1C(&this->actor, globalCtx, GI_MAGIC_BEANS, this->actor.xzDistToPlayer, this->actor.playerHeightRel); + } +} + +void EnMs_TalkAfterPurchase(EnMs* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + func_80151938(globalCtx, 0x936); // "You can plant 'em whenever you want [...]" + this->actionFunc = EnMs_Talk; + } else { + func_800B8500(&this->actor, globalCtx, this->actor.xzDistToPlayer, this->actor.playerHeightRel, -1); + } +} + +void EnMs_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnMs* this = THIS; + + Actor_SetHeight(&this->actor, 20.0f); + this->actor.targetArrowOffset = 500.0f; + Actor_SetScale(&this->actor, 0.015f); + SkelAnime_Update(&this->skelAnime); + this->actionFunc(this, globalCtx); + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void EnMs_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnMs* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + NULL, NULL, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Ms/z_en_ms.h b/src/overlays/actors/ovl_En_Ms/z_en_ms.h index cfacb7f60..2efbdea45 100644 --- a/src/overlays/actors/ovl_En_Ms/z_en_ms.h +++ b/src/overlays/actors/ovl_En_Ms/z_en_ms.h @@ -8,10 +8,12 @@ struct EnMs; typedef void (*EnMsActionFunc)(struct EnMs*, GlobalContext*); typedef struct EnMs { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xB0]; - /* 0x01F4 */ EnMsActionFunc actionFunc; - /* 0x01F8 */ char unk_1F8[0x4C]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[9]; + /* 0x1BE */ Vec3s morphTable[9]; + /* 0x1F4 */ EnMsActionFunc actionFunc; + /* 0x1F8 */ ColliderCylinder collider; } EnMs; // size = 0x244 extern const ActorInit En_Ms_InitVars; diff --git a/src/overlays/actors/ovl_En_Mt_tag/z_en_mt_tag.c b/src/overlays/actors/ovl_En_Mt_tag/z_en_mt_tag.c index 934e7b427..789f308ca 100644 --- a/src/overlays/actors/ovl_En_Mt_tag/z_en_mt_tag.c +++ b/src/overlays/actors/ovl_En_Mt_tag/z_en_mt_tag.c @@ -1,7 +1,7 @@ /* * File: z_en_mt_tag.c * Overlay: ovl_En_Mt_tag - * Description: + * Description: Controls the Goron Race minigame */ #include "z_en_mt_tag.h" diff --git a/src/overlays/actors/ovl_En_Mt_tag/z_en_mt_tag.h b/src/overlays/actors/ovl_En_Mt_tag/z_en_mt_tag.h index 58c625b36..796482b14 100644 --- a/src/overlays/actors/ovl_En_Mt_tag/z_en_mt_tag.h +++ b/src/overlays/actors/ovl_En_Mt_tag/z_en_mt_tag.h @@ -10,7 +10,7 @@ typedef void (*EnMttagActionFunc)(struct EnMttag*, GlobalContext*); typedef struct EnMttag { /* 0x0000 */ Actor actor; /* 0x0144 */ EnMttagActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x20]; + /* 0x0148 */ char unk_148[0x20]; } EnMttag; // size = 0x168 extern const ActorInit En_Mt_tag_InitVars; diff --git a/src/overlays/actors/ovl_En_Mushi2/z_en_mushi2.c b/src/overlays/actors/ovl_En_Mushi2/z_en_mushi2.c index 0969c123a..70945999f 100644 --- a/src/overlays/actors/ovl_En_Mushi2/z_en_mushi2.c +++ b/src/overlays/actors/ovl_En_Mushi2/z_en_mushi2.c @@ -219,7 +219,7 @@ s32 func_80A68C5C(Vec3f* arg0, Vec3f* arg1) { f32 temp_f0 = Math3D_Vec3fMagnitude(arg0); if (temp_f0 < 0.005f) { - Math_Vec3f_Copy(arg0, &D_801D15B0); + Math_Vec3f_Copy(arg0, &gZeroVec3f); return false; } else { arg1->x = arg0->x * (1.0f / temp_f0); @@ -321,7 +321,7 @@ s32 func_80A68F9C(EnMushi2* this, s16 arg1) { matrix->mf[3][2] = 0.0f; matrix->mf[3][3] = 0.0f; - Matrix_RotateY(arg1, 1); + Matrix_RotateY(arg1, MTXMODE_APPLY); this->unk_310.x = matrix->mf[0][0]; this->unk_310.y = matrix->mf[0][1]; @@ -368,7 +368,7 @@ s32 func_80A690C4(EnMushi2* this, s16 arg1) { matrix->mf[3][2] = 0.0f; matrix->mf[3][3] = 0.0f; - Matrix_InsertXRotation_s(arg1, 1); + Matrix_InsertXRotation_s(arg1, MTXMODE_APPLY); this->unk_310.x = matrix->mf[0][0]; this->unk_310.y = matrix->mf[0][1]; @@ -1095,7 +1095,7 @@ void func_80A6B0D8(EnMushi2* this, GlobalContext* globalCtx) { sp48.x = (this->unk_328.x * -0.6f) + (this->unk_31C.x * 0.1f); sp48.y = (this->unk_328.y * -0.6f) + (this->unk_31C.y * 0.1f); sp48.z = (this->unk_328.z * -0.6f) + (this->unk_31C.z * 0.1f); - func_800B0E48(globalCtx, &this->actor.world.pos, &sp48, &D_801D15B0, &D_80A6B984[sp44], &D_80A6B98C[sp44], + func_800B0E48(globalCtx, &this->actor.world.pos, &sp48, &gZeroVec3f, &D_80A6B984[sp44], &D_80A6B98C[sp44], (Rand_ZeroOne() * 5.0f) + 8.0f, (Rand_ZeroOne() * 5.0f) + 8.0f); } diff --git a/src/overlays/actors/ovl_En_Muto/z_en_muto.c b/src/overlays/actors/ovl_En_Muto/z_en_muto.c index e2fba4608..131fbebcc 100644 --- a/src/overlays/actors/ovl_En_Muto/z_en_muto.c +++ b/src/overlays/actors/ovl_En_Muto/z_en_muto.c @@ -144,7 +144,7 @@ void EnMuto_Idle(EnMuto* this, GlobalContext* globalCtx) { if (1) {} // Needed to match - if (!this->isInMayorsRoom && Player_GetMask(globalCtx) == PLAYER_MASK_KAFEI) { + if (!this->isInMayorsRoom && Player_GetMask(globalCtx) == PLAYER_MASK_KAFEIS_MASK) { this->actor.textId = 0x2363; } diff --git a/src/overlays/actors/ovl_En_Neo_Reeba/z_en_neo_reeba.c b/src/overlays/actors/ovl_En_Neo_Reeba/z_en_neo_reeba.c index 86f477a0f..4c3859efd 100644 --- a/src/overlays/actors/ovl_En_Neo_Reeba/z_en_neo_reeba.c +++ b/src/overlays/actors/ovl_En_Neo_Reeba/z_en_neo_reeba.c @@ -1,7 +1,7 @@ /* * File: z_en_neo_reeba.c * Overlay: ovl_En_Neo_Reeba - * Description: Leevers + * Description: (New) Leevers */ #include "z_en_neo_reeba.h" diff --git a/src/overlays/actors/ovl_En_Niw/z_en_niw.c b/src/overlays/actors/ovl_En_Niw/z_en_niw.c index 3eadcc15e..c65d794bb 100644 --- a/src/overlays/actors/ovl_En_Niw/z_en_niw.c +++ b/src/overlays/actors/ovl_En_Niw/z_en_niw.c @@ -1007,7 +1007,7 @@ void EnNiw_DrawFeathers(EnNiw* this, GlobalContext* globalCtx) { } Matrix_InsertTranslation(feather->pos.x, feather->pos.y, feather->pos.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(feather->scale, feather->scale, 1.0f, MTXMODE_APPLY); Matrix_InsertZRotation_f(feather->zRot, MTXMODE_APPLY); Matrix_InsertTranslation(0.0f, -1000.0f, 0.0f, MTXMODE_APPLY); diff --git a/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c b/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c index d2140a16e..10f9a1783 100644 --- a/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c +++ b/src/overlays/actors/ovl_En_Nutsball/z_en_nutsball.c @@ -171,7 +171,7 @@ void EnNutsball_Draw(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C28C(globalCtx->state.gfxCtx); - Matrix_InsertMatrix(&globalCtx->mf_187FC, MTXMODE_APPLY); + Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_APPLY); Matrix_InsertZRotation_s(this->actor.home.rot.z, MTXMODE_APPLY); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, D_04058BA0); diff --git a/src/overlays/actors/ovl_En_Okarina_Effect/z_en_okarina_effect.c b/src/overlays/actors/ovl_En_Okarina_Effect/z_en_okarina_effect.c index 96f12dab2..9b0d89cdd 100644 --- a/src/overlays/actors/ovl_En_Okarina_Effect/z_en_okarina_effect.c +++ b/src/overlays/actors/ovl_En_Okarina_Effect/z_en_okarina_effect.c @@ -1,7 +1,7 @@ /* * File: z_en_okarina_effect.c * Overlay: ovl_En_Okarina_Effect - * Description: + * Description: Manages the storm created when playing Song of Storms */ #include "z_en_okarina_effect.h" diff --git a/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.h b/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.h index 0c6cfe423..53b63236e 100644 --- a/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.h +++ b/src/overlays/actors/ovl_En_Okarina_Tag/z_en_okarina_tag.h @@ -10,7 +10,7 @@ typedef void (*EnOkarinaTagActionFunc)(struct EnOkarinaTag*, GlobalContext*); typedef struct EnOkarinaTag { /* 0x0000 */ Actor actor; /* 0x0144 */ EnOkarinaTagActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x14]; + /* 0x0148 */ char unk_148[0x14]; } EnOkarinaTag; // size = 0x15C extern const ActorInit En_Okarina_Tag_InitVars; diff --git a/src/overlays/actors/ovl_En_Onpuman/z_en_onpuman.c b/src/overlays/actors/ovl_En_Onpuman/z_en_onpuman.c index 0e4ebdd48..1f93a9786 100644 --- a/src/overlays/actors/ovl_En_Onpuman/z_en_onpuman.c +++ b/src/overlays/actors/ovl_En_Onpuman/z_en_onpuman.c @@ -1,7 +1,7 @@ /* * File: z_en_onpuman.c * Overlay: ovl_En_Onpuman - * Description: Monkey Instrument Prompt + * Description: Monkey Instrument Prompt (unused) */ #include "z_en_onpuman.h" diff --git a/src/overlays/actors/ovl_En_Ot/z_en_ot.c b/src/overlays/actors/ovl_En_Ot/z_en_ot.c index d6c95bad6..65fd93e86 100644 --- a/src/overlays/actors/ovl_En_Ot/z_en_ot.c +++ b/src/overlays/actors/ovl_En_Ot/z_en_ot.c @@ -506,7 +506,7 @@ void func_80B5C6DC(EnOt* this, GlobalContext* globalCtx) { Vec3f sp30; sp3E = Actor_YawToPoint(&player->actor, &this->unk_394); - Matrix_RotateY(BINANG_ADD(sp3E, 0x4000), 0); + Matrix_RotateY(BINANG_ADD(sp3E, 0x4000), MTXMODE_NEW); if (this->unk_33C == 2) { Matrix_GetStateTranslationAndScaledZ(26.259998f, &sp30); } else { @@ -1132,7 +1132,7 @@ void func_80B5E078(GlobalContext* globalCtx, EnOtUnkStruct* arg1, s32 arg2) { sp54.x = arg1->unk_30; sp54.y = arg1->unk_34; sp54.z = 0.0f; - Matrix_RotateY(temp, 0); + Matrix_RotateY(temp, MTXMODE_NEW); Matrix_MultiplyVector3fByState(&sp54, &arg1->unk_0C); Math_Vec3f_Sum(&arg1->unk_0C, &arg1->unk_50, &arg1->unk_0C); arg1->unk_4C--; diff --git a/src/overlays/actors/ovl_En_Owl/z_en_owl.c b/src/overlays/actors/ovl_En_Owl/z_en_owl.c index 514245a32..ab5e2520a 100644 --- a/src/overlays/actors/ovl_En_Owl/z_en_owl.c +++ b/src/overlays/actors/ovl_En_Owl/z_en_owl.c @@ -1172,9 +1172,9 @@ void func_8095D074(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); - Matrix_InsertTranslation(0.0f, 500.0f, 0.0f, 1); - Matrix_InsertXRotation_s(this->unk_3D8 - 0x4000, 1); - Matrix_InsertTranslation(0.0f, 0.0f, -500.0f, 1); + Matrix_InsertTranslation(0.0f, 500.0f, 0.0f, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->unk_3D8 - 0x4000, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, 0.0f, -500.0f, MTXMODE_APPLY); if (this->unk_3DC >= 0x20) { gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); diff --git a/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c b/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c index 8993cb14a..cb796119a 100644 --- a/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c +++ b/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.c @@ -7,6 +7,7 @@ #include "z_en_pametfrog.h" #include "overlays/actors/ovl_En_Bigpamet/z_en_bigpamet.h" #include "overlays/effects/ovl_Effect_Ss_Hahen/z_eff_ss_hahen.h" +#include "objects/object_bigslime/object_bigslime.h" #define FLAGS 0x00000035 @@ -65,28 +66,6 @@ void EnPametfrog_SnapperSpawn(EnPametfrog* this, GlobalContext* globalCtx); void EnPametfrog_SetupTransitionGekkoSnapper(EnPametfrog* this, GlobalContext* globalCtx); void EnPametfrog_TransitionGekkoSnapper(EnPametfrog* this, GlobalContext* globalCtx); -extern AnimationHeader D_06000994; // Begin Rear on Snapper -extern AnimationHeader D_06001B08; // Call Snapper -extern AnimationHeader D_06001E14; // Crawl on Wall -extern AnimationHeader D_06001F20; // Falling -extern AnimationHeader D_060030E4; // Get up from Back -extern AnimationHeader D_0600347C; // Jab Punch -extern AnimationHeader D_060039C4; // Jump on Ground -extern AnimationHeader D_06003F28; // Kick -extern AnimationHeader D_06004298; // Fall on Back -extern AnimationHeader D_06004680; // Idle -extern AnimationHeader D_06004894; // Jump on Snapper -extern AnimationHeader D_06004D50; // Continue Rear on Snapper -extern AnimationHeader D_060050B8; // Squeeze Body -extern AnimationHeader D_060052EC; // Land on Snapper -extern AnimationHeader D_06005694; // Wiggle -extern AnimationHeader D_06005D54; // Head Knockback -extern AnimationHeader D_060066B4; // Look Around -extern AnimationHeader D_060070C4; // Hook Punch -extern FlexSkeletonHeader D_0600DF98; -extern AnimationHeader D_0600F048; // Windup Punch -extern AnimationHeader D_0600F990; // Melee Ready Stance - const ActorInit En_Pametfrog_InitVars = { ACTOR_EN_PAMETFROG, ACTORCAT_BOSS, @@ -207,7 +186,8 @@ void EnPametfrog_Init(Actor* thisx, GlobalContext* globalCtx) { Actor_ProcessInitChain(&this->actor, sInitChain); ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 55.0f); CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInit); - SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600DF98, &D_0600F990, this->jointTable, this->morphTable, 24); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &gGekkoSkel, &gGekkoBoxingStanceAnim, this->jointTable, + this->morphTable, GEKKO_LIMB_MAX); Collider_InitAndSetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colElement); this->params = CLAMP(this->actor.params, 1, 4); if (Actor_GetRoomCleared(globalCtx, globalCtx->roomCtx.currRoom.num)) { @@ -250,7 +230,7 @@ u8 EnPametfrog_Vec3fNormalize(Vec3f* vec) { } } -void EnPametfrog_ChangeColliderFreeze(EnPametfrog* this) { +void EnPametfrog_Freeze(EnPametfrog* this) { this->drawEffect = GEKKO_DRAW_EFFECT_FROZEN; this->collider.base.colType = COLTYPE_HIT3; this->collider.elements->info.elemType = ELEMTYPE_UNK0; @@ -259,14 +239,14 @@ void EnPametfrog_ChangeColliderFreeze(EnPametfrog* this) { this->unk_2C4 = 1.0f; } -void EnPametfrog_ChangeColliderThaw(EnPametfrog* this, GlobalContext* globalCtx) { +void EnPametfrog_Thaw(EnPametfrog* this, GlobalContext* globalCtx) { this->freezeTimer = 0; if (this->drawEffect == GEKKO_DRAW_EFFECT_FROZEN) { - this->drawEffect = GEKKO_DRAW_EFFECT_NONE; + this->drawEffect = GEKKO_DRAW_EFFECT_THAW; this->collider.base.colType = COLTYPE_HIT6; this->collider.elements->info.elemType = ELEMTYPE_UNK1; this->unk_2C4 = 0.0f; - func_800BF7CC(globalCtx, &this->actor, this->limbPos, 12, 2, 0.3f, 0.2f); + func_800BF7CC(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), 2, 0.3f, 0.2f); } } @@ -335,7 +315,7 @@ s32 func_8086A2CC(EnPametfrog* this, CollisionPoly* floorPoly) { Math3D_CrossProduct(&this->unk_2DC, &floorNorm, &vec2); EnPametfrog_Vec3fNormalize(&vec2); - Matrix_InsertRotationAroundUnitVector_f(rotation, &vec2, 0); + Matrix_InsertRotationAroundUnitVector_f(rotation, &vec2, MTXMODE_NEW); Matrix_MultiplyVector3fByState(&this->unk_2E8, &vec2); Math_Vec3f_Copy(&this->unk_2E8, &vec2); Math3D_CrossProduct(&this->unk_2E8, &floorNorm, &this->unk_2D0); @@ -407,7 +387,7 @@ void EnPametfrog_JumpOnGround(EnPametfrog* this, GlobalContext* globalCtx) { void EnPametfrog_ApplyMagicArrowEffects(EnPametfrog* this, GlobalContext* globalCtx) { if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_FIRE) { - this->drawEffect = GEKKO_DRAW_EFFECT_NONE; + this->drawEffect = GEKKO_DRAW_EFFECT_THAW; this->unk_2C4 = 3.0f; this->unk_2C8 = 0.75f; } else if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_LIGHT) { @@ -418,7 +398,7 @@ void EnPametfrog_ApplyMagicArrowEffects(EnPametfrog* this, GlobalContext* global this->collider.elements[0].info.bumper.hitPos.x, this->collider.elements[0].info.bumper.hitPos.y, this->collider.elements[0].info.bumper.hitPos.z, 0, 0, 0, CLEAR_TAG_LARGE_LIGHT_RAYS); } else if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_ICE) { - EnPametfrog_ChangeColliderFreeze(this); + EnPametfrog_Freeze(this); } } @@ -439,11 +419,11 @@ void EnPametfrog_ApplyStun(EnPametfrog* this) { void EnPametfrog_SetupRearOnSnapper(EnPametfrog* this) { if (this->actionFunc == EnPametfrog_RearOnSnapperRise) { - Animation_PlayOnce(&this->skelAnime, &D_06005694); + Animation_PlayOnce(&this->skelAnime, &gGekkoWiggleAnim); } else if (this->actionFunc == EnPametfrog_RearOnSnapperWave) { - Animation_PlayOnce(&this->skelAnime, &D_060052EC); + Animation_PlayOnce(&this->skelAnime, &gGekkoLandOnSnapperAnim); } else { - Animation_PlayOnce(&this->skelAnime, &D_06004680); + Animation_PlayOnce(&this->skelAnime, &gGekkoStandingIdleAnim); } this->actor.flags &= ~1; @@ -458,9 +438,9 @@ void EnPametfrog_RearOnSnapper(EnPametfrog* this, GlobalContext* globalCtx) { if (SkelAnime_Update(&this->skelAnime)) { if (Rand_ZeroOne() < 0.5f) { - Animation_PlayOnce(&this->skelAnime, &D_06004D50); + Animation_PlayOnce(&this->skelAnime, &gGekkoQuickFistPumpAnim); } else { - Animation_PlayOnce(&this->skelAnime, &D_06004680); + Animation_PlayOnce(&this->skelAnime, &gGekkoStandingIdleAnim); } } @@ -478,7 +458,7 @@ void EnPametfrog_RearOnSnapper(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupRearOnSnapperWave(EnPametfrog* this) { - Animation_PlayOnce(&this->skelAnime, &D_06004894); + Animation_PlayOnce(&this->skelAnime, &gGekkoJumpOnSnapperAnim); this->timer = 15; this->actionFunc = EnPametfrog_RearOnSnapperWave; } @@ -493,7 +473,7 @@ void EnPametfrog_RearOnSnapperWave(EnPametfrog* this, GlobalContext* globalCtx) } void EnPametfrog_SetupRearOnSnapperRise(EnPametfrog* this) { - Animation_PlayOnce(&this->skelAnime, &D_060050B8); + Animation_PlayOnce(&this->skelAnime, &gGekkoSqueezeAnim); this->timer = 10; this->actor.params = GEKKO_REAR_ON_SNAPPER; this->actor.shape.rot.x = 0; @@ -517,7 +497,7 @@ void EnPametfrog_SetupFallOffSnapper(EnPametfrog* this, GlobalContext* globalCtx Vec3f eye; s16 yaw; - Animation_PlayOnce(&this->skelAnime, &D_06001F20); + Animation_PlayOnce(&this->skelAnime, &gGekkoFallInAirAnim); this->actor.params = GEKKO_FALL_OFF_SNAPPER; this->actor.speedXZ = 7.0f; this->actor.velocity.y = 15.0f; @@ -554,7 +534,7 @@ void EnPametfrog_FallOffSnapper(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupJumpToWall(EnPametfrog* this) { - Animation_Change(&this->skelAnime, &D_060039C4, 2.0f, 0.0f, 0.0f, 0, -2.0f); + Animation_Change(&this->skelAnime, &gGekkoJumpForwardAnim, 2.0f, 0.0f, 0.0f, 0, -2.0f); this->actor.shape.rot.x = 0; this->actor.shape.rot.z = 0; this->actor.bgCheckFlags &= ~8; @@ -578,14 +558,14 @@ void EnPametfrog_JumpToWall(EnPametfrog* this, GlobalContext* globalCtx) { void EnPametfrog_SetupWallCrawl(EnPametfrog* this) { if (this->actionFunc == EnPametfrog_JumpToWall) { - Animation_PlayLoop(&this->skelAnime, &D_06001E14); + Animation_PlayLoop(&this->skelAnime, &gGekkoCrawlAnim); this->collider.base.acFlags |= AC_ON; this->unk_2D0.x = 0.0f; this->unk_2D0.z = 0.0f; this->actor.gravity = 0.0f; this->actor.world.pos.y = this->actor.focus.pos.y; this->unk_2D0.y = 1.0f; - Math_Vec3f_Copy(&this->actor.colChkInfo.displacement, &D_801D15B0); + Math_Vec3f_Copy(&this->actor.colChkInfo.displacement, &gZeroVec3f); this->actor.colChkInfo.mass = MASS_IMMOVABLE; this->unk_2DC.x = COLPOLY_GET_NORMAL(this->actor.wallPoly->normal.x); this->unk_2DC.y = COLPOLY_GET_NORMAL(this->actor.wallPoly->normal.y); @@ -721,7 +701,8 @@ void EnPametfrog_WallPause(EnPametfrog* this, GlobalContext* globalCtx) { void EnPametfrog_SetupClimbDownWall(EnPametfrog* this) { s16 yaw; - Animation_Change(&this->skelAnime, &D_060039C4, 0.0f, 0.0f, Animation_GetLastFrame(&D_060039C4), 2, 0.0f); + Animation_Change(&this->skelAnime, &gGekkoJumpForwardAnim, 0.0f, 0.0f, + Animation_GetLastFrame(&gGekkoJumpForwardAnim), 2, 0.0f); this->actor.shape.rot.y = Actor_YawBetweenActors(&this->actor, this->actor.child); this->actor.world.rot.y = this->actor.shape.rot.y; this->actor.shape.rot.x = 0; @@ -755,7 +736,7 @@ void EnPametfrog_ClimbDownWall(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupRunToSnapper(EnPametfrog* this) { - Animation_Change(&this->skelAnime, &D_060039C4, 2.0f, 0.0f, 0.0f, 0, -2.0f); + Animation_Change(&this->skelAnime, &gGekkoJumpForwardAnim, 2.0f, 0.0f, 0.0f, 0, -2.0f); this->actor.params = GEKKO_RETURN_TO_SNAPPER; this->actionFunc = EnPametfrog_RunToSnapper; } @@ -778,7 +759,7 @@ void EnPametfrog_RunToSnapper(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupJumpOnSnapper(EnPametfrog* this) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_06004680, 6.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &gGekkoStandingIdleAnim, 6.0f); this->timer = 6; this->collider.base.ocFlags1 &= ~OC1_ON; this->collider.base.acFlags &= ~AC_ON; @@ -810,7 +791,7 @@ void EnPametfrog_JumpOnSnapper(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupLandOnSnapper(EnPametfrog* this) { - Animation_PlayOnce(&this->skelAnime, &D_06000994); + Animation_PlayOnce(&this->skelAnime, &gGekkoFullFistPumpAnim); this->actor.shape.rot.y = this->actor.child->shape.rot.y; this->actor.params = GEKKO_ON_SNAPPER; this->actionFunc = EnPametfrog_LandOnSnapper; @@ -828,7 +809,7 @@ void EnPametfrog_SetupFallInAir(EnPametfrog* this, GlobalContext* globalCtx) { Vec3f eye; f32 xzDist; - Animation_PlayOnce(&this->skelAnime, &D_06001F20); + Animation_PlayOnce(&this->skelAnime, &gGekkoFallInAirAnim); if (this->actor.colChkInfo.health > 0) { this->actor.params = GEKKO_RETURN_TO_SNAPPER; } @@ -889,13 +870,13 @@ void EnPametfrog_FallInAir(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupFallOnGround(EnPametfrog* this, GlobalContext* globalCtx) { - Animation_PlayOnce(&this->skelAnime, &D_06004298); + Animation_PlayOnce(&this->skelAnime, &gGekkoFallOnGroundAnim); this->actor.shape.rot.x = 0; this->actor.shape.rot.y += this->spinYaw; this->actor.shape.rot.z = 0; this->spinYaw = 0; this->timer = 5; - EnPametfrog_ChangeColliderThaw(this, globalCtx); + EnPametfrog_Thaw(this, globalCtx); EnPametfrog_JumpWaterEffects(this, globalCtx); Audio_PlayActorSound2(&this->actor, NA_SE_EV_WALK_WATER); this->actionFunc = EnPametfrog_FallOnGround; @@ -903,14 +884,14 @@ void EnPametfrog_SetupFallOnGround(EnPametfrog* this, GlobalContext* globalCtx) void EnPametfrog_FallOnGround(EnPametfrog* this, GlobalContext* globalCtx) { if (SkelAnime_Update(&this->skelAnime)) { - if (this->skelAnime.animation == &D_06004298) { + if (this->skelAnime.animation == &gGekkoFallOnGroundAnim) { if (this->actor.colChkInfo.health == 0) { this->timer--; if (this->timer == 0) { EnPametfrog_SetupDefeatGekko(this, globalCtx); } } else { - Animation_PlayOnce(&this->skelAnime, &D_060030E4); + Animation_PlayOnce(&this->skelAnime, &gGekkoRecoverAnim); } } else { EnPametfrog_SetupRunToSnapper(this); @@ -982,7 +963,7 @@ void EnPametfrog_SetupSpawnFrog(EnPametfrog* this, GlobalContext* globalCtx) { vec1.y = this->actor.world.pos.y + 25.0f; vec1.z = (Math_CosS(yaw) * 20.0f) + this->actor.world.pos.z; this->collider.base.ocFlags1 &= ~OC1_ON; - func_800B0DE0(globalCtx, &vec1, &D_801D15B0, &D_801D15B0, &primColor, &envColor, 800, 50); + func_800B0DE0(globalCtx, &vec1, &gZeroVec3f, &gZeroVec3f, &primColor, &envColor, 800, 50); Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_NPC_APPEAR); Actor_SetRoomClearedTemp(globalCtx, globalCtx->roomCtx.currRoom.num); @@ -1043,7 +1024,7 @@ void EnPametfrog_PlayCutscene(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupLookAround(EnPametfrog* this) { - Animation_PlayOnce(&this->skelAnime, &D_060066B4); + Animation_PlayOnce(&this->skelAnime, &gGekkoLookAroundAnim); this->collider.base.atFlags &= ~AT_ON; this->actor.speedXZ = 0.0f; this->actor.world.rot.y = this->actor.shape.rot.y; @@ -1064,7 +1045,7 @@ void EnPametfrog_LookAround(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupJumpToLink(EnPametfrog* this) { - Animation_PlayLoop(&this->skelAnime, &D_060039C4); + Animation_PlayLoop(&this->skelAnime, &gGekkoJumpForwardAnim); this->collider.base.acFlags |= AC_ON; this->actor.world.rot.y = this->actor.shape.rot.y; this->actionFunc = EnPametfrog_JumpToLink; @@ -1089,17 +1070,17 @@ void EnPametfrog_JumpToLink(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupMeleeAttack(EnPametfrog* this) { - Animation_PlayOnce(&this->skelAnime, &D_0600F990); + Animation_PlayOnce(&this->skelAnime, &gGekkoBoxingStanceAnim); this->timer = 7; this->actor.speedXZ = 0.0f; this->actionFunc = EnPametfrog_MeleeAttack; } static AnimationHeader* sAttackAnimations[] = { - &D_0600347C, // Jab Punch - &D_060070C4, // Hook Punch - &D_06003F28, // Kick - &D_0600F048, // Windup Punch + &gGekkoJabPunchAnim, + &gGekkoHookPunchAnim, + &gGekkoKickAnim, + &gGekkoWindupPunchAnim, }; void EnPametfrog_MeleeAttack(EnPametfrog* this, GlobalContext* globalCtx) { @@ -1109,18 +1090,18 @@ void EnPametfrog_MeleeAttack(EnPametfrog* this, GlobalContext* globalCtx) { if (this->timer == 0) { EnPametfrog_SetupLookAround(this); } else if (this->timer == 6) { - Animation_PlayOnce(&this->skelAnime, &D_0600F990); + Animation_PlayOnce(&this->skelAnime, &gGekkoBoxingStanceAnim); } else { Animation_PlayOnce(&this->skelAnime, sAttackAnimations[(s32)Rand_ZeroFloat(4.0f) % 4]); } } - if ((this->skelAnime.animation == &D_0600347C && Animation_OnFrame(&this->skelAnime, 2.0f)) || - (this->skelAnime.animation == &D_060070C4 && Animation_OnFrame(&this->skelAnime, 9.0f)) || - (this->skelAnime.animation == &D_06003F28 && Animation_OnFrame(&this->skelAnime, 2.0f)) || - ((this->skelAnime.animation == &D_0600F048) && Animation_OnFrame(&this->skelAnime, 27.0f))) { + if ((this->skelAnime.animation == &gGekkoJabPunchAnim && Animation_OnFrame(&this->skelAnime, 2.0f)) || + (this->skelAnime.animation == &gGekkoHookPunchAnim && Animation_OnFrame(&this->skelAnime, 9.0f)) || + (this->skelAnime.animation == &gGekkoKickAnim && Animation_OnFrame(&this->skelAnime, 2.0f)) || + ((this->skelAnime.animation == &gGekkoWindupPunchAnim) && Animation_OnFrame(&this->skelAnime, 27.0f))) { this->collider.base.atFlags |= AT_ON; - if (this->skelAnime.animation == &D_06003F28) { + if (this->skelAnime.animation == &gGekkoKickAnim) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_KICK); } else { Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_PUNCH1); @@ -1131,7 +1112,7 @@ void EnPametfrog_MeleeAttack(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupDamage(EnPametfrog* this) { - Animation_MorphToPlayOnce(&this->skelAnime, &D_06005D54, -3.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &gGekkoKnockbackAnim, -3.0f); this->timer = 20; this->collider.base.atFlags &= ~AT_ON; this->collider.base.acFlags &= ~AC_ON; @@ -1157,7 +1138,7 @@ void EnPametfrog_Damage(EnPametfrog* this, GlobalContext* globalCtx) { } void EnPametfrog_SetupStun(EnPametfrog* this) { - if (this->skelAnime.animation == &D_060039C4) { + if (this->skelAnime.animation == &gGekkoJumpForwardAnim) { this->skelAnime.curFrame = 0.0f; SkelAnime_Update(&this->skelAnime); } @@ -1175,10 +1156,10 @@ void EnPametfrog_SetupStun(EnPametfrog* this) { void EnPametfrog_Stun(EnPametfrog* this, GlobalContext* globalCtx) { this->freezeTimer--; if (this->freezeTimer == 0) { - EnPametfrog_ChangeColliderThaw(this, globalCtx); + EnPametfrog_Thaw(this, globalCtx); EnPametfrog_SetupJumpToLink(this); } else if (this->freezeTimer == 78) { - EnPametfrog_ChangeColliderThaw(this, globalCtx); + EnPametfrog_Thaw(this, globalCtx); this->actor.colorFilterTimer = 0; EnPametfrog_SetupCutscene(this); } @@ -1189,7 +1170,7 @@ void EnPametfrog_SetupCallSnapper(EnPametfrog* this, GlobalContext* globalCtx) { Vec3f at; s16 yawDiff; - Animation_MorphToPlayOnce(&this->skelAnime, &D_06001B08, 3.0f); + Animation_MorphToPlayOnce(&this->skelAnime, &gGekkoCallAnim, 3.0f); Audio_PlayActorSound2(&this->actor, NA_SE_EN_FROG_GREET); this->actor.flags &= ~1; this->actor.colChkInfo.health = 6; @@ -1298,14 +1279,14 @@ void EnPametfrog_ApplyDamageEffect(EnPametfrog* this, GlobalContext* globalCtx) EnPametfrog_ApplyStun(this); EnPametfrog_SetupStun(this); } else if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_ICE) { - EnPametfrog_ChangeColliderFreeze(this); + EnPametfrog_Freeze(this); this->freezeTimer = 80; func_800BCB70(&this->actor, 0x4000, 0xFF, 0, 0x50); EnPametfrog_SetupStun(this); } else { - EnPametfrog_ChangeColliderThaw(this, globalCtx); + EnPametfrog_Thaw(this, globalCtx); if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_FIRE) { - this->drawEffect = GEKKO_DRAW_EFFECT_NONE; + this->drawEffect = GEKKO_DRAW_EFFECT_THAW; this->unk_2C8 = 0.75f; this->unk_2C4 = 4.0f; } else if (this->actor.colChkInfo.damageEffect == GEKKO_DMGEFF_LIGHT) { @@ -1388,19 +1369,19 @@ void EnPametfrog_Update(Actor* thisx, GlobalContext* globalCtx) { } } -/* index -1: Limb Not used - * index 0: GEKKO_LIMB_WAIST - * index 1: GEKKO_LIMB_L_SHIN - * index 2: GEKKO_LIMB_L_FOOT - * index 3: GEKKO_LIMB_R_SHIN - * index 4: GEKKO_LIMB_R_FOOT - * index 5: GEKKO_LIMB_L_UPPER_ARM - * index 6: GEKKO_LIMB_L_FOREARM - * index 7: GEKKO_LIMB_L_HAND - * index 8: GEKKO_LIMB_R_UPPER_ARM - * index 9: GEKKO_LIMB_R_FOREARM - * index 10: GEKKO_LIMB_R_HAND - * index 11: GEKKO_LIMB_JAW +/* value -1: Limb Not used + * value 0: GEKKO_LIMB_WAIST + * value 1: GEKKO_LIMB_L_SHIN + * value 2: GEKKO_LIMB_L_FOOT + * value 3: GEKKO_LIMB_R_SHIN + * value 4: GEKKO_LIMB_R_FOOT + * value 5: GEKKO_LIMB_L_UPPER_ARM + * value 6: GEKKO_LIMB_L_FOREARM + * value 7: GEKKO_LIMB_L_HAND + * value 8: GEKKO_LIMB_R_UPPER_ARM + * value 9: GEKKO_LIMB_R_FOREARM + * value 10: GEKKO_LIMB_R_HAND + * value 11: GEKKO_LIMB_JAW */ static s8 limbPosIndex[] = { -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, 6, -1, 7, 8, 9, -1, 10, -1, 11, -1, -1, diff --git a/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.h b/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.h index f00acecb5..957a46cfc 100644 --- a/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.h +++ b/src/overlays/actors/ovl_En_Pametfrog/z_en_pametfrog.h @@ -21,7 +21,7 @@ typedef enum { } EnPametfrogState; typedef enum { - /* 00 */ GEKKO_DRAW_EFFECT_NONE, // May be GEKKO_DRAW_EFFECT_THAW + /* 00 */ GEKKO_DRAW_EFFECT_THAW, /* 10 */ GEKKO_DRAW_EFFECT_FROZEN = 10, /* 20 */ GEKKO_DRAW_EFFECT_LIGHT_ORBS = 20, /* 30 */ GEKKO_DRAW_EFFECT_ELECTRIC_STUN = 30, diff --git a/src/overlays/actors/ovl_En_Paper/z_en_paper.h b/src/overlays/actors/ovl_En_Paper/z_en_paper.h index d2e12e137..0147442a9 100644 --- a/src/overlays/actors/ovl_En_Paper/z_en_paper.h +++ b/src/overlays/actors/ovl_En_Paper/z_en_paper.h @@ -10,7 +10,7 @@ typedef void (*EnPaperActionFunc)(struct EnPaper*, GlobalContext*); typedef struct EnPaper { /* 0x0000 */ Actor actor; /* 0x0144 */ EnPaperActionFunc actionFunc; - /* 0x0148 */ char unk_144[0xC40]; + /* 0x0148 */ char unk_148[0xC40]; } EnPaper; // size = 0xD88 extern const ActorInit En_Paper_InitVars; diff --git a/src/overlays/actors/ovl_En_Part/z_en_part.c b/src/overlays/actors/ovl_En_Part/z_en_part.c index 9e184b1d9..4f9a7e64f 100644 --- a/src/overlays/actors/ovl_En_Part/z_en_part.c +++ b/src/overlays/actors/ovl_En_Part/z_en_part.c @@ -1,7 +1,7 @@ /* * File: z_en_part.c * Overlay: ovl_En_Part - * Description: + * Description: Enemy body parts (spawned when dying) */ #include "z_en_part.h" diff --git a/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c b/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c index 5f51217bb..1ab37117c 100644 --- a/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c +++ b/src/overlays/actors/ovl_En_Peehat/z_en_peehat.c @@ -5,6 +5,8 @@ */ #include "z_en_peehat.h" +#include "overlays/actors/ovl_En_Bom/z_en_bom.h" +#include "objects/object_ph/object_ph.h" #define FLAGS 0x00000015 @@ -15,7 +17,26 @@ void EnPeehat_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnPeehat_Update(Actor* thisx, GlobalContext* globalCtx); void EnPeehat_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80897498(EnPeehat* this); +void func_80897520(EnPeehat* this, GlobalContext* globalCtx); +void func_80897648(EnPeehat* this); +void func_808976DC(EnPeehat* this, GlobalContext* globalCtx); +void func_80897910(EnPeehat* this, GlobalContext* globalCtx); +void func_80897A34(EnPeehat* this); +void func_80897A94(EnPeehat* this, GlobalContext* globalCtx); +void func_80897D48(EnPeehat* this, GlobalContext* globalCtx); +void func_80897EAC(EnPeehat* this); +void func_80897F44(EnPeehat* this, GlobalContext* globalCtx); +void func_80898124(EnPeehat* this); +void func_80898144(EnPeehat* this, GlobalContext* globalCtx); +void func_808982E0(EnPeehat* this); +void func_80898338(EnPeehat* this, GlobalContext* globalCtx); +void func_80898454(EnPeehat* this, GlobalContext* globalCtx); +void func_808984E0(EnPeehat* this); +void func_80898594(EnPeehat* this, GlobalContext* globalCtx); +void func_80898654(EnPeehat* this); +void func_808986A4(EnPeehat* this, GlobalContext* globalCtx); + const ActorInit En_Peehat_InitVars = { ACTOR_EN_PEEHAT, ACTORCAT_ENEMY, @@ -28,40 +49,85 @@ const ActorInit En_Peehat_InitVars = { (ActorFunc)EnPeehat_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80899430 = { - { COLTYPE_WOOD, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_WOOD, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 50, 120, -20, { 0, 0, 0 } }, }; -// static ColliderSphereInit sSphereInit = { -static ColliderSphereInit D_8089945C = { - { COLTYPE_HIT6, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_SPHERE, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderSphereInit sSphereInit = { + { + COLTYPE_HIT6, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_SPHERE, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 40 }, 100 }, }; -// static ColliderTrisElementInit sTrisElementsInit[2] = { -static ColliderTrisElementInit D_80899488[2] = { +static ColliderTrisElementInit sTrisElementsInit[2] = { { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, }, { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x10 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x10 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } } }, }, }; -// static ColliderTrisInit sTrisInit = { -static ColliderTrisInit D_80899500 = { - { COLTYPE_METAL, AT_NONE | AT_TYPE_ENEMY, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_TRIS, }, - 2, D_80899488, // sTrisElementsInit, +static ColliderTrisInit sTrisInit = { + { + COLTYPE_METAL, + AT_NONE | AT_TYPE_ENEMY, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_NONE, + OC2_TYPE_1, + COLSHAPE_TRIS, + }, + 2, + sTrisElementsInit, }; -// static DamageTable sDamageTable = { -static DamageTable D_80899510 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(1, 0x0), /* Horse trample */ DMG_ENTRY(1, 0x0), @@ -96,98 +162,787 @@ static DamageTable D_80899510 = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80899530 = { 15, 50, 120, -20, MASS_HEAVY }; +static CollisionCheckInfoInit2 sColChkInfoInit1 = { 15, 50, 120, -20, MASS_HEAVY }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_8089953C = { 1, 20, 15, -5, 30 }; +static CollisionCheckInfoInit2 sColChkInfoInit2 = { 1, 20, 15, -5, 30 }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80899548[] = { +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4200, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 800, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 1800, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 700, ICHAIN_STOP), }; -#endif +void EnPeehat_Init(Actor* thisx, GlobalContext* globalCtx) { + EnPeehat* this = THIS; -extern ColliderCylinderInit D_80899430; -extern ColliderSphereInit D_8089945C; -extern ColliderTrisElementInit D_80899488[2]; -extern ColliderTrisInit D_80899500; -extern DamageTable D_80899510; -extern CollisionCheckInfoInit2 D_80899530; -extern CollisionCheckInfoInit2 D_8089953C; -extern InitChainEntry D_80899548[]; + Actor_ProcessInitChain(&this->actor, sInitChain); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_ph_Skel_001C80, &object_ph_Anim_0009C4, this->jointTable, + this->morphTable, 24); + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 27.0f); + this->unk_2B0 = 0; + Math_Vec3f_Copy(&this->actor.focus.pos, &this->actor.world.pos); + this->actor.floorHeight = this->actor.world.pos.y; + Collider_InitAndSetCylinder(globalCtx, &this->colliderCylinder, &this->actor, &sCylinderInit); + Collider_InitAndSetSphere(globalCtx, &this->colliderSphere, &this->actor, &sSphereInit); + Collider_InitAndSetTris(globalCtx, &this->colliderTris, &this->actor, &sTrisInit, this->colliderTriElements); -extern UNK_TYPE D_06000350; -extern UNK_TYPE D_060005C4; -extern UNK_TYPE D_06000844; -extern UNK_TYPE D_060009C4; + if (this->actor.params == 0) { + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit1); + if (gSaveContext.isNight) { + this->actor.shape.yOffset = -1000.0f; + } + Actor_SetScale(&this->actor, 0.036f); + this->actor.hintId = 0x48; + func_80897498(this); + } else { + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit2); + this->actor.scale.z = this->actor.scale.x = 0.006f; + this->actor.scale.y = 0.003f; + this->actor.velocity.y = 6.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/EnPeehat_Init.s") + this->colliderCylinder.dim.radius = 20; + this->colliderCylinder.dim.height = 15; + this->colliderCylinder.dim.yShift = -5; + this->actor.hintId = 0x49; + this->colliderCylinder.base.ocFlags1 &= ~OC1_ON; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/EnPeehat_Destroy.s") + func_80897A34(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897170.s") +void EnPeehat_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnPeehat* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_808971DC.s") + Collider_DestroyCylinder(globalCtx, &this->colliderCylinder); + Collider_DestroySphere(globalCtx, &this->colliderSphere); + Collider_DestroyTris(globalCtx, &this->colliderTris); + if (this->actor.params != 0) { + EnPeehat* parent = (EnPeehat*)this->actor.parent; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897258.s") + if ((parent != NULL) && (parent->actor.update != NULL)) { + parent->unk_2AC--; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897390.s") +void func_80897170(EnPeehat* this) { + this->unk_2AE = 10; + this->unk_2CC = 1.1f; + this->unk_2D0 = 1.6500001f; + this->unk_2C8 = 1.0f; + this->colliderSphere.base.colType = COLTYPE_HIT3; + this->unk_2B0 = 80; + func_800BCB70(&this->actor, 0x4000, 255, 0, 80); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897498.s") +void func_808971DC(EnPeehat* this, GlobalContext* globalCtx) { + if (this->unk_2AE == 10) { + this->unk_2AE = 0; + this->colliderSphere.base.colType = COLTYPE_HIT6; + this->unk_2C8 = 0.0f; + func_800BF7CC(globalCtx, &this->actor, this->unk_2EC, ARRAY_COUNT(this->unk_2EC), 2, 0.5f, 0.35f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897520.s") +void func_80897258(GlobalContext* globalCtx, EnPeehat* this, Vec3f* arg2, f32 arg3, f32 arg4) { + static Vec3f D_80899558 = { 0.0f, 8.0f, 0.0f }; + static Vec3f D_80899564 = { 0.0f, -1.5f, 0.0f }; + Vec3f sp44; + s16 sp42 = Rand_Next() >> 0x10; + s32 temp_v1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897648.s") + sp44.y = this->actor.floorHeight; + sp44.x = (Math_SinS(sp42) * arg3) + arg2->x; + sp44.z = (Math_CosS(sp42) * arg3) + arg2->z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_808976DC.s") + D_80899564.x = randPlusMinusPoint5Scaled(1.05f); + D_80899564.z = randPlusMinusPoint5Scaled(1.05f); + D_80899558.y = randPlusMinusPoint5Scaled(4.0f) + 8.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897864.s") + EffectSsHahen_Spawn(globalCtx, &sp44, &D_80899558, &D_80899564, 0, (Rand_ZeroFloat(5.0f) + 12.0f) * arg4, -1, 10, + NULL); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897910.s") +void func_80897390(EnPeehat* this, GlobalContext* globalCtx) { + s32 i; + s16 phi_s2 = BINANG_ROT180(this->actor.yawTowardsPlayer); + Actor* actor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897A34.s") + this->colliderCylinder.base.acFlags &= ~AC_HIT; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897A94.s") + for (i = 3 - this->unk_2AC; i > 0; i--) { + actor = + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_PEEHAT, this->actor.world.pos.x, + this->actor.world.pos.y + 50.0f, this->actor.world.pos.z, 0, phi_s2, 0, 1); + phi_s2 += 0x5555; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897D00.s") + if (actor != NULL) { + this->unk_2AC++; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897D48.s") + this->unk_2B0 = 8; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PIHAT_DAMAGE); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897EAC.s") +void func_80897498(EnPeehat* this) { + Animation_Change(&this->skelAnime, &object_ph_Anim_0009C4, 0.0f, 3.0f, + Animation_GetLastFrame(&object_ph_Anim_0009C4), 2, 0.0f); + this->unk_2B0 = 0; + this->unk_2AD = 1; + this->colliderCylinder.base.acFlags &= ~AC_HIT; + this->actionFunc = func_80897520; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80897F44.s") +void func_80897520(EnPeehat* this, GlobalContext* globalCtx) { + if (!gSaveContext.isNight) { + this->actor.flags |= 1; + this->colliderSphere.base.acFlags |= AC_ON; + if (this->actor.xzDistToPlayer < 740.0f) { + func_80897648(this); + } else { + Math_StepToF(&this->actor.shape.yOffset, -1000.0f, 10.0f); + } + } else { + this->actor.flags &= ~1; + this->colliderSphere.base.acFlags &= ~AC_ON; + Math_StepToF(&this->actor.shape.yOffset, -1000.0f, 50.0f); + if (this->unk_2B0 != 0) { + this->unk_2B0--; + if (this->unk_2B0 & 4) { + Math_StepToF(&this->unk_2C4, 0.205f, 0.235f); + } else { + Math_StepToF(&this->unk_2C4, 0.0f, 0.005f); + } + } else if (this->colliderCylinder.base.acFlags & AC_HIT) { + func_80897390(this, globalCtx); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80898124.s") +void func_80897648(EnPeehat* this) { + if (this->actionFunc != func_80898454) { + Animation_Change(&this->skelAnime, &object_ph_Anim_0009C4, 0.0f, 3.0f, + Animation_GetLastFrame(&object_ph_Anim_0009C4), 2, 0.0f); + } + this->unk_2B0 = 16; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PIHAT_UP); + this->actionFunc = func_808976DC; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80898144.s") +void func_808976DC(EnPeehat* this, GlobalContext* globalCtx) { + Vec3f sp34; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_808982E0.s") + Math_StepToF(&this->actor.shape.yOffset, 0.0f, 50.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80898338.s") + if (Math_ScaledStepToS(&this->unk_2B2, 4000, 800)) { + if (this->unk_2B0 != 0) { + this->unk_2B0--; + if ((this->unk_2B0 == 0) && (this->skelAnime.playSpeed < 0.5f)) { + this->unk_2B0 = -1; + this->skelAnime.playSpeed = 1.0f; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80898414.s") + if (SkelAnime_Update(&this->skelAnime) || (this->unk_2B0 == 0)) { + func_80897EAC(this); + } else { + this->actor.world.pos.y += 6.5f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80898454.s") + if ((this->actor.world.pos.y - this->actor.floorHeight) < 80.0f) { + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + sp34.y = this->actor.floorHeight; + func_800BBFB0(globalCtx, &sp34, 90.0f, 1, 150, 100, 1); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_808984E0.s") + func_80897258(globalCtx, this, &this->actor.world.pos, 75.0f, 2.0f); + Math_StepToF(&this->unk_2C4, 0.075f, 0.005f); + this->unk_2B4 += this->unk_2B2; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80898594.s") +void func_80897864(EnPeehat* this) { + Animation_PlayLoop(&this->skelAnime, &object_ph_Anim_0005C4); + this->unk_2B8 = 0.0f; + if (this->actionFunc == func_80898338) { + this->unk_2AD = -this->unk_2AD; + } else { + this->unk_2AD = (Rand_ZeroOne() < 0.5f) ? 1 : -1; + } + this->colliderTris.base.atFlags |= AT_ON; + this->actionFunc = func_80897910; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80898654.s") +void func_80897910(EnPeehat* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_808986A4.s") + Math_StepToF(&this->actor.speedXZ, 3.0f, 0.25f); + Math_StepToF(&this->actor.world.pos.y, this->actor.floorHeight + 80.0f, 3.0f); + SkelAnime_Update(&this->skelAnime); + if (!gSaveContext.isNight && (Math_Vec3f_DistXZ(&this->actor.home.pos, &player->actor.world.pos) < 1200.0f)) { + Math_ScaledStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 1000); + this->actor.shape.rot.y += (s16)(this->unk_2AD * 450); + } else { + func_80898124(this); + } + Math_ScaledStepToS(&this->unk_2B2, 4000, 500); + this->unk_2B4 += this->unk_2B2; + Math_StepToF(&this->unk_2C4, 0.075f, 0.005f); + func_800B9010(&this->actor, NA_SE_EN_PIHAT_FLY - SFX_FLAG); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_8089874C.s") +void func_80897A34(EnPeehat* this) { + Animation_PlayLoop(&this->skelAnime, &object_ph_Anim_0005C4); + this->unk_2B0 = 30; + this->actor.speedXZ = 5.3f; + this->colliderTris.base.atFlags |= AT_ON; + this->actionFunc = func_80897A94; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/EnPeehat_Update.s") +void func_80897A94(EnPeehat* this, GlobalContext* globalCtx) { + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80898E74.s") + if ((this->actor.parent != NULL) && (this->actor.parent->update == NULL)) { + this->actor.parent = NULL; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/func_80899024.s") + if ((this->actor.world.pos.y - this->actor.floorHeight) >= 70.0f) { + Math_StepToF(&this->actor.velocity.y, -1.3f, 0.5f); + } else { + Math_StepToF(&this->actor.velocity.y, -0.135f, 0.05f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Peehat/EnPeehat_Draw.s") + if (this->unk_2B0 > 0) { + this->unk_2B0--; + } else { + Math_ScaledStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 0x33E); + this->colliderCylinder.base.ocFlags1 |= OC1_ON; + } + + this->actor.shape.rot.y += 0x15E; + SkelAnime_Update(&this->skelAnime); + Math_ScaledStepToS(&this->unk_2B2, 4000, 500); + this->unk_2B4 += this->unk_2B2; + Math_StepToF(&this->unk_2C4, 0.075f, 0.005f); + func_800B9010(&this->actor, NA_SE_EN_PIHAT_SM_FLY - SFX_FLAG); + + if (this->colliderTris.base.atFlags & AT_BOUNCED) { + this->colliderTris.base.atFlags &= ~(AT_BOUNCED | AT_ON); + this->actor.colChkInfo.health = 0; + func_808982E0(this); + } else if ((this->colliderCylinder.base.acFlags & AC_HIT) || (this->actor.bgCheckFlags & 1)) { + func_800B3030(globalCtx, &this->actor.world.pos, &gZeroVec3f, &gZeroVec3f, 40, 7, 0); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 11, NA_SE_EN_EXTINCT); + if (!(this->actor.bgCheckFlags & 1)) { + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_PIHAT_SM_DEAD); + } + Actor_MarkForDeath(&this->actor); + } else if (this->colliderTris.base.atFlags & AT_HIT) { + this->colliderTris.base.atFlags &= ~AT_HIT; + if (BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.world.rot.y) > 0) { + this->actor.world.rot.y -= 0x2000; + } else { + this->actor.world.rot.y += 0x2000; + } + this->unk_2B0 = 40; + } else if (this->colliderCylinder.base.ocFlags1 & OC1_HIT) { + this->colliderCylinder.base.ocFlags1 &= ~OC1_HIT; + if ((BINANG_SUB(Actor_YawBetweenActors(&this->actor, this->colliderCylinder.base.oc), + this->actor.world.rot.y)) > 0) { + this->actor.world.rot.y -= 0x2000; + } else { + this->actor.world.rot.y += 0x2000; + } + this->unk_2B0 = 10; + } +} + +void func_80897D00(EnPeehat* this) { + Animation_PlayOnce(&this->skelAnime, &object_ph_Anim_000350); + this->colliderTris.base.atFlags &= ~AT_ON; + this->actionFunc = func_80897D48; +} + +void func_80897D48(EnPeehat* this, GlobalContext* globalCtx) { + Vec3f sp34; + + Math_StepToF(&this->actor.shape.yOffset, -1000.0f, 50.0f); + Math_StepToF(&this->actor.speedXZ, 0.0f, 1.0f); + Math_ScaledStepToS(&this->actor.shape.rot.x, 0, 50); + if (SkelAnime_Update(&this->skelAnime)) { + func_80897498(this); + this->actor.world.pos.y = this->actor.floorHeight; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PIHAT_LAND); + } else if (this->actor.floorHeight < this->actor.world.pos.y) { + Math_SmoothStepToF(&this->actor.world.pos.y, this->actor.floorHeight, 0.3f, 3.5f, 0.25f); + if ((this->actor.world.pos.y - this->actor.floorHeight) < 60.0f) { + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + sp34.y = this->actor.floorHeight; + func_800BBFB0(globalCtx, &sp34, 80.0f, 1, 150, 100, 1); + func_80897258(globalCtx, this, &sp34, 75.0f, 2.0f); + } + } + Math_ScaledStepToS(&this->unk_2B2, 0, 100); + this->unk_2B4 += this->unk_2B2; +} + +void func_80897EAC(EnPeehat* this) { + Animation_PlayLoop(&this->skelAnime, &object_ph_Anim_0005C4); + this->actor.speedXZ = Rand_ZeroFloat(0.5f) + 2.5f; + this->unk_2B0 = Rand_ZeroFloat(10.0f) + 10.0f; + this->colliderTris.base.atFlags |= AT_ON; + this->colliderSphere.base.acFlags |= AC_ON; + this->actionFunc = func_80897F44; +} + +void func_80897F44(EnPeehat* this, GlobalContext* globalCtx) { + s32 pad; + f32 cos; + Player* player = GET_PLAYER(globalCtx); + + if ((this->actor.world.pos.y - this->actor.floorHeight) > 75.0f) { + this->actor.world.pos.y -= 1.0f; + } + + cos = cos_rad(this->unk_2B8); + this->actor.world.pos.y += cos * 1.4f; + this->unk_2B8 += fabsf(cos * 0.18f) + 0.07f; + this->unk_2B0--; + + if (this->unk_2B0 <= 0) { + this->actor.speedXZ = Rand_ZeroFloat(0.5f) + 2.5f; + this->unk_2B0 = Rand_ZeroFloat(10.0f) + 10.0f; + this->unk_2B6 = randPlusMinusPoint5Scaled(1000.0f); + } + + SkelAnime_Update(&this->skelAnime); + this->actor.world.rot.y += this->unk_2B6; + this->actor.shape.rot.y += 0x15E; + + if (!gSaveContext.isNight && (Math_Vec3f_DistXZ(&this->actor.home.pos, &player->actor.world.pos) < 1200.0f)) { + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + func_80897864(this); + } else { + func_80898124(this); + } + + Math_ScaledStepToS(&this->unk_2B2, 4000, 500); + this->unk_2B4 += this->unk_2B2; + Math_StepToF(&this->unk_2C4, 0.075f, 0.005f); + func_800B9010(&this->actor, NA_SE_EN_PIHAT_FLY - SFX_FLAG); +} + +void func_80898124(EnPeehat* this) { + this->actionFunc = func_80898144; + this->actor.speedXZ = 2.5f; +} + +void func_80898144(EnPeehat* this, GlobalContext* globalCtx) { + s32 step; + f32 cos; + Player* player = GET_PLAYER(globalCtx); + + if ((this->actor.world.pos.y - this->actor.floorHeight) > 75.0f) { + this->actor.world.pos.y -= 1.0f; + } else { + this->actor.world.pos.y += 1.0f; + } + cos = cos_rad(this->unk_2B8); + this->actor.world.pos.y += cos * 1.4f; + + cos = cos_rad(this->unk_2B8); + this->unk_2B8 += fabsf(cos * 0.18f) + 0.07f; + + step = Math_Vec3f_Yaw(&this->actor.world.pos, &this->actor.home.pos); + Math_ScaledStepToS(&this->actor.world.rot.y, step, 0x258); + Math_ScaledStepToS(&this->actor.shape.rot.x, 0x1194, 0x258); + + this->actor.shape.rot.y += 0x15E; + this->unk_2B4 += this->unk_2B2; + + if (Math_Vec3f_DistXZ(&this->actor.world.pos, &this->actor.home.pos) < 2.0f) { + func_80897D00(this); + } + + if (!gSaveContext.isNight && (Math_Vec3f_DistXZ(&this->actor.home.pos, &player->actor.world.pos) < 1200.0f)) { + func_80897864(this); + } + func_800B9010(&this->actor, NA_SE_EN_PIHAT_FLY - SFX_FLAG); +} + +void func_808982E0(EnPeehat* this) { + Animation_MorphToPlayOnce(&this->skelAnime, &object_ph_Anim_000844, -4.0f); + this->actor.speedXZ = -9.0f; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + this->actionFunc = func_80898338; +} + +void func_80898338(EnPeehat* this, GlobalContext* globalCtx) { + this->unk_2B4 += this->unk_2B2; + SkelAnime_Update(&this->skelAnime); + + if (Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f)) { + if (this->actor.params != 0) { + func_800B3030(globalCtx, &this->actor.world.pos, &gZeroVec3f, &gZeroVec3f, 40, 7, 0); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 30, NA_SE_EN_EXTINCT); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_PIHAT_SM_DEAD); + Actor_MarkForDeath(&this->actor); + } else { + func_80897864(this); + } + } + func_800B9010(&this->actor, NA_SE_EN_PIHAT_FLY - SFX_FLAG); +} + +void func_80898414(EnPeehat* this) { + func_800BE568(&this->actor, &this->colliderSphere); + this->unk_2B2 = 0; + this->actor.speedXZ = 0.0f; + this->actionFunc = func_80898454; +} + +void func_80898454(EnPeehat* this, GlobalContext* globalCtx) { + if (this->unk_2B0 != 0) { + this->unk_2B0--; + } + + Math_StepToF(&this->actor.world.pos.y, this->actor.floorHeight, 8.0f); + + if (this->unk_2B0 == 0) { + func_808971DC(this, globalCtx); + if (this->actor.colChkInfo.health == 0) { + func_808984E0(this); + } else { + func_80897648(this); + } + } +} + +void func_808984E0(EnPeehat* this) { + Animation_MorphToPlayOnce(&this->skelAnime, &object_ph_Anim_000844, -4.0f); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PIHAT_DAMAGE); + this->unk_2B2 = 4000; + this->unk_2B0 = 14; + this->actor.speedXZ = 10.0f; + func_800BCB70(&this->actor, 0x4000, 255, 0, 14); + this->colliderSphere.base.acFlags &= ~AC_ON; + this->unk_2C4 = 0.0f; + if (this->actor.colChkInfo.health == 0) { + this->actor.velocity.y = 6.0f; + } + this->actionFunc = func_80898594; +} + +void func_80898594(EnPeehat* this, GlobalContext* globalCtx) { + SkelAnime_Update(&this->skelAnime); + this->unk_2B4 += this->unk_2B2; + Math_ScaledStepToS(&this->unk_2B2, 4000, 250); + Math_StepToF(&this->actor.world.pos.y, this->actor.floorHeight + 88.5f, 3.0f); + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f); + this->unk_2B0--; + if (this->unk_2B0 <= 0) { + if (this->actor.colChkInfo.health == 0) { + func_80898654(this); + } else { + func_80897EAC(this); + } + } +} + +void func_80898654(EnPeehat* this) { + Animation_PlayLoop(&this->skelAnime, &object_ph_Anim_0005C4); + this->unk_2B0 = 5; + this->unk_2B8 = 0.0f; + this->actionFunc = func_808986A4; +} + +void func_808986A4(EnPeehat* this, GlobalContext* globalCtx) { + if (this->unk_2B0 == 5) { + EnBom* bomb = (EnBom*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_BOM, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0x602, 0); + + if (bomb != NULL) { + bomb->timer = 0; + } + } + + this->unk_2B0--; + + if (this->unk_2B0 == 0) { + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0xE0); + Actor_MarkForDeath(&this->actor); + } +} + +void func_8089874C(EnPeehat* this, GlobalContext* globalCtx) { + if (this->colliderTris.base.acFlags & AC_BOUNCED) { + this->colliderTris.base.acFlags &= ~AC_BOUNCED; + this->colliderSphere.base.acFlags &= ~AC_HIT; + return; + } + + if (this->colliderSphere.base.acFlags & AC_HIT) { + this->colliderSphere.base.acFlags &= ~AC_HIT; + if ((this->unk_2AE != 10) || !(this->colliderSphere.info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) { + if (!Actor_ApplyDamage(&this->actor)) { + Enemy_StartFinishingBlow(globalCtx, &this->actor); + } + + this->colliderTris.base.atFlags &= ~(AT_HIT | AT_ON); + func_800BE258(&this->actor, &this->colliderSphere.info); + func_808971DC(this, globalCtx); + + if (this->actor.colChkInfo.damageEffect == 5) { + this->unk_2B0 = 40; + func_800BCB70(&this->actor, 0, 255, 0, 40); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->unk_2CC = 1.1f; + this->unk_2C8 = 2.0f; + this->unk_2AE = 32; + func_80898414(this); + } else if (this->actor.colChkInfo.damageEffect == 1) { + this->unk_2B0 = 40; + func_800BCB70(&this->actor, 0, 200, 0, 40); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + func_80898414(this); + } else if (this->actor.colChkInfo.damageEffect == 3) { + func_80897170(this); + if (this->actor.colChkInfo.health == 0) { + this->unk_2B0 = 3; + this->colliderSphere.base.acFlags &= ~AC_ON; + } + func_80898414(this); + } else { + if (this->actor.colChkInfo.damageEffect == 2) { + this->unk_2C8 = 4.0f; + this->unk_2CC = 2.1f; + this->unk_2AE = 0; + } else if (this->actor.colChkInfo.damageEffect == 4) { + this->unk_2C8 = 4.0f; + this->unk_2CC = 1.1f; + this->unk_2AE = 20; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, + this->colliderSphere.info.bumper.hitPos.x, this->colliderSphere.info.bumper.hitPos.y, + this->colliderSphere.info.bumper.hitPos.z, 0, 0, 0, CLEAR_TAG_LARGE_LIGHT_RAYS); + } + func_800BE568(&this->actor, &this->colliderSphere); + func_808984E0(this); + } + } + } else if ((this->unk_2AE == 10) && (this->colliderCylinder.base.acFlags & AC_HIT) && + ((this->unk_2AE != 10) || !(this->colliderCylinder.info.acHitInfo->toucher.dmgFlags & 0xDB0B3))) { + func_808971DC(this, globalCtx); + this->actor.colorFilterTimer = 0; + func_80897648(this); + } +} + +void EnPeehat_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnPeehat* this = THIS; + + if (thisx->params == 0) { + func_8089874C(this, globalCtx); + } + Actor_SetVelocityAndMoveYRotationAndGravity(thisx); + Actor_UpdateBgCheckInfo(globalCtx, thisx, 25.0f, 30.0f, 30.0f, 5); + + this->actionFunc(this, globalCtx); + + if ((globalCtx->gameplayFrames % 128) == 0) { + this->unk_2C0 = Rand_ZeroFloat(0.25f) + 0.5f; + } + + this->unk_2BC += this->unk_2C0; + if (thisx->params == 0) { + if (this->actionFunc == func_80897910) { + Math_ScaledStepToS(&thisx->shape.rot.x, 6000, 300); + } else { + Math_ScaledStepToS(&thisx->shape.rot.x, 0, 300); + } + } else { + Actor_SetHeight(thisx, 0.0f); + } + + Collider_UpdateCylinder(thisx, &this->colliderCylinder); + this->colliderCylinder.dim.pos.y += (s16)(thisx->shape.yOffset * thisx->scale.y); + if (this->colliderCylinder.base.ocFlags1 & OC1_ON) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base); + } + + if (thisx->params == 0) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere.base); + if (this->colliderSphere.base.acFlags & AC_ON) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderSphere.base); + } + } + + if (this->colliderTris.base.atFlags & AT_HIT) { + this->colliderTris.base.atFlags &= ~AT_HIT; + func_808982E0(this); + } + + if (this->colliderTris.base.atFlags & AT_ON) { + thisx->flags |= 0x1000000; + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->colliderTris.base); + if (thisx->params == 0) { + Vec3f sp74; + CollisionPoly* sp70; + s32 sp6C; + s32 i; + + sp70 = NULL; + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderTris.base); + + for (i = 1; i >= 0; i--) { + if (BgCheck_EntityLineTest1(&globalCtx->colCtx, &thisx->world.pos, &this->unk_2D4[i], &sp74, &sp70, 1, + 1, 0, 1, &sp6C)) { + func_800BBFB0(globalCtx, &sp74, 0.0f, 1, 300, 150, 1); + func_80897258(globalCtx, this, &sp74, 0.0f, 1.5f); + } + } + } + } + + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->colliderCylinder.base); + + if (this->actionFunc != func_80898454) { + Math_StepToF(&this->unk_2C4, 0.0f, 0.001f); + } + + if (this->unk_2C8 > 0.0f) { + if (this->unk_2AE != 10) { + Math_StepToF(&this->unk_2C8, 0.0f, 0.05f); + if (this->unk_2AE == 0) { + this->unk_2CC = (this->unk_2C8 + 1.0f) * 1.05f; + this->unk_2CC = CLAMP_MAX(this->unk_2CC, 2.1f); + } else { + this->unk_2CC = (this->unk_2C8 + 1.0f) * 0.55f; + this->unk_2CC = CLAMP_MAX(this->unk_2CC, 1.1f); + } + } else if (!Math_StepToF(&this->unk_2D0, 1.1f, 0.0275f)) { + func_800B9010(thisx, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } + } +} + +s32 EnPeehat_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnPeehat* this = THIS; + s32 pad; + + if (limbIndex == 4) { + rot->x = -this->unk_2B4; + } else if ((limbIndex == 3) || + ((limbIndex == 23) && ((this->actionFunc == func_80898594) || (this->actionFunc == func_80897520)))) { + OPEN_DISPS(globalCtx->state.gfxCtx); + Gfx* gfx = POLY_OPA_DISP; + + Matrix_StatePush(); + Matrix_RotateStateAroundXAxis(this->unk_2BC * 0.115f); + Matrix_InsertYRotation_f(this->unk_2BC * 0.13f, MTXMODE_APPLY); + Matrix_InsertZRotation_f(this->unk_2BC * 0.1f, MTXMODE_APPLY); + Matrix_Scale(1.0f - this->unk_2C4, this->unk_2C4 + 1.0f, 1.0f - this->unk_2C4, MTXMODE_APPLY); + Matrix_InsertZRotation_f(-(this->unk_2BC * 0.1f), MTXMODE_APPLY); + Matrix_InsertYRotation_f(-(this->unk_2BC * 0.13f), MTXMODE_APPLY); + Matrix_RotateStateAroundXAxis(-(this->unk_2BC * 0.115f)); + + gSPMatrix(&gfx[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&gfx[1], *dList); + + Matrix_StatePop(); + + POLY_OPA_DISP = &gfx[2]; + + CLOSE_DISPS(globalCtx->state.gfxCtx); + return true; + } + return false; +} + +void EnPeehat_PostLimbDraw(GlobalContext* globalCtx2, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Vec3f D_80899570[] = { + { 1300.0f, 1200.0f, 0.0f }, + { 1300.0f, -1200.0f, 0.0f }, + { 1300.0f, 0.0f, 1200.0f }, + { 1300.0f, 0.0f, -1200.0f }, + }; + static s8 D_808995A0[] = { + -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 2, -1, -1, 4, -1, -1, 6, -1, -1, 8, -1, -1, 10, -1, + }; + GlobalContext* globalCtx = globalCtx2; + EnPeehat* this = THIS; + s32 i; + s32 index = D_808995A0[limbIndex]; + Gfx* gfx; + + if (index != -1) { + Matrix_GetStateTranslationAndScaledX(2000.0f, &this->unk_2EC[index]); + Matrix_GetStateTranslationAndScaledX(4000.0f, &this->unk_2EC[index + 1]); + } + + if (limbIndex == 4) { + Matrix_GetStateTranslationAndScaledZ(5500.0f, &this->unk_2D4[0]); + Matrix_GetStateTranslationAndScaledZ(-5500.0f, &this->unk_2D4[1]); + } else if ((limbIndex == 3) && (thisx->params == 0)) { + Vec3f* vec = &D_80899570[0]; + Vec3f* vec2 = &this->unk_2EC[12]; + + for (i = 0; i < ARRAY_COUNT(D_80899570); i++, vec++, vec2++) { + Matrix_MultiplyVector3fByState(vec, vec2); + } + + Matrix_GetStateTranslationAndScaledX(3000.0f, vec2++); + Matrix_GetStateTranslationAndScaledX(-400.0f, vec2); + + OPEN_DISPS(globalCtx->state.gfxCtx); + gfx = POLY_OPA_DISP; + + Matrix_InsertTranslation(-1000.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Collider_UpdateSphere(0, &this->colliderSphere); + Matrix_InsertTranslation(500.0f, 0.0f, 0.0f, MTXMODE_APPLY); + Matrix_InsertYRotation_f(3.2f, MTXMODE_APPLY); + Matrix_Scale(0.3f, 0.2f, 0.2f, MTXMODE_APPLY); + + gSPMatrix(&gfx[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(&gfx[1], *dList); + + POLY_OPA_DISP = &gfx[2]; + Math_Vec3s_ToVec3f(&this->actor.focus.pos, &this->colliderSphere.dim.worldSphere.center); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void EnPeehat_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnPeehat* this = THIS; + Vec3f sp58; + Vec3f sp4C; + Vec3f sp40; + s32 i; + + func_8012C28C(globalCtx->state.gfxCtx); + + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnPeehat_OverrideLimbDraw, + (this->actor.params == 0) ? EnPeehat_PostLimbDraw : NULL, &this->actor); + + if ((this->actor.speedXZ != 0.0f) || (this->actor.velocity.y != 0.0f)) { + Matrix_GetStateTranslationAndScaledZ(4500.0f, &sp40); + Matrix_GetStateTranslationAndScaledZ(-4500.0f, &sp4C); + Matrix_GetStateTranslationAndScaledX(4500.0f, &sp58); + Collider_SetTrisVertices(&this->colliderTris, 0, &sp40, &sp4C, &sp58); + Matrix_GetStateTranslationAndScaledX(-4500.0f, &sp58); + Collider_SetTrisVertices(&this->colliderTris, 1, &sp40, &sp58, &sp4C); + } + + if (this->unk_2AE == 0) { + for (i = 0; i < ARRAY_COUNT(this->unk_2EC); i++) { + this->unk_2EC[i].y -= 50.0f; + } + } + + func_800BE680(globalCtx, &this->actor, this->unk_2EC, ARRAY_COUNT(this->unk_2EC), this->unk_2CC, this->unk_2D0, + this->unk_2C8, this->unk_2AE); +} diff --git a/src/overlays/actors/ovl_En_Peehat/z_en_peehat.h b/src/overlays/actors/ovl_En_Peehat/z_en_peehat.h index c6303311a..0aee3a742 100644 --- a/src/overlays/actors/ovl_En_Peehat/z_en_peehat.h +++ b/src/overlays/actors/ovl_En_Peehat/z_en_peehat.h @@ -8,10 +8,31 @@ struct EnPeehat; typedef void (*EnPeehatActionFunc)(struct EnPeehat*, GlobalContext*); typedef struct EnPeehat { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x164]; - /* 0x02A8 */ EnPeehatActionFunc actionFunc; - /* 0x02AC */ char unk_2AC[0x294]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[24]; + /* 0x188 */ Vec3s morphTable[24]; + /* 0x2A8 */ EnPeehatActionFunc actionFunc; + /* 0x2AC */ u8 unk_2AC; + /* 0x2AD */ s8 unk_2AD; + /* 0x2AE */ u8 unk_2AE; + /* 0x2B0 */ s16 unk_2B0; + /* 0x2B2 */ s16 unk_2B2; + /* 0x2B4 */ s16 unk_2B4; + /* 0x2B6 */ s16 unk_2B6; + /* 0x2B8 */ f32 unk_2B8; + /* 0x2BC */ f32 unk_2BC; + /* 0x2C0 */ f32 unk_2C0; + /* 0x2C4 */ f32 unk_2C4; + /* 0x2C8 */ f32 unk_2C8; + /* 0x2CC */ f32 unk_2CC; + /* 0x2D0 */ f32 unk_2D0; + /* 0x2D4 */ Vec3f unk_2D4[2]; + /* 0x2EC */ Vec3f unk_2EC[18]; + /* 0x3C4 */ ColliderCylinder colliderCylinder; + /* 0x410 */ ColliderSphere colliderSphere; + /* 0x468 */ ColliderTris colliderTris; + /* 0x488 */ ColliderTrisElement colliderTriElements[2]; } EnPeehat; // size = 0x540 extern const ActorInit En_Peehat_InitVars; diff --git a/src/overlays/actors/ovl_En_Pm/z_en_pm.c b/src/overlays/actors/ovl_En_Pm/z_en_pm.c index 2cf6b353f..28ed05d9d 100644 --- a/src/overlays/actors/ovl_En_Pm/z_en_pm.c +++ b/src/overlays/actors/ovl_En_Pm/z_en_pm.c @@ -315,7 +315,7 @@ Actor* func_80AF7CB0(EnPm* this, GlobalContext* globalCtx, u8 actorCat, s16 acto Actor* actor; while (true) { - actor = func_ActorCategoryIterateById(globalCtx, phi_s0, actorCat, actorId); + actor = SubS_FindActor(globalCtx, phi_s0, actorCat, actorId); phi_s0 = actor; if (actor == NULL) { @@ -338,7 +338,7 @@ Actor* func_80AF7CB0(EnPm* this, GlobalContext* globalCtx, u8 actorCat, s16 acto return phi_s0; } -Actor* func_80AF7D60(GlobalContext* globalCtx, s32 arg1) { +EnDoor* func_80AF7D60(GlobalContext* globalCtx, s32 arg1) { s32 phi_a1; switch (arg1) { @@ -367,7 +367,7 @@ Actor* func_80AF7D60(GlobalContext* globalCtx, s32 arg1) { return NULL; } - return func_8013A7C0(globalCtx, phi_a1); + return SubS_FindDoor(globalCtx, phi_a1); } Actor* func_80AF7DC4(EnPm* this, GlobalContext* globalCtx, s32 arg2) { @@ -375,7 +375,7 @@ Actor* func_80AF7DC4(EnPm* this, GlobalContext* globalCtx, s32 arg2) { Actor* actor; while (true) { - actor = func_ActorCategoryIterateById(globalCtx, phi_s0, ACTORCAT_PROP, ACTOR_EN_PST); + actor = SubS_FindActor(globalCtx, phi_s0, ACTORCAT_PROP, ACTOR_EN_PST); phi_s0 = actor; if (actor == NULL) { @@ -671,7 +671,7 @@ UNK_TYPE* func_80AF8540(EnPm* this, GlobalContext* globalCtx) { return D_80AFB650; default: - if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEI) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEIS_MASK) { return D_80AFB744; } @@ -861,7 +861,7 @@ void func_80AF8C68(EnPm* this, GlobalContext* globalCtx) { this->unk_360 = 0.0f; } Math_SmoothStepToF(&this->unk_364, this->unk_360, 0.8f, 40.0f, 10.0f); - Matrix_InsertTranslation(this->unk_364, 0.0f, 0.0f, 1); + Matrix_InsertTranslation(this->unk_364, 0.0f, 0.0f, MTXMODE_APPLY); this->unk_388 = sp28; } @@ -942,7 +942,7 @@ s32 func_80AF8ED4(EnPm* this, GlobalContext* globalCtx, struct_80133038_arg2* ar s32 func_80AF9008(EnPm* this, GlobalContext* globalCtx, struct_80133038_arg2* arg2) { u16 sp56 = gSaveContext.time - 0x3FFC; u8 sp55 = this->actor.params & 0xFF; - Actor* sp50; + EnDoor* sp50; Vec3s* sp4C; Vec3f sp40; Vec3f sp34; @@ -955,7 +955,7 @@ s32 func_80AF9008(EnPm* this, GlobalContext* globalCtx, struct_80133038_arg2* ar this->unk_234 = func_8013BB34(globalCtx, sp55, D_80AFB430[arg2->unk0]); } - if ((sp50 != NULL) && (sp50->update != NULL)) { + if ((sp50 != NULL) && (sp50->actor.update != NULL)) { if (this->unk_234 != 0) { sp4C = (Vec3s*)Lib_SegmentedToVirtual(this->unk_234->points); Math_Vec3s_ToVec3f(&sp40, &sp4C[0]); @@ -964,7 +964,7 @@ s32 func_80AF9008(EnPm* this, GlobalContext* globalCtx, struct_80133038_arg2* ar Math_Vec3f_Copy(&this->unk_278, &sp34); this->actor.world.rot.y = Math_Vec3f_Yaw(&sp40, &sp34); Math_Vec3f_Copy(&this->actor.world.pos, &sp40); - temp = this->actor.world.rot.y - sp50->shape.rot.y; + temp = this->actor.world.rot.y - sp50->actor.shape.rot.y; if (ABS_ALT(temp) <= 0x4000) { this->unk_260 = -0x4B; } else { @@ -1409,7 +1409,7 @@ s32 func_80AF9BF8(EnPm* this, GlobalContext* globalCtx, struct_80133038_arg2* ar } s32 func_80AF9D04(EnPm* this, GlobalContext* globalCtx) { - EnDoor* sp44 = (EnDoor*)func_80AF7D60(globalCtx, this->unk_258); + EnDoor* sp44 = func_80AF7D60(globalCtx, this->unk_258); Vec3f sp38; Vec3f* sp28; f32 temp; @@ -1449,7 +1449,7 @@ s32 func_80AF9E7C(EnPm* this, GlobalContext* globalCtx) { func_8013AF00(sp7C, 3, this->unk_234->count + 3); if (!(this->unk_356 & 8)) { - sp58 = D_801D15B0; + sp58 = gZeroVec3f; func_8013B6B0(this->unk_234, &this->unk_244, &this->unk_254, this->unk_24C, this->unk_248, &this->unk_250, sp7C, &sp58, this->unk_374); func_8013B878(globalCtx, this->unk_234, this->unk_250, &sp58); @@ -1468,7 +1468,7 @@ s32 func_80AF9E7C(EnPm* this, GlobalContext* globalCtx) { sp58 = this->actor.world.pos; } - this->unk_238 = D_801D15B0; + this->unk_238 = gZeroVec3f; if (func_8013B6B0(this->unk_234, &this->unk_244, &this->unk_254, this->unk_24C, this->unk_248, &this->unk_250, sp7C, &this->unk_238, this->unk_374)) { @@ -1827,7 +1827,7 @@ void func_80AFAA44(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* switch (limbIndex) { case 15: if (ActorCutscene_GetCurrentIndex() == -1) { - Matrix_MultiplyVector3fByState(&D_801D15B0, &this->actor.focus.pos); + Matrix_MultiplyVector3fByState(&gZeroVec3f, &this->actor.focus.pos); Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.world.rot); } if ((this->unk_356 & 0x8000) && !(gSaveContext.weekEventReg[90] & 4)) { @@ -1843,10 +1843,10 @@ void func_80AFAA44(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* case 8: if ((this->unk_258 == 9) || (this->unk_258 == 20) || (this->unk_258 == 21) || (this->unk_258 == 22)) { - Matrix_MultiplyVector3fByState(&D_801D15B0, &sp2C); + Matrix_MultiplyVector3fByState(&gZeroVec3f, &sp2C); Math_Vec3f_ToVec3s(&this->colliderSphere.dim.worldSphere.center, &sp2C); } else if (this->unk_258 == 24) { - Matrix_MultiplyVector3fByState(&D_801D15B0, &sp2C); + Matrix_MultiplyVector3fByState(&gZeroVec3f, &sp2C); Math_Vec3f_ToVec3s(&this->colliderSphere.dim.worldSphere.center, &sp2C); } func_80AF8890(this, gfx, 2); diff --git a/src/overlays/actors/ovl_En_Pm/z_en_pm.h b/src/overlays/actors/ovl_En_Pm/z_en_pm.h index d571f43bd..6d545373b 100644 --- a/src/overlays/actors/ovl_En_Pm/z_en_pm.h +++ b/src/overlays/actors/ovl_En_Pm/z_en_pm.h @@ -24,11 +24,11 @@ typedef struct EnPm { /* 0x0250 */ s32 unk_250; /* 0x0254 */ s32 unk_254; /* 0x0258 */ u8 unk_258; - /* 0x026C */ UNK_TYPE* unk_25C; + /* 0x025C */ UNK_TYPE* unk_25C; /* 0x0260 */ s8 unk_260; /* 0x0264 */ s32 unk_264; /* 0x0268 */ Actor* unk_268; - /* 0x0268 */ Vec3f unk_26C; + /* 0x026C */ Vec3f unk_26C; /* 0x0278 */ Vec3f unk_278; /* 0x0284 */ Vec3f unk_284; /* 0x0290 */ Vec3s unk_290; diff --git a/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c b/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c index 1bb44aa02..6f267771b 100644 --- a/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c +++ b/src/overlays/actors/ovl_En_Po_Sisters/z_en_po_sisters.c @@ -5,6 +5,7 @@ */ #include "z_en_po_sisters.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x00005015 @@ -725,7 +726,7 @@ void func_80B1BE4C(EnPoSisters* this, s32 arg1) { sp34.x = this->actor.world.pos.x; sp34.y = this->actor.world.pos.y + 45.0f; sp34.z = this->actor.world.pos.z; - func_800B3030(arg1, &sp34, &D_801D15B0, &D_801D15B0, 150, 0, 3); + func_800B3030(arg1, &sp34, &gZeroVec3f, &gZeroVec3f, 150, 0, 3); } Lights_PointSetColorAndRadius(&this->lightInfo, 0, 0, 0, 0); this->actionFunc = func_80B1BF2C; @@ -1189,7 +1190,7 @@ void EnPoSisters_Draw(Actor* thisx, GlobalContext* globalCtx) { Matrix_Scale(phi_f20, phi_f20, phi_f20, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, D_0407D590); + gSPDisplayList(POLY_XLU_DISP++, gGameplayKeepDrawFlameDL); } func_800BE680(globalCtx, &this->actor, this->unk_28C, ARRAY_COUNT(this->unk_28C), diff --git a/src/overlays/actors/ovl_En_Poh/z_en_poh.c b/src/overlays/actors/ovl_En_Poh/z_en_poh.c index 08fbedeaf..f9dc6ddf4 100644 --- a/src/overlays/actors/ovl_En_Poh/z_en_poh.c +++ b/src/overlays/actors/ovl_En_Poh/z_en_poh.c @@ -203,7 +203,7 @@ void func_80B2C910(Vec3f* vec, GlobalContext* globalCtx) { } Math_Vec3f_ScaleAndStore(&sp20, temp_f0, vec); } else { - Math_Vec3f_Copy(vec, &D_801D15B0); + Math_Vec3f_Copy(vec, &gZeroVec3f); } } @@ -426,13 +426,13 @@ void func_80B2D300(EnPoh* this, GlobalContext* globalCtx) { sp44.z = (Math_CosS(sp38) * 23.0f) + this->actor.world.pos.z; } sp36 = (this->unk_18E * 10) + 80; - func_800B3030(globalCtx, &sp44, &D_80B2F710, &D_801D15B0, sp36, 0, 2); + func_800B3030(globalCtx, &sp44, &D_80B2F710, &gZeroVec3f, sp36, 0, 2); sp44.x = (2.0f * this->actor.world.pos.x) - sp44.x; sp44.z = (2.0f * this->actor.world.pos.z) - sp44.z; - func_800B3030(globalCtx, &sp44, &D_80B2F710, &D_801D15B0, sp36, 0, 2); + func_800B3030(globalCtx, &sp44, &D_80B2F710, &gZeroVec3f, sp36, 0, 2); sp44.x = this->actor.world.pos.x; sp44.z = this->actor.world.pos.z; - func_800B3030(globalCtx, &sp44, &D_80B2F710, &D_801D15B0, sp36, 0, 2); + func_800B3030(globalCtx, &sp44, &D_80B2F710, &gZeroVec3f, sp36, 0, 2); } else if (this->unk_18E == 28) { func_80B2DC50(this, globalCtx); } else if (this->unk_18E > 18) { @@ -893,7 +893,8 @@ void EnPoh_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Ve if (limbIndex == 18) { if ((this->actionFunc == func_80B2D300) && (this->unk_18E >= 19) && (this->actor.scale.x != 0.0f)) { - Matrix_Scale(0.01f / this->actor.scale.x, 0.01f / this->actor.scale.x, 0.01f / this->actor.scale.x, 1); + Matrix_Scale(0.01f / this->actor.scale.x, 0.01f / this->actor.scale.x, 0.01f / this->actor.scale.x, + MTXMODE_APPLY); } Matrix_CopyCurrentState(&this->unk_3D8); func_80B2C910(&sp60, globalCtx); diff --git a/src/overlays/actors/ovl_En_Racedog/z_en_racedog.h b/src/overlays/actors/ovl_En_Racedog/z_en_racedog.h index da4ced9dd..4008ba4e1 100644 --- a/src/overlays/actors/ovl_En_Racedog/z_en_racedog.h +++ b/src/overlays/actors/ovl_En_Racedog/z_en_racedog.h @@ -10,7 +10,14 @@ typedef void (*EnRacedogActionFunc)(struct EnRacedog*, GlobalContext*); typedef struct EnRacedog { /* 0x0000 */ Actor actor; /* 0x0144 */ EnRacedogActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x180]; + /* 0x0148 */ char unk_148[0xA0]; + /* 0x01E8 */ s32 unk_1E8; + /* 0x01EC */ char unk_1EC[0xA4]; + /* 0x0290 */ s16 unk_290; + /* 0x0292 */ s16 unk_292; + /* 0x0294 */ char unk_294[0x8]; + /* 0x029C */ s16 unk_29C; + /* 0x029E */ char unk_29E[0x2A]; } EnRacedog; // size = 0x2C8 extern const ActorInit En_Racedog_InitVars; diff --git a/src/overlays/actors/ovl_En_Rail_Skb/z_en_rail_skb.c b/src/overlays/actors/ovl_En_Rail_Skb/z_en_rail_skb.c index a1a88ecbd..280c898ce 100644 --- a/src/overlays/actors/ovl_En_Rail_Skb/z_en_rail_skb.c +++ b/src/overlays/actors/ovl_En_Rail_Skb/z_en_rail_skb.c @@ -4,7 +4,9 @@ * Description: Ikana Graveyard - Circle of Stalchildren */ +#include "overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.h" #include "z_en_rail_skb.h" +#include "objects/object_skb/object_skb.h" #define FLAGS 0x00000015 @@ -15,23 +17,39 @@ void EnRailSkb_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnRailSkb_Update(Actor* thisx, GlobalContext* globalCtx); void EnRailSkb_Draw(Actor* thisx, GlobalContext* globalCtx); +void func_80B70FA0(EnRailSkb* this); void func_80B70FF8(EnRailSkb* this, GlobalContext* globalCtx); void func_80B710E4(EnRailSkb* this, GlobalContext* globalCtx); void func_80B7114C(EnRailSkb* this, GlobalContext* globalCtx); void func_80B7123C(EnRailSkb* this, GlobalContext* globalCtx); +void func_80B712FC(EnRailSkb* this); void func_80B71314(EnRailSkb* this, GlobalContext* globalCtx); +void func_80B71354(EnRailSkb* this); void func_80B713A4(EnRailSkb* this, GlobalContext* globalCtx); +void func_80B71488(EnRailSkb* this); void func_80B714D8(EnRailSkb* this, GlobalContext* globalCtx); +void func_80B7151C(EnRailSkb* this); void func_80B715AC(EnRailSkb* this, GlobalContext* globalCtx); void func_80B716A8(EnRailSkb* this, GlobalContext* globalCtx); +void func_80B717C8(EnRailSkb* this); void func_80B717E0(EnRailSkb* this, GlobalContext* globalCtx); void func_80B718C4(EnRailSkb* this, GlobalContext* globalCtx); +void func_80B71910(EnRailSkb* this); void func_80B71954(EnRailSkb* this, GlobalContext* globalCtx); +void func_80B71A08(EnRailSkb* this); void func_80B71A58(EnRailSkb* this, GlobalContext* globalCtx); +void func_80B71B6C(EnRailSkb* this); void func_80B71BB8(EnRailSkb* this, GlobalContext* globalCtx); +void func_80B71D8C(EnRailSkb* this, GlobalContext* globalCtx, EnRailSkbUnkFunc unkFunc); void func_80B71EA8(EnRailSkb* this, GlobalContext* globalCtx); +void func_80B71F3C(EnRailSkb* this, GlobalContext* globalCtx); +void func_80B72100(EnRailSkb* this, GlobalContext* globalCtx); +void func_80B723F8(EnRailSkb* this); +void func_80B72430(EnRailSkb* this, GlobalContext* globalCtx, s32 arg2); +void func_80B726B4(EnRailSkb* this, GlobalContext* globalCtx); +void func_80B72830(EnRailSkb* this, s16 arg1); +s32 func_80B7285C(EnRailSkb* this); -#if 0 const ActorInit En_Rail_Skb_InitVars = { ACTOR_EN_RAIL_SKB, ACTORCAT_ENEMY, @@ -44,29 +62,57 @@ const ActorInit En_Rail_Skb_InitVars = { (ActorFunc)EnRailSkb_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[2] = { -static ColliderJntSphElementInit D_80B73408[2] = { +static ActorAnimationEntry sAnimations[] = { + { &object_skb_Anim_0064E0, 0.96f, 0.0f, 0.0f, 0, -4.0f }, { &object_skb_Anim_003584, 1.0f, 0.0f, 0.0f, 2, -1.0f }, + { &object_skb_Anim_002190, 0.6f, 0.0f, 0.0f, 3, 4.0f }, { &object_skb_Anim_002AC8, 1.0f, 0.0f, 0.0f, 2, -4.0f }, + { &object_skb_Anim_00270C, 1.0f, 0.0f, 0.0f, 2, -4.0f }, { &object_skb_Anim_00697C, 1.0f, 0.0f, 0.0f, 0, -4.0f }, + { &object_skb_Anim_006D90, 1.0f, 0.0f, 0.0f, 0, -4.0f }, { &object_skb_Anim_001D1C, 1.0f, 0.0f, 0.0f, 0, -4.0f }, + { &object_skb_Anim_003584, 1.0f, 0.0f, 0.0f, 2, -8.0f }, { &object_skb_Anim_003584, 1.0f, 0.0f, 0.0f, 2, -16.0f }, + { &object_skb_Anim_002AC8, 1.0f, 0.0f, 0.0f, 2, -8.0f }, { &object_skb_Anim_0015EC, 1.0f, 0.0f, 0.0f, 2, -8.0f }, + { &object_skb_Anim_0009E4, 1.0f, 0.0f, 0.0f, 0, -8.0f }, +}; + +static ColliderJntSphElementInit sJntSphElementsInit[2] = { { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x04 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_NONE, + }, { 15, { { 0, 0, 0 }, 10 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 1, { { 0, 0, 0 }, 20 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_80B73450 = { - { COLTYPE_HIT6, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 2, D_80B73408, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_HIT6, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 2, + sJntSphElementsInit, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80B73460 = { 2, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 2, 0, 0, 0, MASS_IMMOVABLE }; -// static DamageTable sDamageTable = { -static DamageTable D_80B7346C = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x1), /* Deku Stick */ DMG_ENTRY(1, 0xD), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -101,122 +147,1004 @@ static DamageTable D_80B7346C = { /* Powder Keg */ DMG_ENTRY(1, 0xF), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B73490[] = { +void func_80B708C0(EnRailSkb* this, GlobalContext* globalCtx) { + static s32 D_80B7348C = 0; + Path* path = &globalCtx->setupPathList[ENRAILSKB_GET_FF00(&this->actor)]; + Vec3f sp70; + s32 phi_a3; + + this->unk_230 = Lib_SegmentedToVirtual(path->points); + this->unk_2E0 = D_80B7348C; + this->unk_2E8 = path->count; + + if (D_80B7348C == 0) { + s32 i; + + for (i = 1; (i < this->unk_2E8) && (i < 10); i++) { + D_80B7348C++; + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_RAIL_SKB, 0.0f, 0.0f, 0.0f, 0, 0, + 0, this->actor.params); + } + D_80B7348C = 0; + } + + this->actor.world.pos.x = this->unk_230[this->unk_2E0].x; + this->actor.world.pos.y = this->unk_230[this->unk_2E0].y; + this->actor.world.pos.z = this->unk_230[this->unk_2E0].z; + + if (this->unk_2E0 < (this->unk_2E8 - 1)) { + phi_a3 = this->unk_2E0 + 1; + } else { + phi_a3 = 0; + } + + sp70.x = this->unk_230[phi_a3].x; + sp70.y = this->unk_230[phi_a3].y; + sp70.z = this->unk_230[phi_a3].z; + + this->actor.world.rot.y = this->actor.shape.rot.y = Math_Vec3f_Yaw(&this->actor.world.pos, &sp70); +} + +s32 func_80B70AB4(Vec2f arg0, Vec2f arg1) { + s32 phi_v1; + + if ((arg1.x * arg0.y) < (arg0.x * arg1.y)) { + phi_v1 = 1; + } else { + phi_v1 = -1; + } + return phi_v1; +} + +s32 func_80B70B04(EnRailSkb* this, Vec3f pos) { + s32 pad; + s32 temp_s3; + Vec2f sp60; + Vec2f sp58; + s32 ret = true; + s32 pad2; + s32 i = 0; + s32 j; + + sp60.x = this->unk_230[0].z - pos.z; + sp60.y = this->unk_230[0].x - pos.x; + sp58.x = this->unk_230[1].z - pos.z; + sp58.y = this->unk_230[1].x - pos.x; + j = 1; + temp_s3 = func_80B70AB4(sp60, sp58); + + while (j != 0) { + i++; + + if (j < (this->unk_2E8 - 1)) { + j++; + } else { + j = 0; + } + + sp60.x = this->unk_230[i].z - pos.z; + sp60.y = this->unk_230[i].x - pos.x; + sp58.x = this->unk_230[j].z - pos.z; + sp58.y = this->unk_230[j].x - pos.x; + + if (func_80B70AB4(sp60, sp58) != temp_s3) { + ret = false; + break; + } + } + + return ret; +} + +void func_80B70D24(EnRailSkb* this, GlobalContext* globalCtx) { + Actor* actor = globalCtx->actorCtx.actorList[ACTORCAT_PROP].first; + + while (actor != NULL) { + if ((actor->id == ACTOR_OBJ_HAKAISI) && func_80B70B04(this, actor->world.pos)) { + if (Flags_GetSwitch(globalCtx, (actor->params & 0xFF00) >> 8)) { + Actor_MarkForDeath(&this->actor); + return; + } + this->unk_22C = (ObjHakaisi*)actor; + return; + } + actor = actor->next; + } + Actor_MarkForDeath(&this->actor); +} + +static InitChainEntry sInitChain[] = { ICHAIN_F32(targetArrowOffset, 2000, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_STOP), }; -#endif +void EnRailSkb_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnRailSkb* this = THIS; -extern ColliderJntSphElementInit D_80B73408[2]; -extern ColliderJntSphInit D_80B73450; -extern CollisionCheckInfoInit2 D_80B73460; -extern DamageTable D_80B7346C; -extern InitChainEntry D_80B73490[]; + func_80B708C0(this, globalCtx); + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 36.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_skb_Skel_005EF8, &object_skb_Anim_0064E0, this->jointTable, + this->morphTable, 20); + Collider_InitJntSph(globalCtx, &this->collider); + Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElements); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); -extern UNK_TYPE D_060064E0; + if (Flags_GetSwitch(globalCtx, ENRAILSKB_GET_FF(&this->actor))) { + Actor_MarkForDeath(&this->actor); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B708C0.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + this->actor.speedXZ = 1.6f; + this->actor.hintId = 0x55; + this->unk_3F2 = 0; + this->unk_2E4 = -1; + this->unk_3FC = 0; + this->unk_3FA = 0; + this->unk_403 = 0; + this->unk_3FE = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B70AB4.s") + if (this->actor.parent == NULL) { + this->unk_3F4 = 1; + this->unk_3F6 = 1; + this->unk_3F8 = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B70B04.s") + if ((globalCtx->sceneNum == SCENE_BOTI) && (gSaveContext.sceneSetupIndex == 1) && (globalCtx->csCtx.unk_12 == 0)) { + this->actor.flags |= 0x100000; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B70D24.s") + func_80B70FA0(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/EnRailSkb_Init.s") +void EnRailSkb_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnRailSkb* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/EnRailSkb_Destroy.s") + Collider_DestroyJntSph(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B70FA0.s") +void func_80B70FA0(EnRailSkb* this) { + this->unk_3F2 = 0; + if (this->actionFunc != func_80B716A8) { + func_800BDC5C(&this->skelAnime, sAnimations, 0); + } + this->actionFunc = func_80B70FF8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B70FF8.s") +void func_80B70FF8(EnRailSkb* this, GlobalContext* globalCtx) { + s16 temp_v0 = this->actor.yawTowardsPlayer - this->actor.shape.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B710AC.s") + if (this->actor.xzDistToPlayer < 65.0f) { + if ((ABS_ALT(temp_v0) < 0x2AAA) && (this->unk_3F2 >= 6)) { + func_80B71354(this); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B710E4.s") + if (this->unk_3F2 < 6) { + this->unk_3F2++; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B71114.s") + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.world.rot.y, 1, 0x71C, 0xB6); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B7114C.s") +void func_80B710AC(EnRailSkb* this) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->actionFunc = func_80B710E4; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B71228.s") +void func_80B710E4(EnRailSkb* this, GlobalContext* globalCtx) { + if (this->actor.colorFilterTimer == 0) { + func_80B70FA0(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B7123C.s") +void func_80B71114(EnRailSkb* this) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->actionFunc = func_80B7114C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B712FC.s") +void func_80B7114C(EnRailSkb* this, GlobalContext* globalCtx) { + if (this->unk_3F0 == 0) { + this->unk_3F0 = 0; + this->unk_2F0 = 0.0f; + this->unk_2EC = 0.0f; + if (this->actor.colChkInfo.health != 0) { + func_800BCB70(&this->actor, 0x4000, 255, 0, 8); + func_800BDC5C(&this->skelAnime, sAnimations, 3); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_DAMAGE); + this->unk_402 |= 1; + func_80B712FC(this); + } else { + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_STALKID_DEAD); + func_80B71488(this); + } + } else if (this->unk_3F0 == 1) { + func_80B726B4(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B71314.s") +void func_80B71228(EnRailSkb* this) { + this->actionFunc = func_80B7123C; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B71354.s") +void func_80B7123C(EnRailSkb* this, GlobalContext* globalCtx) { + if (this->unk_3F0 == 0) { + this->unk_3F0 = 0; + this->unk_2F0 = 0.0f; + this->unk_2EC = 0.0f; + if (this->actor.colChkInfo.health != 0) { + func_800BCB70(&this->actor, 0x4000, 255, 0, 8); + func_800BDC5C(&this->skelAnime, sAnimations, 3); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_DAMAGE); + this->unk_402 |= 1; + func_80B712FC(this); + } else { + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_STALKID_DEAD); + func_80B71488(this); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B713A4.s") +void func_80B712FC(EnRailSkb* this) { + this->unk_3F2 = 0; + this->actionFunc = func_80B71314; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B71488.s") +void func_80B71314(EnRailSkb* this, GlobalContext* globalCtx) { + if (this->unk_3F2 >= 6) { + func_80B70FA0(this); + } else { + this->unk_3F2++; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B714D8.s") +void func_80B71354(EnRailSkb* this) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_ATTACK); + func_800BDC5C(&this->skelAnime, sAnimations, 2); + this->actionFunc = func_80B713A4; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B7151C.s") +void func_80B713A4(EnRailSkb* this, GlobalContext* globalCtx) { + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + if ((this->actor.xzDistToPlayer > 65.0f) || (Player_GetMask(globalCtx) == PLAYER_MASK_CAPTAIN)) { + func_80B70FA0(this); + } else { + func_800BDC5C(&this->skelAnime, sAnimations, 2); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B715AC.s") + if (this->actor.xzDistToPlayer > 65.0f) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.world.rot.y, 1, 0x71C, 0xB6); + } else { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 2, 0xAAA, 0xB6); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B71650.s") +void func_80B71488(EnRailSkb* this) { + this->unk_402 |= 0x40; + this->actor.flags &= ~1; + if (this->unk_2E0 != 0) { + this->unk_2E4 = this->unk_2E0 - 1; + } else { + this->unk_2E4 = this->unk_2E8 - 1; + } + this->actionFunc = func_80B714D8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B716A8.s") +void func_80B714D8(EnRailSkb* this, GlobalContext* globalCtx) { + if (this->actor.draw != NULL) { + this->actor.draw = NULL; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B717C8.s") + if (this->unk_2E0 == this->unk_2E4) { + func_80B7151C(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B717E0.s") +void func_80B7151C(EnRailSkb* this) { + this->actor.shape.yOffset = -5000.0f; + this->actor.colChkInfo.health = 2; + this->unk_402 = 0; + this->actor.flags |= 1; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_APPEAR); + this->actor.draw = EnRailSkb_Draw; + this->actor.shape.shadowAlpha = 0; + this->actor.shape.rot.y = this->actor.world.rot.y; + func_800BDC5C(&this->skelAnime, sAnimations, 1); + this->actionFunc = func_80B715AC; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B718B0.s") +void func_80B715AC(EnRailSkb* this, GlobalContext* globalCtx) { + if (Math_SmoothStepToF(&this->actor.shape.yOffset, 0.0f, 0.5f, 500.0f, 10.0f) == 0.0f) { + func_80B70FA0(this); + } else { + func_80B72430(this, globalCtx, 1); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B718C4.s") + if (this->actor.shape.shadowAlpha != 255) { + if (this->actor.shape.shadowAlpha >= 235) { + this->actor.shape.shadowAlpha = 255; + } else { + this->actor.shape.shadowAlpha += 20; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B71910.s") +void func_80B71650(EnRailSkb* this) { + this->unk_3FE = 0; + if (this->actionFunc != func_80B70FF8) { + func_800BDC5C(&this->skelAnime, sAnimations, 0); + } + this->actionFunc = func_80B716A8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B71954.s") +void func_80B716A8(EnRailSkb* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + this->unk_3FE = 1; + func_80B71D8C(this, globalCtx, func_80B723F8); + if (!func_80B7285C(this)) { + func_801518B0(globalCtx, 0x13EC, &this->actor); + this->unk_400 = 0x13EC; + func_80B72830(this, 1); + } else { + func_801518B0(globalCtx, 0x13F5, &this->actor); + this->unk_400 = 0x13F5; + } + func_800BDC5C(&this->skelAnime, sAnimations, 12); + func_80B717C8(this); + } else if ((this->actor.xzDistToPlayer < 100.0f) && !(this->collider.base.acFlags & AC_HIT)) { + func_800B8614(&this->actor, globalCtx, 100.0f); + } + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.world.rot.y, 1, 0x71C, 0xB6); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B71A08.s") +void func_80B717C8(EnRailSkb* this) { + this->unk_3F2 = 0; + this->actionFunc = func_80B717E0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B71A58.s") +void func_80B717E0(EnRailSkb* this, GlobalContext* globalCtx) { + this->unk_3FA = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B71B6C.s") + switch (func_80152498(&globalCtx->msgCtx)) { + case 0: + case 1: + case 2: + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B71BB8.s") + case 3: + if ((globalCtx->gameplayFrames % 2) != 0) { + this->unk_3FA = 1; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B71D8C.s") + case 4: + func_80B72100(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B71DF0.s") + case 5: + func_80B71F3C(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B71EA8.s") + case 6: + if (func_80147624(globalCtx)) { + func_80B71650(this); + } + break; + } + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 1, 0x71C, 0xB6); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B71F3C.s") +void func_80B718B0(EnRailSkb* this) { + this->actionFunc = func_80B718C4; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B72100.s") +void func_80B718C4(EnRailSkb* this, GlobalContext* globalCtx) { + func_80B70D24(this, globalCtx); + if (this->actor.parent == NULL) { + if (this->unk_22C != NULL) { + ObjHakaisi* hakasi = this->unk_22C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B72190.s") + hakasi->unk_198 = 1; + } + } + func_80B71910(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B723F8.s") +void func_80B71910(EnRailSkb* this) { + func_800BDC5C(&this->skelAnime, sAnimations, 0); + this->actionFunc = func_80B71954; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B72430.s") +void func_80B71954(EnRailSkb* this, GlobalContext* globalCtx) { + s16 sp36 = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_22C->actor.world.pos); + f32 sp30 = Math_Vec3f_DistXZ(&this->actor.world.pos, &this->unk_22C->actor.world.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B725C0.s") + Math_SmoothStepToS(&this->actor.shape.rot.y, sp36, 1, 0x71C, 0xB6); + this->actor.world.rot = this->actor.shape.rot; + if (sp30 < 80.0f) { + func_80B71A08(this); + } + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B726B4.s") +void func_80B71A08(EnRailSkb* this) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_ATTACK); + func_800BDC5C(&this->skelAnime, sAnimations, 2); + this->actionFunc = func_80B71A58; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B72830.s") +void func_80B71A58(EnRailSkb* this, GlobalContext* globalCtx) { + s16 sp36 = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_22C->actor.world.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B7285C.s") + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_ATTACK); + func_800BDC5C(&this->skelAnime, sAnimations, 2); + if (this->unk_2E8 < this->unk_22C->actor.colChkInfo.health) { + this->unk_22C->actor.colChkInfo.health--; + } else { + this->unk_22C->actor.colChkInfo.health--; + func_80B71B6C(this); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B72880.s") + if (Animation_OnFrame(&this->skelAnime, 3.0f)) { + if (this->unk_2E8 < this->unk_22C->actor.colChkInfo.health) { + this->unk_22C->actor.colChkInfo.health--; + } else { + this->unk_22C->actor.colChkInfo.health--; + func_80B71B6C(this); + } + } + Math_SmoothStepToS(&this->actor.shape.rot.y, sp36, 1, 0x71C, 0xB6); + this->actor.world.rot = this->actor.shape.rot; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B72970.s") +void func_80B71B6C(EnRailSkb* this) { + this->unk_3F2 = 10; + func_800BDC5C(&this->skelAnime, sAnimations, 0); + this->actionFunc = func_80B71BB8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/EnRailSkb_Update.s") +void func_80B71BB8(EnRailSkb* this, GlobalContext* globalCtx) { + s32 pad; + s32 i; + f32 sp34 = Math_Vec3f_DistXZ(&this->actor.world.pos, &this->unk_22C->actor.world.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B72E88.s") + if (this->unk_3F2 > 0) { + this->unk_3F2--; + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/func_80B7302C.s") + Math_SmoothStepToS(&this->actor.shape.rot.y, + Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_22C->actor.world.pos), 1, 0x71C, 0xB6); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rail_Skb/EnRailSkb_Draw.s") + if ((this->actor.bgCheckFlags & 1) && (this->unk_22C->actor.colChkInfo.health == 0)) { + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + } else { + this->actor.velocity.y += this->actor.gravity; + this->actor.world.pos.y += this->actor.velocity.y; + Math_SmoothStepToF(&this->actor.world.pos.x, this->unk_22C->actor.world.pos.x, 0.6f, 1.6f, 0.1f); + Math_SmoothStepToF(&this->actor.world.pos.z, this->unk_22C->actor.world.pos.z, 0.6f, 1.6f, 0.1f); + } + + if (this->actor.bgCheckFlags & 2) { + Actor_MarkForDeath(&this->actor); + return; + } + + if ((sp34 < 50.0f) && (this->actor.bgCheckFlags & 1)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_ATTACK); + func_800BDC5C(&this->skelAnime, sAnimations, 9); + this->actor.velocity.y = 10.0f; + + for (i = 0; i < 4; i++) { + func_80B72430(this, globalCtx, 0); + } + } +} + +void func_80B71D8C(EnRailSkb* this, GlobalContext* globalCtx, EnRailSkbUnkFunc unkFunc) { + Actor* actor = globalCtx->actorCtx.actorList[ACTORCAT_ENEMY].first; + + while (actor != NULL) { + if (actor->id == ACTOR_EN_RAIL_SKB) { + unkFunc((EnRailSkb*)actor); + } + actor = actor->next; + } +} + +void func_80B71DF0(EnRailSkb* this) { + if (this->actionFunc == func_80B714D8) { + this->actor.shape.yOffset = -5000.0f; + this->actor.colChkInfo.health = 2; + this->unk_402 = 0; + this->actor.flags |= 1; + this->actor.draw = EnRailSkb_Draw; + this->actor.shape.shadowAlpha = 0; + this->actor.shape.rot.y = this->actor.world.rot.y; + } else if ((this->actionFunc == func_80B7114C) && (this->unk_3F0 >= 2)) { + this->unk_3F0 = 0; + } + + func_800BDC5C(&this->skelAnime, sAnimations, 11); + this->actionFunc = func_80B71EA8; +} + +void func_80B71EA8(EnRailSkb* this, GlobalContext* globalCtx) { + if (Math_SmoothStepToF(&this->actor.shape.yOffset, 0.0f, 0.5f, 500.0f, 10.0f) != 0.0f) { + func_80B72430(this, globalCtx, 1); + } + + if (this->actor.shape.shadowAlpha != 255) { + if (this->actor.shape.shadowAlpha >= 235) { + this->actor.shape.shadowAlpha = 255; + } else { + this->actor.shape.shadowAlpha += 20; + } + } +} + +void func_80B71F3C(EnRailSkb* this, GlobalContext* globalCtx) { + if (((this->unk_400 == 0x13ED) || (this->unk_400 == 0x13F5)) && (this->unk_3F2 != 1)) { + func_80B71D8C(this, globalCtx, func_80B71DF0); + func_80B717C8(this); + this->unk_3F2 = 1; + } + + if (func_80147624(globalCtx)) { + switch (this->unk_400) { + case 0x13EC: + func_801518B0(globalCtx, 0x13ED, &this->actor); + this->unk_400 = 0x13ED; + break; + + case 0x13ED: + func_801518B0(globalCtx, 0x13EE, &this->actor); + this->unk_400 = 0x13EE; + break; + + case 0x13EE: + func_801518B0(globalCtx, 0x13EF, &this->actor); + this->unk_400 = 0x13EF; + break; + + case 0x13EF: + case 0x13F5: + func_801518B0(globalCtx, 0x13F0, &this->actor); + this->unk_400 = 0x13F0; + break; + + case 0x13F1: + func_801518B0(globalCtx, 0x13F2, &this->actor); + this->unk_400 = 0x13F2; + break; + + case 0x13F2: + if (this->unk_3FC == 1) { + func_801518B0(globalCtx, 0x13F4, &this->actor); + this->unk_400 = 0x13F4; + } else { + func_801477B4(globalCtx); + func_80B71D8C(this, globalCtx, func_80B71650); + } + break; + + case 0x13F3: + func_801518B0(globalCtx, 0x13F2, &this->actor); + this->unk_400 = 0x13F2; + this->unk_3FC = 1; + break; + + case 0x13F4: + func_801477B4(globalCtx); + func_80B71D8C(this, globalCtx, func_80B718B0); + break; + } + } +} + +void func_80B72100(EnRailSkb* this, GlobalContext* globalCtx) { + if (func_80147624(globalCtx)) { + if (globalCtx->msgCtx.choiceIndex == 0) { + func_8019F208(); + func_801518B0(globalCtx, 0x13F1, &this->actor); + this->unk_400 = 0x13F1; + } else { + func_8019F208(); + func_801518B0(globalCtx, 0x13F3, &this->actor); + this->unk_400 = 0x13F3; + } + } +} + +void func_80B72190(EnRailSkb* this, GlobalContext* globalCtx) { + EnRailSkb* parent; + Vec3f sp38; + s32 pad; + s16 sp32; + + if ((this->actionFunc != func_80B714D8) && + (Animation_OnFrame(&this->skelAnime, 8.0f) || Animation_OnFrame(&this->skelAnime, 15.0f))) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_WALK); + } + + if (this->actor.parent == NULL) { + this->unk_3F4 = this->unk_3F6; + this->unk_3F6 = 1; + + if ((this->actionFunc == func_80B713A4) || (this->actionFunc == func_80B710E4) || + (this->actionFunc == func_80B7114C) || (this->actionFunc == func_80B7123C) || + (this->actionFunc == func_80B717E0)) { + this->unk_3F6 = 0; + } + + if (this->unk_3F4 == 0) { + return; + } + } else { + parent = (EnRailSkb*)this->actor.parent; + + if ((this->actionFunc == func_80B713A4) || (this->actionFunc == func_80B710E4) || + (this->actionFunc == func_80B7114C) || (this->actionFunc == func_80B7123C) || + (this->actionFunc == func_80B717E0)) { + parent->unk_3F6 = 0; + } + + if (parent->unk_3F4 == 0) { + return; + } + } + + if ((this->actionFunc != func_80B71EA8) && (this->actionFunc != func_80B71954) && + (this->actionFunc != func_80B71A58) && (this->actionFunc != func_80B71BB8)) { + sp38.x = this->unk_230[this->unk_2E0].x; + sp38.y = this->unk_230[this->unk_2E0].y; + sp38.z = this->unk_230[this->unk_2E0].z; + sp32 = Math_Vec3f_Yaw(&this->actor.world.pos, &sp38); + + if (Math_Vec3f_DistXZ(&this->actor.world.pos, &sp38) > 100.0f) { + Math_SmoothStepToS(&this->actor.world.rot.y, sp32, 10, 0x3000, 0x100); + } else if (this->unk_2E0 < (this->unk_2E8 - 1)) { + this->unk_2E0++; + } else { + this->unk_2E0 = 0; + } + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + } +} + +void func_80B723F8(EnRailSkb* this) { + this->actor.flags &= ~(4 | 1); + this->actor.flags |= (8 | 1); + this->actor.flags |= 0x100000; + this->actor.hintId = 0xFF; + this->actor.textId = 0; +} + +void func_80B72430(EnRailSkb* this, GlobalContext* globalCtx, s32 arg2) { + Vec3f sp5C = this->actor.world.pos; + Vec3f sp50 = { 0.0f, 8.0f, 0.0f }; + Vec3f sp44 = { 0.0f, -1.5f, 0.0f }; + s16 sp42; + s32 pad; + + if ((globalCtx->gameplayFrames & arg2) == 0) { + sp42 = Rand_Next(); + + sp5C.x += 15.0f * Math_SinS(sp42); + sp5C.y = this->actor.floorHeight; + sp5C.z += 15.0f * Math_CosS(sp42); + + sp44.x = Rand_Centered(); + sp44.z = Rand_Centered(); + + sp50.y += Rand_Centered() * 4.0f; + + EffectSsHahen_Spawn(globalCtx, &sp5C, &sp50, &sp44, 0, (Rand_Next() & 7) + 10, -1, 10, NULL); + func_800BBFB0(globalCtx, &sp5C, 10.0f, 1, 150, 0, 1); + } +} + +void func_80B725C0(EnRailSkb* this, GlobalContext* globalCtx) { + if (this->unk_3F0 > 0) { + this->unk_3F0--; + } + + if (this->actionFunc != func_80B7114C) { + if (this->unk_3F0 < 20) { + if (this->actionFunc == func_80B7123C) { + Math_SmoothStepToF(&this->unk_2F0, 0.0f, 0.5f, 0.03f, 0.0f); + } else { + Math_SmoothStepToF(&this->unk_2F0, 0.0f, 0.5f, 0.01f, 0.0f); + } + this->unk_2EC = this->unk_3F0 * 0.05f; + } else { + Math_SmoothStepToF(&this->unk_2F0, 0.5f, 0.1f, 0.02f, 0.0f); + } + } +} + +void func_80B726B4(EnRailSkb* this, GlobalContext* globalCtx) { + static Color_RGBA8 D_80B734B0 = { 170, 255, 255, 255 }; + static Color_RGBA8 D_80B734B4 = { 200, 200, 255, 255 }; + static Vec3f D_80B734B8 = { 0.0f, -1.0f, 0.0f }; + Vec3f sp84; + s32 i; + s32 end; + s16 yaw; + + if (this->unk_402 & 2) { + end = ARRAY_COUNT(this->unk_234) - 1; + } else { + end = ARRAY_COUNT(this->unk_234); + } + + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 30, NA_SE_EV_ICE_BROKEN); + + for (i = 0; i < end; i++) { + yaw = Math_Vec3f_Yaw(&this->actor.world.pos, &this->unk_234[i]); + + sp84.x = Math_SinS(yaw) * 3.0f; + sp84.z = Math_CosS(yaw) * 3.0f; + sp84.y = (Rand_ZeroOne() * 4.0f) + 4.0f; + + EffectSsEnIce_Spawn(globalCtx, &this->unk_234[i], 0.6f, &sp84, &D_80B734B8, &D_80B734B0, &D_80B734B4, 30); + } +} + +void func_80B72830(EnRailSkb* this, s16 arg1) { + if (this->actor.parent == NULL) { + this->unk_3F8 = arg1; + } else { + ((EnRailSkb*)this->actor.parent)->unk_3F8 = arg1; + } +} + +s32 func_80B7285C(EnRailSkb* this) { + s32 phi_v1; + + if (this->actor.parent == NULL) { + phi_v1 = this->unk_3F8; + } else { + phi_v1 = ((EnRailSkb*)this->actor.parent)->unk_3F8; + } + return phi_v1; +} + +void func_80B72880(EnRailSkb* this, GlobalContext* globalCtx) { + if ((this->actionFunc == func_80B70FF8) || (this->actionFunc == func_80B716A8)) { + if (this->actionFunc != func_80B716A8) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_CAPTAIN) { + this->actor.flags &= ~(4 | 1); + this->actor.flags |= (8 | 1); + this->actor.flags |= 0x100000; + this->actor.hintId = 0xFF; + this->actor.textId = 0; + func_80B71650(this); + } + } else if (Player_GetMask(globalCtx) != PLAYER_MASK_CAPTAIN) { + this->actor.flags &= ~(8 | 1); + this->actor.flags &= ~0x100000; + this->actor.flags |= 5; + this->actor.hintId = 0x55; + this->actor.textId = 0; + func_80B70FA0(this); + } + } +} + +void func_80B72970(EnRailSkb* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 pad; + + if ((this->actionFunc == func_80B714D8) || (this->actionFunc == func_80B7123C) || + (this->actionFunc == func_80B715AC) || (this->actionFunc == func_80B71954) || + (this->actionFunc == func_80B71A58) || (this->actionFunc == func_80B71BB8) || (this->unk_3FE == 1)) { + return; + } + + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + if (this->actionFunc == func_80B7114C) { + switch (this->actor.colChkInfo.damageEffect) { + case 1: + case 3: + case 4: + case 12: + case 13: + return; + + default: + if (this->unk_3F0 >= 2) { + func_80B726B4(this, globalCtx); + } + this->unk_3F0 = 0; + break; + } + } + + if ((Actor_ApplyDamage(&this->actor) == 0) && (this->actor.colChkInfo.damageEffect != 3) && + (this->actor.colChkInfo.damageEffect != 4)) { + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_STALKID_DEAD); + func_80B71488(this); + return; + } + + switch (this->actor.colChkInfo.damageEffect) { + case 11: + this->unk_3F0 = 40; + this->unk_403 = 30; + this->unk_2EC = 1.0f; + this->unk_2F0 = 0.0f; + func_800BCB70(&this->actor, 0, 120, 0, 40); + func_80B710AC(this); + break; + + case 1: + func_800BCB70(&this->actor, 0, 120, 0, 40); + func_80B710AC(this); + break; + + case 2: + this->unk_3F0 = 80; + this->unk_403 = 0; + this->unk_2EC = 1.0f; + this->unk_2F0 = 0.0f; + func_800BCB70(&this->actor, 0x4000, 255, 0, 8); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_DAMAGE); + func_800BDC5C(&this->skelAnime, sAnimations, 3); + this->unk_402 |= 1; + func_80B712FC(this); + break; + + case 3: + if (this->actor.colChkInfo.health != 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_DAMAGE); + this->unk_3F0 = 80; + } else { + this->unk_3F0 = 3; + } + this->unk_403 = 11; + this->unk_2EC = 1.0f; + this->unk_2F0 = 0.5f; + func_800BCB70(&this->actor, 0x4000, 255, 0, 8); + func_80B71114(this); + break; + + case 4: + this->unk_3F0 = 40; + this->unk_403 = 20; + this->unk_2EC = 1.0f; + this->unk_2F0 = 0.5f; + func_800BCB70(&this->actor, 0x4000, 255, 0, 8); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_DAMAGE); + func_800BDC5C(&this->skelAnime, sAnimations, 3); + func_80B71228(this); + break; + + case 12: + case 14: + this->unk_402 |= 1; + + case 15: + if ((player->swordAnimation == 4) || (player->swordAnimation == 11) || (player->swordAnimation == 22) || + (player->swordAnimation == 23)) { + this->unk_402 |= 1; + } + + case 13: + func_800BCB70(&this->actor, 0x4000, 255, 0, 8); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALKID_DAMAGE); + func_800BDC5C(&this->skelAnime, sAnimations, 3); + func_80B712FC(this); + break; + + default: + break; + } + } + + if (this->actionFunc == func_80B713A4) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + if (this->actionFunc != func_80B71314) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void EnRailSkb_Update(Actor* thisx, GlobalContext* globalCtx) { + EnRailSkb* this = THIS; + + this->actionFunc(this, globalCtx); + + func_80B72190(this, globalCtx); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 15.0f, 30.0f, 60.0f, 5); + func_80B72970(this, globalCtx); + + if ((this->actionFunc != func_80B710E4) && (this->actionFunc != func_80B7114C) && + (this->actionFunc != func_80B7123C)) { + SkelAnime_Update(&this->skelAnime); + } + + func_80B72880(this, globalCtx); + func_80B725C0(this, globalCtx); +} + +s32 EnRailSkb_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnRailSkb* this = THIS; + s16 abs; + + if (limbIndex == 11) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + abs = fabsf(Math_SinS(globalCtx->state.frames * 6000) * 95.0f) + 160.0f; + + gDPPipeSync(POLY_OPA_DISP++); + gDPSetEnvColor(POLY_OPA_DISP++, abs, abs, abs, 255); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } else if (limbIndex == 10) { + Vec3f sp24 = { 0.0f, 1000.0f, 0.0f }; + + Matrix_MultiplyVector3fByState(&sp24, &this->actor.focus.pos); + } else if ((limbIndex == 12) && (this->unk_3FA == 1)) { + Matrix_InsertZRotation_s(1820, MTXMODE_APPLY); + } + + if (((limbIndex == 11) || (limbIndex == 12)) && (this->unk_402 & 2)) { + *dList = NULL; + } + + return false; +} + +void EnRailSkb_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Vec3f D_80B734D0 = { 800.0f, 1200.0f, 0.0f }; + EnRailSkb* this = THIS; + + if (!(this->unk_402 & 0x80)) { + Collider_UpdateSpheres(limbIndex, &this->collider); + + if ((limbIndex == 11) && (this->unk_402 & 1) && !(this->unk_402 & 2)) { + func_800BBCEC(&this->actor, globalCtx, 1, dList); + this->unk_402 |= 2; + } else if ((this->unk_402 & 0x40) && ((limbIndex != 11) || !(this->unk_402 & 1)) && (limbIndex != 12)) { + func_800BBCEC(&this->actor, globalCtx, 1, dList); + } + + if (this->unk_3F0 != 0) { + if ((limbIndex == 2) || (limbIndex == 4) || (limbIndex == 5) || (limbIndex == 6) || (limbIndex == 7) || + (limbIndex == 8) || (limbIndex == 9) || (limbIndex == 13) || (limbIndex == 14) || (limbIndex == 15) || + (limbIndex == 16) || (limbIndex == 17) || (limbIndex == 18)) { + Matrix_GetStateTranslation(&this->unk_234[this->unk_2DC]); + this->unk_2DC++; + } else if ((limbIndex == 11) && !(this->unk_402 & 2)) { + Matrix_MultiplyVector3fByState(&D_80B734D0, &this->unk_234[this->unk_2DC]); + this->unk_2DC++; + } + } + } +} + +void EnRailSkb_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnRailSkb* this = THIS; + + this->unk_2DC = 0; + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnRailSkb_OverrideLimbDraw, + EnRailSkb_PostLimbDraw, &this->actor); + if (this->unk_3F0 > 0) { + func_800BE680(globalCtx, &this->actor, this->unk_234, this->unk_2DC, this->unk_2F0, 0.5f, this->unk_2EC, + this->unk_403); + } + + if ((this->unk_402 & 0x40) && !(this->unk_402 & 0x80)) { + this->unk_402 |= 0x80; + } +} diff --git a/src/overlays/actors/ovl_En_Rail_Skb/z_en_rail_skb.h b/src/overlays/actors/ovl_En_Rail_Skb/z_en_rail_skb.h index 90569ea82..23202ef19 100644 --- a/src/overlays/actors/ovl_En_Rail_Skb/z_en_rail_skb.h +++ b/src/overlays/actors/ovl_En_Rail_Skb/z_en_rail_skb.h @@ -6,12 +6,40 @@ struct EnRailSkb; typedef void (*EnRailSkbActionFunc)(struct EnRailSkb*, GlobalContext*); +typedef void (*EnRailSkbUnkFunc)(struct EnRailSkb*); + +#define ENRAILSKB_GET_FF00(thisx) (((thisx)->params >> 8) & 0xFF) +#define ENRAILSKB_GET_FF(thisx) ((thisx)->params & 0xFF) typedef struct EnRailSkb { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xE4]; - /* 0x0228 */ EnRailSkbActionFunc actionFunc; - /* 0x022C */ char unk_22C[0x1D8]; + /* 0x000 */ Actor actor; + /* 0x144 */ ColliderJntSph collider; + /* 0x164 */ ColliderJntSphElement colliderElements[2]; + /* 0x1E4 */ SkelAnime skelAnime; + /* 0x228 */ EnRailSkbActionFunc actionFunc; + /* 0x22C */ ObjHakaisi* unk_22C; + /* 0x230 */ Vec3s* unk_230; + /* 0x234 */ Vec3f unk_234[14]; + /* 0x2DC */ s32 unk_2DC; + /* 0x2E0 */ s32 unk_2E0; + /* 0x2E4 */ s32 unk_2E4; + /* 0x2E8 */ s32 unk_2E8; + /* 0x2EC */ f32 unk_2EC; + /* 0x2F0 */ f32 unk_2F0; + /* 0x2F4 */ Vec3s jointTable[20]; + /* 0x36C */ Vec3s morphTable[20]; + /* 0x3E4 */ UNK_TYPE1 unk3E4[0xC]; + /* 0x3F0 */ s16 unk_3F0; + /* 0x3F2 */ s16 unk_3F2; + /* 0x3F4 */ s16 unk_3F4; + /* 0x3F6 */ s16 unk_3F6; + /* 0x3F8 */ s16 unk_3F8; + /* 0x3FA */ s16 unk_3FA; + /* 0x3FC */ s16 unk_3FC; + /* 0x3FE */ s16 unk_3FE; + /* 0x400 */ u16 unk_400; + /* 0x402 */ u8 unk_402; + /* 0x403 */ u8 unk_403; } EnRailSkb; // size = 0x404 extern const ActorInit En_Rail_Skb_InitVars; diff --git a/src/overlays/actors/ovl_En_Railgibud/z_en_railgibud.c b/src/overlays/actors/ovl_En_Railgibud/z_en_railgibud.c index 6b1d57ea8..de64df7df 100644 --- a/src/overlays/actors/ovl_En_Railgibud/z_en_railgibud.c +++ b/src/overlays/actors/ovl_En_Railgibud/z_en_railgibud.c @@ -611,7 +611,7 @@ void func_80BA6800(EnRailgibud* this, GlobalContext* globalCtx, s32 arg2) { void func_80BA6974(GlobalContext* globalCtx, Vec3f* vec, f32 arg2, s32 arg3, s16 arg4, s16 arg5) { Vec3f sp8C; Vec3f sp80 = { 0.0f, 0.3f, 0.0f }; - Vec3f sp74 = D_801D15B0; + Vec3f sp74 = gZeroVec3f; s32 i; s32 pad; diff --git a/src/overlays/actors/ovl_En_Rd/z_en_rd.c b/src/overlays/actors/ovl_En_Rd/z_en_rd.c index 696e360a6..be62210ea 100644 --- a/src/overlays/actors/ovl_En_Rd/z_en_rd.c +++ b/src/overlays/actors/ovl_En_Rd/z_en_rd.c @@ -1,7 +1,7 @@ /* * File: z_en_rd.c * Overlay: ovl_En_Rd - * Description: Dancing Redead/Gibdo + * Description: Redead/Gibdo (able to dance) */ #include "z_en_rd.h" diff --git a/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.c b/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.c index 6c3afaa6f..07f3ca850 100644 --- a/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.c +++ b/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.c @@ -15,7 +15,11 @@ void EnRecepgirl_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnRecepgirl_Update(Actor* thisx, GlobalContext* globalCtx); void EnRecepgirl_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void EnRecepgirl_SetupWait(EnRecepgirl* this); +void EnRecepgirl_Wait(EnRecepgirl* this, GlobalContext* globalCtx); +void EnRecepgirl_SetupTalk(EnRecepgirl* this); +void EnRecepgirl_Talk(EnRecepgirl* this, GlobalContext* globalCtx); + const ActorInit En_Recepgirl_InitVars = { ACTOR_EN_RECEPGIRL, ACTORCAT_NPC, @@ -28,38 +32,193 @@ const ActorInit En_Recepgirl_InitVars = { (ActorFunc)EnRecepgirl_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80C106C0[] = { +extern TexturePtr D_0600F8F0; +extern TexturePtr D_0600FCF0; +extern TexturePtr D_060100F0; + +static TexturePtr sEyeTextures[] = { &D_0600F8F0, &D_0600FCF0, &D_060100F0, &D_0600FCF0 }; + +static InitChainEntry sInitChain[] = { ICHAIN_U8(targetMode, 6, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 1000, ICHAIN_STOP), }; -#endif +static s32 texturesDesegmented = false; -extern InitChainEntry D_80C106C0[]; +extern AnimationHeader D_06000968; +extern AnimationHeader D_06001384; +extern AnimationHeader D_06009890; +extern AnimationHeader D_0600A280; +extern AnimationHeader D_0600AD98; +extern FlexSkeletonHeader D_06011B60; -extern UNK_TYPE D_06001384; -extern UNK_TYPE D_06009890; -extern UNK_TYPE D_0600A280; +void EnRecepgirl_Init(Actor* thisx, GlobalContext* globalCtx) { + EnRecepgirl* this = THIS; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Init.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06011B60, &D_06009890, this->jointTable, this->morphTable, 24); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Destroy.s") + if (!texturesDesegmented) { + for (i = 0; i < ARRAY_COUNT(sEyeTextures); i++) { + sEyeTextures[i] = Lib_SegmentedToVirtual(sEyeTextures[i]); + } + texturesDesegmented = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C100DC.s") + this->eyeTexIndex = 2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10148.s") + if (Flags_GetSwitch(globalCtx, this->actor.params)) { + this->actor.textId = 0x2ADC; // hear directions again? + } else { + this->actor.textId = 0x2AD9; // "Welcome..." + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C1019C.s") + EnRecepgirl_SetupWait(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10290.s") +void EnRecepgirl_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C102D4.s") +void EnRecepgirl_UpdateEyes(EnRecepgirl* this) { + if (this->eyeTexIndex != 0) { + this->eyeTexIndex++; + if (this->eyeTexIndex == 4) { + this->eyeTexIndex = 0; + } + } else if (Rand_ZeroOne() < 0.02f) { + this->eyeTexIndex++; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Update.s") +void EnRecepgirl_SetupWait(EnRecepgirl* this) { + if (this->skelAnime.animation == &D_06001384) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 5.0f); + } + this->actionFunc = EnRecepgirl_Wait; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10558.s") +void EnRecepgirl_Wait(EnRecepgirl* this, GlobalContext* globalCtx) { + if (SkelAnime_Update(&this->skelAnime) != 0) { + if (this->skelAnime.animation == &D_0600A280) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 5.0f); + } else { + Animation_MorphToLoop(&this->skelAnime, &D_06009890, -4.0f); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10590.s") + if (func_800B84D0(&this->actor, globalCtx) != 0) { + EnRecepgirl_SetupTalk(this); + } else if (Actor_IsActorFacingLink(&this->actor, 0x2000)) { + func_800B8614(&this->actor, globalCtx, 60.0f); + if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEIS_MASK) { + this->actor.textId = 0x2367; // "... doesn't Kafei want to break off his engagement ... ?" + } else if (Flags_GetSwitch(globalCtx, this->actor.params)) { + this->actor.textId = 0x2ADC; // hear directions again? + } else { + this->actor.textId = 0x2AD9; // "Welcome..." + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Draw.s") +void EnRecepgirl_SetupTalk(EnRecepgirl* this) { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600A280, -4.0f); + this->actionFunc = EnRecepgirl_Talk; +} + +void EnRecepgirl_Talk(EnRecepgirl* this, GlobalContext* globalCtx) { + u8 temp_v0_2; + + if (SkelAnime_Update(&this->skelAnime)) { + if (this->skelAnime.animation == &D_0600A280) { + Animation_PlayLoop(&this->skelAnime, &D_06001384); + } else if (this->skelAnime.animation == &D_0600AD98) { + if (this->actor.textId == 0x2ADA) { // Mayor's office is on the left (meeting ongoing) + Animation_MorphToPlayOnce(&this->skelAnime, &D_06000968, 10.0f); + } else { + Animation_MorphToLoop(&this->skelAnime, &D_06009890, 10.0f); + } + } else { + if (this->actor.textId == 0x2ADA) { // Mayor's office is on the left (meeting ongoing) + Animation_MorphToLoop(&this->skelAnime, &D_06009890, 10.0f); + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600A280, -4.0f); + } + } + } + + temp_v0_2 = func_80152498(&globalCtx->msgCtx); + if (temp_v0_2 == 2) { + this->actor.textId = 0x2ADC; // hear directions again? + EnRecepgirl_SetupWait(this); + } else if ((temp_v0_2 == 5) && (func_80147624(globalCtx) != 0)) { + if (this->actor.textId == 0x2AD9) { // "Welcome..." + Actor_SetSwitchFlag(globalCtx, this->actor.params); + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 10.0f); + + if (gSaveContext.weekEventReg[63] & 0x80) { // showed Couple's Mask to meeting + this->actor.textId = 0x2ADF; // Mayor's office is on the left (meeting ended) + } else { + this->actor.textId = 0x2ADA; // Mayor's office is on the left (meeting ongoing) + } + } else if (this->actor.textId == 0x2ADC) { // hear directions again? + Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 10.0f); + this->actor.textId = 0x2ADD; // "So..." + } else { + Animation_MorphToPlayOnce(&this->skelAnime, &D_06000968, 10.0f); + + if (this->actor.textId == 0x2ADD) { // "So..." + this->actor.textId = 0x2ADE; // Mayor's office is on the left, drawing room on the right + } else if (this->actor.textId == 0x2ADA) { // Mayor's office is on the left (meeting ongoing) + this->actor.textId = 0x2ADB; // drawing room on the right + } else { + this->actor.textId = 0x2AE0; // drawing room on the right, don't go in without an appointment + } + } + func_80151938(globalCtx, this->actor.textId); + } +} + +void EnRecepgirl_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnRecepgirl* this = THIS; + Vec3s sp30; + + this->actionFunc(this, globalCtx); + func_800E9250(globalCtx, &this->actor, &this->headRot, &sp30, this->actor.focus.pos); + EnRecepgirl_UpdateEyes(this); +} + +s32 EnRecepgirl_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnRecepgirl* this = THIS; + + if (limbIndex == 5) { + rot->x += this->headRot.y; + } + return false; +} + +void EnRecepgirl_UnkLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnRecepgirl* this = THIS; + + if (limbIndex == 5) { + Matrix_RotateY(0x400 - this->headRot.x, MTXMODE_APPLY); + Matrix_GetStateTranslationAndScaledX(500.0f, &this->actor.focus.pos); + } +} + +void EnRecepgirl_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnRecepgirl* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x08, sEyeTextures[this->eyeTexIndex]); + + func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnRecepgirl_OverrideLimbDraw, NULL, EnRecepgirl_UnkLimbDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.h b/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.h index 0b7cbe073..a6b858192 100644 --- a/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.h +++ b/src/overlays/actors/ovl_En_Recepgirl/z_en_recepgirl.h @@ -8,10 +8,13 @@ struct EnRecepgirl; typedef void (*EnRecepgirlActionFunc)(struct EnRecepgirl*, GlobalContext*); typedef struct EnRecepgirl { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x164]; - /* 0x02A8 */ EnRecepgirlActionFunc actionFunc; - /* 0x02AC */ char unk_2AC[0x8]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[24]; + /* 0x218 */ Vec3s morphTable[24]; + /* 0x2A8 */ EnRecepgirlActionFunc actionFunc; + /* 0x2AC */ u8 eyeTexIndex; + /* 0x2AE */ Vec3s headRot; } EnRecepgirl; // size = 0x2B4 extern const ActorInit En_Recepgirl_InitVars; diff --git a/src/overlays/actors/ovl_En_Rg/z_en_rg.c b/src/overlays/actors/ovl_En_Rg/z_en_rg.c index 6a2b734bd..00f96e291 100644 --- a/src/overlays/actors/ovl_En_Rg/z_en_rg.c +++ b/src/overlays/actors/ovl_En_Rg/z_en_rg.c @@ -1,7 +1,7 @@ /* * File: z_en_rg.c * Overlay: ovl_En_Rg - * Description: Racetrack Goron + * Description: Racing Goron */ #include "z_en_rg.h" diff --git a/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.c b/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.c index f104ff1b2..2dc6842c9 100644 --- a/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.c +++ b/src/overlays/actors/ovl_En_River_Sound/z_en_river_sound.c @@ -1,7 +1,7 @@ /* * File: z_en_river_sound.c * Overlay: ovl_En_River_Sound - * Description: + * Description: Various environment Sfx (e.g., ocean waves, gulls, waterfall, lava, etc) */ #include "z_en_river_sound.h" diff --git a/src/overlays/actors/ovl_En_Rr/z_en_rr.c b/src/overlays/actors/ovl_En_Rr/z_en_rr.c index 1d44f721c..f01235327 100644 --- a/src/overlays/actors/ovl_En_Rr/z_en_rr.c +++ b/src/overlays/actors/ovl_En_Rr/z_en_rr.c @@ -23,7 +23,11 @@ void func_808FB42C(EnRr* this, GlobalContext* globalCtx); void func_808FB680(EnRr* this, GlobalContext* globalCtx); void func_808FB710(EnRr* this, GlobalContext* globalCtx); -#if 0 +void func_808FAD1C(EnRr* this, GlobalContext* globalCtx); +void func_808FB398(EnRr* this, GlobalContext* globalCtx); + +extern Gfx D_06000470[]; + const ActorInit En_Rr_InitVars = { ACTOR_EN_RR, ACTORCAT_ENEMY, @@ -36,22 +40,47 @@ const ActorInit En_Rr_InitVars = { (ActorFunc)EnRr_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_808FC150 = { - { COLTYPE_HIT0, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK1, { 0x20000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit1 = { + { + COLTYPE_HIT0, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK1, + { 0x20000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 45, 60, 0, { 0, 0, 0 } }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_808FC17C = { - { COLTYPE_HIT0, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK1, { 0x20000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NONE, BUMP_ON | BUMP_HOOKABLE, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit2 = { + { + COLTYPE_HIT0, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK1, + { 0x20000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NONE, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_NONE, + }, { 30, 45, -30, { 0, 0, 0 } }, }; -// static DamageTable sDamageTable = { -static DamageTable D_808FC1A8 = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(3, 0x0), /* Horse trample */ DMG_ENTRY(1, 0x0), @@ -86,11 +115,9 @@ static DamageTable D_808FC1A8 = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -// sColChkInfoInit -static CollisionCheckInfoInit D_808FC1C8 = { 3, 45, 60, 250 }; +static CollisionCheckInfoInit sColChkInfoInit = { 3, 45, 60, 250 }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_808FC1D0[] = { +static InitChainEntry sInitChain[] = { ICHAIN_S8(hintId, 55, ICHAIN_CONTINUE), ICHAIN_U8(targetMode, 2, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -400, ICHAIN_CONTINUE), @@ -98,72 +125,816 @@ static InitChainEntry D_808FC1D0[] = { ICHAIN_F32(targetArrowOffset, 30, ICHAIN_STOP), }; -#endif +void EnRr_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnRr* this = THIS; -extern ColliderCylinderInit D_808FC150; -extern ColliderCylinderInit D_808FC17C; -extern DamageTable D_808FC1A8; -extern CollisionCheckInfoInit D_808FC1C8; -extern InitChainEntry D_808FC1D0[]; + Actor_ProcessInitChain(&this->actor, sInitChain); + Collider_InitAndSetCylinder(globalCtx, &this->collider1, &this->actor, &sCylinderInit1); + Collider_InitAndSetCylinder(globalCtx, &this->collider2, &this->actor, &sCylinderInit2); + if (this->actor.params != ENRR_3) { + this->actor.scale.y = 0.015f; + this->actor.scale.x = 0.019f; + this->actor.scale.z = 0.019f; + } else { + this->actor.scale.y = 0.022499999f; + this->actor.scale.x = 0.028499998f; + this->actor.scale.z = 0.028499998f; + this->collider1.dim.radius = this->collider1.dim.radius * 1.5f; + this->collider1.dim.height = this->collider1.dim.height * 1.5f; + this->collider2.dim.radius = this->collider2.dim.radius * 1.5f; + this->collider2.dim.height = this->collider2.dim.height * 1.5f; + this->collider2.dim.yShift = this->collider2.dim.yShift * 1.5f; + } -extern UNK_TYPE D_06000470; + Collider_UpdateCylinder(&this->actor, &this->collider2); + Actor_SetHeight(&this->actor, this->actor.scale.y * 2000.0f); + CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/EnRr_Init.s") + if ((this->actor.params == ENRR_2) || (this->actor.params == ENRR_3)) { + this->actor.colChkInfo.health = 6; + if (this->actor.params == ENRR_2) { + this->actor.colChkInfo.mass = MASS_HEAVY; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/EnRr_Destroy.s") + this->actionFunc = func_808FAF94; + func_808FAD1C(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FA01C.s") +void EnRr_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnRr* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FA11C.s") + Collider_DestroyCylinder(globalCtx, &this->collider1); + Collider_DestroyCylinder(globalCtx, &this->collider2); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FA19C.s") +void func_808FA01C(EnRr* this, GlobalContext* globalCtx, ColliderCylinder* collider) { + if (this->actor.colChkInfo.damageEffect == 2) { + this->unk_220 = 0.85f; + this->unk_21C = 4.0f; + this->unk_1E0 = 0; + } else if (this->actor.colChkInfo.damageEffect == 4) { + this->unk_220 = 0.85f; + this->unk_21C = 4.0f; + this->unk_1E0 = 20; + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, collider->info.bumper.hitPos.x, + collider->info.bumper.hitPos.y, collider->info.bumper.hitPos.z, 0, 0, 0, + CLEAR_TAG_LARGE_LIGHT_RAYS); + } else if (this->actor.colChkInfo.damageEffect == 5) { + this->unk_220 = 0.85f; + this->unk_21C = 4.0f; + this->unk_1E0 = 30; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FA238.s") +void func_808FA11C(EnRr* this) { + this->unk_1E0 = 10; + this->collider1.base.colType = COLTYPE_HIT3; + this->collider1.info.elemType = ELEMTYPE_UNK0; + this->unk_1EE = 80; + this->unk_220 = 0.85f; + this->unk_224 = 1.2750001f; + this->unk_21C = 1.0f; + this->actor.flags &= ~0x400; + func_800BCB70(&this->actor, 0x4000, 255, 0, 80); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FA260.s") +void func_808FA19C(EnRr* this, GlobalContext* globalCtx) { + this->unk_1EE = 0; + if (this->unk_1E0 == 10) { + this->unk_1E0 = 0; + this->collider1.base.colType = COLTYPE_HIT0; + this->collider1.info.elemType = ELEMTYPE_UNK1; + this->unk_21C = 0.0f; + func_800BF7CC(globalCtx, &this->actor, this->unk_234, 20, 2, this->actor.scale.y * 23.333334f, + this->actor.scale.y * 20.000002f); + this->actor.flags |= 0x400; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FA344.s") +void func_808FA238(EnRr* this, f32 arg1) { + this->actor.speedXZ = arg1; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_LIKE_WALK); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FA3F8.s") +void func_808FA260(EnRr* this) { + static f32 D_808FC1E4[] = { 0.0f, 500.0f, 750.0f, 1000.0f, 1000.0f }; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FA4F4.s") + this->unk_1E1 = 1; + this->unk_1E6 = 20; + this->unk_1F6 = 2500; + this->unk_210 = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FA6B8.s") + for (i = 0; i < ARRAY_COUNT(this->unk_324); i++) { + this->unk_324[i].unk_04 = D_808FC1E4[i]; + this->unk_324[i].unk_14 = 6000; + this->unk_324[i].unk_18 = 0; + this->unk_324[i].unk_0C = 0.8f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FA7AC.s") + this->actionFunc = func_808FB088; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FA870.s") + Audio_PlayActorSound2(&this->actor, NA_SE_EN_LIKE_UNARI); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FA910.s") +void func_808FA344(EnRr* this) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FA9CC.s") + this->unk_1E1 = 0; + this->unk_210 = 0.0f; + this->unk_1F6 = 2500; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FAA94.s") + for (i = 0; i < ARRAY_COUNT(this->unk_324); i++) { + this->unk_324[i].unk_04 = 0.0f; + this->unk_324[i].unk_14 = 0; + this->unk_324[i].unk_18 = 0; + this->unk_324[i].unk_0C = 1.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FAC80.s") + if (this->unk_1E2 != 0) { + this->unk_1E6 = 100; + this->actionFunc = func_808FB680; + } else { + this->unk_1E6 = 60; + this->actionFunc = func_808FAF94; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FAD1C.s") +void func_808FA3F8(EnRr* this, Player* player) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FAE50.s") + this->unk_1EA = 100; + this->unk_1FC = 20; + this->collider1.base.ocFlags1 &= ~OC1_TYPE_PLAYER; + this->actor.flags &= ~1; + this->unk_1F0 = 8; + this->unk_1E1 = 0; + this->actor.speedXZ = 0.0f; + this->unk_218 = 0.0f; + this->unk_210 = 0.0f; + this->unk_204 = 0.15f; + this->unk_20C = 0x200; + this->unk_1F6 = 5000; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FAF94.s") + for (i = 0; i < ARRAY_COUNT(this->unk_324); i++) { + this->unk_324[i].unk_04 = 0.0f; + this->unk_324[i].unk_0C = 1.0f; + this->unk_324[i].unk_14 = 0; + this->unk_324[i].unk_18 = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FB088.s") + this->actionFunc = func_808FB1C0; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_SUISEN_DRINK); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FB1C0.s") +void func_808FA4F4(EnRr* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + u32 sp38; + s32 sp34; + f32 sp30; + f32 sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FB2C0.s") + if (player->stateFlags2 & 0x80) { + player->actor.parent = NULL; + player->unk_AE8 = 100; + this->actor.flags |= 1; + this->unk_1F0 = 110; + this->unk_1F6 = 2500; + this->unk_210 = 0.0f; + this->unk_20C = 0x800; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FB398.s") + if (((this->unk_1E2 == 0) && (gSaveContext.playerForm == PLAYER_FORM_HUMAN)) && + (CUR_EQUIP_VALUE_VOID(EQUIP_SHIELD) == EQUIP_SHIELD)) { + sp34 = true; + this->unk_1E2 = func_8012ED78(globalCtx, 1); + } else { + sp34 = false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FB42C.s") + if (sp34 && (func_80152498(&globalCtx->msgCtx) == 0)) { + func_801518B0(globalCtx, 0xF6, NULL); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FB680.s") + if (this->actor.params == ENRR_0) { + sp38 = 8; + } else { + sp38 = 16; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FB710.s") + sp30 = this->actor.scale.x * 210.52632f; + sp2C = this->actor.scale.x * 631.579f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/func_808FB794.s") + player->actor.world.pos.x += sp30 * Math_SinS(this->actor.shape.rot.y); + player->actor.world.pos.y += sp2C; + player->actor.world.pos.z += sp30 * Math_CosS(this->actor.shape.rot.y); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/EnRr_Update.s") + func_800B8D50(globalCtx, &this->actor, sp30, this->actor.shape.rot.y, sp2C, sp38); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_SUISEN_THROW); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Rr/EnRr_Draw.s") +void func_808FA6B8(EnRr* this) { + s32 i; + + this->unk_1E1 = 0; + if (this->actor.colChkInfo.damageEffect == 5) { + this->unk_1EC = 80; + } else { + this->unk_1EC = 40; + } + func_800BCB70(&this->actor, 0x4000, 255, 0, this->unk_1EC); + + this->unk_1E6 = 20; + this->unk_1F6 = 2500; + this->unk_210 = 0.0f; + this->unk_204 = 0.0f; + this->unk_20C = 0.0f; + + for (i = 0; i < ARRAY_COUNT(this->unk_324); i++) { + this->unk_324[i].unk_04 = 0.0f; + this->unk_324[i].unk_0C = 1.0f; + this->unk_324[i].unk_14 = 0; + this->unk_324[i].unk_18 = 0; + } + + this->actionFunc = func_808FB398; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_LIKE_DAMAGE); +} + +void func_808FA7AC(EnRr* this) { + static f32 D_808FC1F8[] = { 0.0f, 500.0f, 750.0f, 1000.0f, 1000.0f, 0.0f }; + s32 i; + + this->unk_1F6 = 2500; + this->unk_1E1 = 1; + this->unk_1E6 = 10; + this->unk_210 = 0.0f; + + for (i = 0; i < ARRAY_COUNT(this->unk_324); i++) { + this->unk_324[i].unk_04 = D_808FC1F8[i]; + this->unk_324[i].unk_0C = 0.8f; + this->unk_324[i].unk_14 = 5000; + this->unk_324[i].unk_18 = 0; + } + + this->actionFunc = func_808FB2C0; +} + +void func_808FA870(EnRr* this) { + s32 i; + + this->unk_210 = 0.0f; + this->unk_204 = 0.15f; + this->unk_20C = 0x800; + this->unk_1F6 = 2500; + + for (i = 0; i < ARRAY_COUNT(this->unk_324); i++) { + this->unk_324[i].unk_04 = 0.0f; + this->unk_324[i].unk_0C = 1.0f; + this->unk_324[i].unk_14 = 0; + this->unk_324[i].unk_18 = 0; + } + + this->actionFunc = func_808FAF94; +} + +void func_808FA910(EnRr* this) { + s32 i; + + this->unk_1E4 = 0; + this->unk_214 = 0.0f; + func_800BCB70(&this->actor, 0x4000, 255, 0, 40); + this->unk_210 = 0.0f; + + for (i = 0; i < ARRAY_COUNT(this->unk_324); i++) { + this->unk_324[i].unk_04 = 0.0f; + this->unk_324[i].unk_14 = 0; + this->unk_324[i].unk_18 = 0; + } + + this->actionFunc = func_808FB42C; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_LIKE_DEAD); + this->actor.flags &= ~1; +} + +void func_808FA9CC(EnRr* this) { + s32 i; + + this->unk_1F2 = 0; + this->unk_1F4 = 0; + this->unk_1F6 = 2500; + this->unk_1F8 = 0; + this->unk_1FA = 0; + this->unk_200 = 0.0f; + this->unk_204 = 0.15f; + this->unk_208 = 0.0f; + this->unk_20C = 0x800; + + for (i = 0; i < ARRAY_COUNT(this->unk_324); i++) { + this->unk_324[i].unk_08 = 1.0f; + this->unk_324[i].unk_0C = 1.0f; + this->unk_324[i].unk_14 = 0; + this->unk_324[i].unk_16 = 0; + this->unk_324[i].unk_18 = 0; + } + + this->actionFunc = func_808FB710; +} + +s32 func_808FAA94(EnRr* this, GlobalContext* globalCtx) { + ColliderCylinder* sp2C; + s32 flag = (this->collider1.base.acFlags & AC_HIT) != 0; + + if (flag || (this->collider2.base.acFlags & AC_HIT)) { + if (flag) { + sp2C = &this->collider1; + } else { + sp2C = &this->collider2; + } + + this->collider1.base.acFlags &= ~AC_HIT; + this->collider2.base.acFlags &= ~AC_HIT; + + if ((this->unk_1E0 == 10) && (sp2C->info.acHitInfo->toucher.dmgFlags & 0xDB0B3)) { + return false; + } + + if (this->actor.colChkInfo.damageEffect == 14) { + return false; + } + + func_800BE258(&this->actor, &sp2C->info); + func_808FA4F4(this, globalCtx); + func_808FA19C(this, globalCtx); + + if (!Actor_ApplyDamage(&this->actor)) { + Enemy_StartFinishingBlow(globalCtx, &this->actor); + if (this->actor.colChkInfo.damageEffect == 3) { + func_808FA11C(this); + this->collider1.base.acFlags &= ~AC_ON; + this->collider2.base.acFlags &= ~AC_ON; + func_808FA9CC(this); + } else { + func_808FA01C(this, globalCtx, sp2C); + func_808FA910(this); + } + } else if (this->actor.colChkInfo.damageEffect == 1) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + func_800BCB70(&this->actor, 0, 255, 0, 80); + this->unk_1EE = 80; + func_808FA9CC(this); + } else if (this->actor.colChkInfo.damageEffect == 3) { + func_808FA11C(this); + func_808FA9CC(this); + } else { + func_808FA01C(this, globalCtx, sp2C); + func_808FA6B8(this); + } + return true; + } + return false; +} + +void func_808FAC80(EnRr* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if ((this->unk_1F0 == 0) && ((this->collider2.base.atFlags & AT_HIT) || (this->collider1.base.atFlags & AT_HIT))) { + this->collider1.base.atFlags &= ~AT_HIT; + this->collider2.base.atFlags &= ~AT_HIT; + if (globalCtx->grabPlayer(globalCtx, player)) { + player->actor.parent = &this->actor; + func_808FA3F8(this, player); + } + } +} + +void func_808FAD1C(EnRr* this, GlobalContext* globalCtx) { + s32 i; + EnRrStruct* ptr; + + this->unk_1F2 = 0; + this->unk_1F4 = 0; + this->unk_1F6 = 2500; + this->unk_1F8 = 0; + this->unk_1FA = 0; + this->unk_200 = 0.0f; + this->unk_204 = 0.15f; + this->unk_208 = 0.0f; + this->unk_20C = 0x800; + + for (i = 0; i < ARRAY_COUNT(this->unk_324); i++) { + this->unk_324[i].unk_14 = 0; + this->unk_324[i].unk_16 = 0; + this->unk_324[i].unk_18 = 0; + + this->unk_324[i].unk_08 = 1.0f; + this->unk_324[i].unk_0C = 1.0f; + this->unk_324[i].unk_10 = this->unk_200; + } + + for (i = 1; i < ARRAY_COUNT(this->unk_324); i++) { + ptr = &this->unk_324[i]; + ptr->unk_14 = Math_CosS(this->unk_1F8 * i) * this->unk_208; + ptr->unk_18 = Math_SinS(this->unk_1FA * i) * this->unk_208; + } +} + +void func_808FAE50(EnRr* this, GlobalContext* globalCtx) { + s32 i; + EnRrStruct* ptr; + + if (this->actionFunc != func_808FB42C) { + for (i = 0; i < ARRAY_COUNT(this->unk_324); i++) { + ptr = &this->unk_324[i]; + ptr->unk_10 = Math_CosS(this->unk_1F2 + (i * 0x4000)) * this->unk_200; + } + + if (this->unk_1E1 == 0) { + for (i = 1; i < ARRAY_COUNT(this->unk_324); i++) { + ptr = &this->unk_324[i]; + ptr->unk_14 = Math_CosS(this->unk_1F2 + (i * this->unk_1F8)) * this->unk_208; + ptr->unk_18 = Math_SinS(this->unk_1F2 + (i * this->unk_1FA)) * this->unk_208; + } + } + } + + if (this->unk_1EE == 0) { + this->unk_1F2 += this->unk_1F4; + } +} + +void func_808FAF94(EnRr* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 10, 500, 0); + this->actor.world.rot.y = this->actor.shape.rot.y; + if ((this->unk_1E6 == 0) && !(player->stateFlags2 & 0x80) && (Player_GetMask(globalCtx) != PLAYER_MASK_STONE) && + (this->actor.xzDistToPlayer < (8421.053f * this->actor.scale.x))) { + func_808FA260(this); + } else if ((this->actor.xzDistToPlayer < 400.0f) && (this->actor.speedXZ == 0.0f)) { + func_808FA238(this, 2.0f); + } +} + +void func_808FB088(EnRr* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 10, 500, 0); + this->actor.world.rot.y = this->actor.shape.rot.y; + if (Player_GetMask(globalCtx) == PLAYER_MASK_STONE) { + func_808FA344(this); + return; + } + + switch (this->unk_1E1) { + case 1: + if (this->unk_1E6 == 0) { + this->unk_1E1 = 2; + } + break; + + case 2: + if (this->unk_1E6 == 0) { + this->unk_324[4].unk_0C = 1.5f; + this->unk_1E6 = 5; + this->unk_1E1 = 3; + } + break; + + case 3: + if (this->unk_1E6 == 0) { + this->unk_1E6 = 2; + this->unk_324[4].unk_04 = 2000.0f; + this->unk_1E1 = 4; + } + break; + + case 4: + if (this->unk_1E6 == 0) { + this->unk_324[4].unk_0C = 0.8f; + this->unk_1E6 = 20; + this->unk_1E1 = 5; + } + break; + + case 5: + if (this->unk_1E6 == 0) { + func_808FA344(this); + } + break; + } +} + +void func_808FB1C0(EnRr* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + func_8013ECE0(this->actor.xyzDistToPlayerSq, 120, 2, 120); + if (!(this->unk_1E4 & 7)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_EYEGOLE_DEMO_EYE); + } + + player->unk_AE8 = 0; + this->unk_1F0 = 8; + this->unk_1EA--; + + if (this->unk_1EA == 0) { + func_808FA7AC(this); + } else { + Math_StepToF(&player->actor.world.pos.x, this->unk_228.x, 30.0f); + Math_StepToF(&player->actor.world.pos.y, this->unk_228.y + this->unk_218, 30.0f); + Math_StepToF(&player->actor.world.pos.z, this->unk_228.z, 30.0f); + Math_StepToF(&this->unk_218, -(f32)this->collider1.dim.height, 5.0f); + } +} + +void func_808FB2C0(EnRr* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + this->unk_1E6--; + player->unk_AE8 = 0; + Math_StepToF(&player->actor.world.pos.x, this->unk_228.x, 30.0f); + Math_StepToF(&player->actor.world.pos.y, this->unk_228.y + this->unk_218, 30.0f); + Math_StepToF(&player->actor.world.pos.z, this->unk_228.z, 30.0f); + Math_StepToF(&this->unk_218, -(f32)this->collider1.dim.height, 5.0f); + if (this->unk_1E6 == 0) { + this->unk_1E1 = 0; + func_808FA4F4(this, globalCtx); + func_808FA344(this); + } +} + +void func_808FB398(EnRr* this, GlobalContext* globalCtx) { + s32 i; + s16 phi_v1; + + this->unk_1EC--; + if (this->unk_1EC == 0) { + func_808FA870(this); + return; + } + + if (this->unk_1E0 == 30) { + if (this->unk_1EC & 2) { + phi_v1 = 1000; + } else { + phi_v1 = -1000; + } + } else { + if (this->unk_1EC & 8) { + phi_v1 = 5000; + } else { + phi_v1 = -5000; + } + } + + for (i = 1; i < ARRAY_COUNT(this->unk_324); i++) { + this->unk_324[i].unk_18 = phi_v1; + } +} + +void func_808FB42C(EnRr* this, GlobalContext* globalCtx) { + s32 pad; + s32 i; + EnRrStruct* ptr; + f32 temp_f20; + + this->actor.colorFilterTimer = 40; + if (this->unk_1E4 < 40) { + for (i = 0; i < ARRAY_COUNT(this->unk_324); i++) { + ptr = &this->unk_324[i]; + Math_StepToF(&ptr->unk_04, (i + 59) - (this->unk_1E4 * 25.0f), 50.0f); + ptr->unk_0C = (SQ((f32)(4 - i)) * this->unk_1E4 * 0.003f) + 1.0f; + } + return; + } + + if (this->unk_1E4 >= 95) { + if (this->unk_1E2 != 0) { + Item_DropCollectible(globalCtx, &this->actor.world.pos, ITEM00_SHIELD_HERO); + } + Item_DropCollectibleRandom(globalCtx, &this->actor, &this->actor.world.pos, 0x90); + Actor_MarkForDeath(&this->actor); + } else if (this->unk_1E4 == 88) { + Vec3f sp74; + + sp74.x = this->actor.world.pos.x; + sp74.y = this->actor.world.pos.y + 20.0f; + sp74.z = this->actor.world.pos.z; + func_800B3030(globalCtx, &sp74, &gZeroVec3f, &gZeroVec3f, 100, 0, 0); + Audio_PlaySoundAtPosition(globalCtx, &sp74, 11, NA_SE_EN_EXTINCT); + } else { + temp_f20 = this->actor.scale.y * 66.66667f; + + Math_StepToF(&this->actor.scale.x, 0.0f, this->unk_214); + Math_StepToF(&this->unk_214, 0.001f * temp_f20, 0.00001f * temp_f20); + this->actor.scale.z = this->actor.scale.x; + } +} + +void func_808FB680(EnRr* this, GlobalContext* globalCtx) { + if (this->unk_1E6 == 0) { + this->actionFunc = func_808FAF94; + } else { + Math_SmoothStepToS(&this->actor.shape.rot.y, BINANG_ROT180(this->actor.yawTowardsPlayer), 10, 1000, 0); + this->actor.world.rot.y = this->actor.shape.rot.y; + if (this->actor.speedXZ == 0.0f) { + func_808FA238(this, 2.0f); + } + } +} + +void func_808FB710(EnRr* this, GlobalContext* globalCtx) { + this->unk_1EE--; + if (this->unk_1EE == 0) { + func_808FA19C(this, globalCtx); + func_808FA870(this); + this->actionFunc = func_808FAF94; + } else if ((this->actor.colChkInfo.health == 0) && (this->unk_1EE == 77)) { + func_808FA19C(this, globalCtx); + func_808FA910(this); + } +} + +void func_808FB794(EnRr* this, GlobalContext* globalCtx) { + Vec3f sp2C; + + if ((this->actor.depthInWater < this->collider1.dim.height) && (this->actor.depthInWater > 1.0f) && + ((globalCtx->gameplayFrames % 9) == 0)) { + sp2C.x = this->actor.world.pos.x; + sp2C.y = this->actor.world.pos.y + this->actor.depthInWater; + sp2C.z = this->actor.world.pos.z; + EffectSsGRipple_Spawn(globalCtx, &sp2C, this->actor.scale.x * 34210.527f, this->actor.scale.x * 60526.316f, 0); + } +} + +void EnRr_Update(Actor* thisx, GlobalContext* globalCtx) { + EnRr* this = THIS; + EnRrStruct* ptr; + s32 i; + + this->unk_1E4++; + + if (this->unk_1EE == 0) { + this->unk_1E8++; + } + + if (this->unk_1E6 != 0) { + this->unk_1E6--; + } + + if (this->unk_1F0 != 0) { + this->unk_1F0--; + } + + Actor_SetHeight(&this->actor, this->actor.scale.y * 2000.0f); + func_808FAE50(this, globalCtx); + + if (!func_808FAA94(this, globalCtx)) { + func_808FAC80(this, globalCtx); + } + + this->actionFunc(this, globalCtx); + + if (this->actor.params == ENRR_2) { + this->actor.speedXZ = 0.0f; + } else { + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.1f); + } + + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, this->collider1.dim.radius, 0.0f, 0x5D); + func_808FB794(this, globalCtx); + + if (this->unk_1FC > 0) { + Player* player = GET_PLAYER(globalCtx); + + if (!(player->stateFlags2 & 0x80)) { + this->unk_1FC--; + if (this->unk_1FC == 0) { + this->collider1.base.ocFlags1 |= OC1_TYPE_PLAYER; + } + } + } + + Collider_UpdateCylinder(&this->actor, &this->collider1); + + if ((this->actionFunc != func_808FB42C) && (this->actionFunc != func_808FB398)) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + if ((this->unk_1F0 == 0) && (this->actionFunc == func_808FB088) && (this->unk_1EE == 0)) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + } else { + this->collider2.base.atFlags &= ~AT_HIT; + this->collider1.base.atFlags &= ~AT_HIT; + } + } else { + this->collider2.base.atFlags &= ~AT_HIT; + this->collider1.base.atFlags &= ~AT_HIT; + this->collider2.base.acFlags &= ~AC_HIT; + this->collider1.base.acFlags &= ~AC_HIT; + } + + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + + if (this->unk_1EE == 0) { + Math_ScaledStepToS(&this->unk_1F4, this->unk_1F6, 50); + Math_ScaledStepToS(&this->unk_1F8, 0x3000, 0xA4); + Math_ScaledStepToS(&this->unk_1FA, 0x1000, 0x29); + Math_StepToF(&this->unk_200, this->unk_204, 0.0015f); + Math_StepToF(&this->unk_208, this->unk_20C, 20.0f); + + for (i = 0; i < ARRAY_COUNT(this->unk_324); i++) { + ptr = &this->unk_324[i]; + Math_SmoothStepToS(&ptr->unk_1A.x, ptr->unk_14, 5, this->unk_210 * 1000.0f, 0); + Math_SmoothStepToS(&ptr->unk_1A.z, ptr->unk_18, 5, this->unk_210 * 1000.0f, 0); + Math_StepToF(&ptr->unk_08, ptr->unk_0C, this->unk_210 * 0.2f); + Math_StepToF(&ptr->unk_00, ptr->unk_04, this->unk_210 * 300.0f); + } + + Math_StepToF(&this->unk_210, 1.0f, 0.2f); + } + + if (this->unk_21C > 0.0f) { + if (this->unk_1E0 != 10) { + Math_StepToF(&this->unk_21C, 0.0f, 0.05f); + this->unk_220 = (this->unk_21C + 1.0f) * 0.425f; + this->unk_220 = CLAMP_MAX(this->unk_220, 0.85f); + } else if (!Math_StepToF(&this->unk_224, 0.85f, 0.02125f)) { + func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } + } +} + +void EnRr_Draw(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnRr* this = THIS; + Mtx* matrix; + Vec3f* vecPtr; + s32 i; + EnRrStruct* ptr; + Vec3f spA4; + f32 temp_f20; + + matrix = GRAPH_ALLOC(globalCtx->state.gfxCtx, 256); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x0C, matrix); + gSPSegment(POLY_OPA_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, (this->unk_1E8 * 0) & 0x7F, (this->unk_1E8 * 0) & 0x3F, + 0x20, 0x10, 1, (this->unk_1E8 * 0) & 0x3F, (this->unk_1E8 * -6) & 0x7F, 0x20, 0x10)); + + Matrix_StatePush(); + Matrix_Scale((1.0f + this->unk_324[0].unk_10) * this->unk_324[0].unk_08, 1.0f, + (1.0f + this->unk_324[0].unk_10) * this->unk_324[0].unk_08, MTXMODE_APPLY); + + vecPtr = &this->unk_234[0]; + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + + Matrix_GetStateTranslationAndScaledZ(1842.1053f, vecPtr++); + Matrix_GetStateTranslationAndScaledZ(-1842.1053f, vecPtr++); + Matrix_GetStateTranslationAndScaledX(1842.1053f, vecPtr++); + Matrix_GetStateTranslationAndScaledX(-1842.1053f, vecPtr++); + Matrix_StatePop(); + + for (i = 1; i < ARRAY_COUNT(this->unk_324); i++) { + temp_f20 = this->unk_324[i].unk_08 * (this->unk_324[i].unk_10 + 1.0f); + ptr = &this->unk_324[i]; + + Matrix_InsertTranslation(0.0f, ptr->unk_00 + 1000.0f, 0.0f, MTXMODE_APPLY); + Matrix_InsertRotation(ptr->unk_1A.x, ptr->unk_1A.y, ptr->unk_1A.z, MTXMODE_APPLY); + Matrix_StatePush(); + Matrix_Scale(temp_f20, 1.0f, temp_f20, MTXMODE_APPLY); + Matrix_ToMtx(matrix); + + if ((i & 1) != 0) { + Matrix_RotateY(0x2000, MTXMODE_APPLY); + } + + Matrix_GetStateTranslationAndScaledZ(1842.1053f, vecPtr++); + Matrix_GetStateTranslationAndScaledZ(-1842.1053f, vecPtr++); + Matrix_GetStateTranslationAndScaledX(1842.1053f, vecPtr++); + Matrix_GetStateTranslationAndScaledX(-1842.1053f, vecPtr++); + Matrix_StatePop(); + matrix++; + if (i == 3) { + Matrix_GetStateTranslation(&spA4); + } + } + + Matrix_GetStateTranslation(&this->unk_228); + this->collider2.dim.pos.x = ((this->unk_228.x - spA4.x) * 0.85f) + spA4.x; + this->collider2.dim.pos.y = ((this->unk_228.y - spA4.y) * 0.85f) + spA4.y; + this->collider2.dim.pos.z = ((this->unk_228.z - spA4.z) * 0.85f) + spA4.z; + + gSPDisplayList(POLY_OPA_DISP++, D_06000470); + + func_800BE680(globalCtx, &this->actor, this->unk_234, ARRAY_COUNT(this->unk_234), + this->actor.scale.y * 66.66667f * this->unk_220, this->unk_224, this->unk_21C, this->unk_1E0); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Rr/z_en_rr.h b/src/overlays/actors/ovl_En_Rr/z_en_rr.h index d6df8a710..036107477 100644 --- a/src/overlays/actors/ovl_En_Rr/z_en_rr.h +++ b/src/overlays/actors/ovl_En_Rr/z_en_rr.h @@ -7,10 +7,59 @@ struct EnRr; typedef void (*EnRrActionFunc)(struct EnRr*, GlobalContext*); +enum { + /* 0 */ ENRR_0, + /* 1 */ ENRR_1, + /* 2 */ ENRR_2, + /* 3 */ ENRR_3, +}; + +typedef struct { + /* 0x00 */ f32 unk_00; + /* 0x04 */ f32 unk_04; + /* 0x08 */ f32 unk_08; + /* 0x0C */ f32 unk_0C; + /* 0x10 */ f32 unk_10; + /* 0x14 */ s16 unk_14; + /* 0x16 */ s16 unk_16; + /* 0x18 */ s16 unk_18; + /* 0x1A */ Vec3s unk_1A; +} EnRrStruct; // size = 0x20 + typedef struct EnRr { - /* 0x0000 */ Actor actor; - /* 0x0144 */ EnRrActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x27C]; + /* 0x000 */ Actor actor; + /* 0x144 */ EnRrActionFunc actionFunc; + /* 0x148 */ ColliderCylinder collider1; + /* 0x194 */ ColliderCylinder collider2; + /* 0x1E0 */ u8 unk_1E0; + /* 0x1E1 */ u8 unk_1E1; + /* 0x1E2 */ u8 unk_1E2; + /* 0x1E4 */ s16 unk_1E4; + /* 0x1E6 */ s16 unk_1E6; + /* 0x1E8 */ s16 unk_1E8; + /* 0x1EA */ s16 unk_1EA; + /* 0x1EC */ s16 unk_1EC; + /* 0x1EE */ s16 unk_1EE; + /* 0x1F0 */ s16 unk_1F0; + /* 0x1F2 */ s16 unk_1F2; + /* 0x1F4 */ s16 unk_1F4; + /* 0x1F6 */ s16 unk_1F6; + /* 0x1F8 */ s16 unk_1F8; + /* 0x1FA */ s16 unk_1FA; + /* 0x1FC */ s16 unk_1FC; + /* 0x200 */ f32 unk_200; + /* 0x204 */ f32 unk_204; + /* 0x208 */ f32 unk_208; + /* 0x20C */ f32 unk_20C; + /* 0x210 */ f32 unk_210; + /* 0x214 */ f32 unk_214; + /* 0x218 */ f32 unk_218; + /* 0x21C */ f32 unk_21C; + /* 0x220 */ f32 unk_220; + /* 0x224 */ f32 unk_224; + /* 0x228 */ Vec3f unk_228; + /* 0x234 */ Vec3f unk_234[20]; + /* 0x324 */ EnRrStruct unk_324[5]; } EnRr; // size = 0x3C4 extern const ActorInit En_Rr_InitVars; diff --git a/src/overlays/actors/ovl_En_Rsn/z_en_rsn.c b/src/overlays/actors/ovl_En_Rsn/z_en_rsn.c index f02130121..3adecaad3 100644 --- a/src/overlays/actors/ovl_En_Rsn/z_en_rsn.c +++ b/src/overlays/actors/ovl_En_Rsn/z_en_rsn.c @@ -1,7 +1,7 @@ /* * File: z_en_rsn.c * Overlay: ovl_En_Rsn - * Description: Bomb Shop Man in the credits? + * Description: Bomb Shop Man in the credits */ #include "z_en_rsn.h" @@ -72,7 +72,7 @@ s32 EnRsn_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, EnRsn* this = (EnRsn*)arg; if (limbIndex == 14) { - Matrix_InsertXRotation_s(this->unk1D8.y, 1); + Matrix_InsertXRotation_s(this->unk1D8.y, MTXMODE_APPLY); } return 0; } diff --git a/src/overlays/actors/ovl_En_Ru/z_en_ru.c b/src/overlays/actors/ovl_En_Ru/z_en_ru.c index 3a0acd4b6..f3edfa7c3 100644 --- a/src/overlays/actors/ovl_En_Ru/z_en_ru.c +++ b/src/overlays/actors/ovl_En_Ru/z_en_ru.c @@ -1,7 +1,7 @@ /* * File: z_en_ru.c * Overlay: ovl_En_Ru - * Description: Ruto + * Description: OoT's Adult Ruto (unused) */ #include "z_en_ru.h" diff --git a/src/overlays/actors/ovl_En_Ru/z_en_ru.h b/src/overlays/actors/ovl_En_Ru/z_en_ru.h index 9b1037ed4..b368fb584 100644 --- a/src/overlays/actors/ovl_En_Ru/z_en_ru.h +++ b/src/overlays/actors/ovl_En_Ru/z_en_ru.h @@ -10,7 +10,7 @@ typedef void (*EnRuActionFunc)(struct EnRu*, GlobalContext*); typedef struct EnRu { /* 0x0000 */ Actor actor; /* 0x0144 */ EnRuActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x30C]; + /* 0x0148 */ char unk_148[0x30C]; } EnRu; // size = 0x454 extern const ActorInit En_Ru_InitVars; diff --git a/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.c b/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.c index ba851d64d..a255b0b80 100644 --- a/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.c +++ b/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.c @@ -5,17 +5,41 @@ */ #include "z_en_ruppecrow.h" +#include "objects/object_crow/object_crow.h" #define FLAGS 0x00004030 #define THIS ((EnRuppecrow*)thisx) +enum { + ENRUPPECROW_EFFECT_NONE = 0, + ENRUPPECROW_EFFECT_ICE = 10, + ENRUPPECROW_EFFECT_LIGHT = 20, +}; + void EnRuppecrow_Init(Actor* thisx, GlobalContext* globalCtx); void EnRuppecrow_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnRuppecrow_Update(Actor* thisx, GlobalContext* globalCtx); void EnRuppecrow_Draw(Actor* thisx, GlobalContext* globalCtx); +void EnRuppecrow_HandleSong(EnRuppecrow*, GlobalContext*); +s32 EnRuppecrow_UpdateCollision(EnRuppecrow*, GlobalContext*); +void EnRuppecrow_UpdateRupees(EnRuppecrow*); +void EnRuppecrow_UpdateDamage(EnRuppecrow*, GlobalContext*); +void EnRuppecrow_HandleDeath(EnRuppecrow*); +void EnRuppecrow_FallToDespawn(EnRuppecrow*, GlobalContext*); +void EnRuppecrow_ShatterIce(EnRuppecrow*, GlobalContext*); +void EnRuppecrow_UpdatePosition(EnRuppecrow*, GlobalContext*); +s32 EnRuppecrow_CheckPlayedMatchingSong(GlobalContext*); +void EnRuppecrow_HandleSongCutscene(EnRuppecrow*, GlobalContext*); +s32 EnRuppecrow_ReachedPointClockwise(EnRuppecrow*, Path*, s32); +s32 EnRuppecrow_ReachedPointCounterClockwise(EnRuppecrow*, Path*, s32); +f32 EnRuppecrow_GetPointDirection(Path*, s32, PosRot*, Vec3s*); +s32 EnRuppecrow_CanSpawnBlueRupees(GlobalContext*); +void EnRuppecrow_SpawnRupee(EnRuppecrow*, GlobalContext*); +void EnRuppecrow_FlyWhileDroppingRupees(EnRuppecrow*, GlobalContext*); +void EnRuppecrow_UpdateSpeed(EnRuppecrow*, GlobalContext*); +void EnRuppecrow_FlyToDespawn(EnRuppecrow*, GlobalContext*); -#if 0 const ActorInit En_Ruppecrow_InitVars = { ACTOR_EN_RUPPECROW, ACTORCAT_ENEMY, @@ -28,25 +52,36 @@ const ActorInit En_Ruppecrow_InitVars = { (ActorFunc)EnRuppecrow_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_80BE39B0[1] = { +static ColliderJntSphElementInit sJntSphElementsInit[1] = { { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 1, { { 0, 0, 0 }, 20 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_80BE39D4 = { - { COLTYPE_HIT3, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 1, D_80BE39B0, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_HIT3, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit, }; -// sColChkInfoInit -static CollisionCheckInfoInit D_80BE39E4 = { 1, 15, 30, 30 }; +static CollisionCheckInfoInit sColChkInfoInit = { 1, 15, 30, 30 }; -// static DamageTable sDamageTable = { -static DamageTable D_80BE39EC = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x1), /* Deku Stick */ DMG_ENTRY(1, 0x0), /* Horse trample */ DMG_ENTRY(1, 0x0), @@ -81,62 +116,558 @@ static DamageTable D_80BE39EC = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80BE3A0C[] = { +static InitChainEntry sInitChain[] = { ICHAIN_F32_DIV1000(gravity, -500, ICHAIN_CONTINUE), ICHAIN_F32(targetArrowOffset, 2000, ICHAIN_STOP), }; -#endif +s32 EnRuppecrow_UpdateCollision(EnRuppecrow* this, GlobalContext* globalCtx) { + s32 pad; -extern ColliderJntSphElementInit D_80BE39B0[1]; -extern ColliderJntSphInit D_80BE39D4; -extern CollisionCheckInfoInit D_80BE39E4; -extern DamageTable D_80BE39EC; -extern InitChainEntry D_80BE3A0C[]; + this->collider.elements->dim.worldSphere.center.x = this->actor.world.pos.x; + this->collider.elements->dim.worldSphere.center.y = + sJntSphInit.elements->dim.modelSphere.center.y + this->actor.world.pos.y; + this->collider.elements->dim.worldSphere.center.z = this->actor.world.pos.z; -extern UNK_TYPE D_060000F0; + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 12.0f, 25.0f, 50.0f, 0x07); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2260.s") + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2330.s") +s32 EnRuppecrow_ReachedPointClockwise(EnRuppecrow* this, Path* path, s32 pointIndex) { + Vec3s* points = Lib_SegmentedToVirtual(path->points); + s32 pathCount = path->count; + s32 currentPoint = pointIndex; + s32 reached = false; + f32 diffX; + f32 diffZ; + f32 px; + f32 pz; + f32 d; + Vec3f point; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE24CC.s") + Math_Vec3s_ToVec3f(&point, &points[currentPoint]); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2668.s") + if (currentPoint == 0) { + diffX = points[1].x - points[0].x; + diffZ = points[1].z - points[0].z; + } else { + if (currentPoint == (pathCount - 1)) { + diffX = points[pathCount - 1].x - points[pathCount - 2].x; + diffZ = points[pathCount - 1].z - points[pathCount - 2].z; + } else { + diffX = points[currentPoint + 1].x - points[currentPoint - 1].x; + diffZ = points[currentPoint + 1].z - points[currentPoint - 1].z; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2728.s") + func_8017B7F8(&point, RADF_TO_BINANG(func_80086B30(diffX, diffZ)), &px, &pz, &d); + if (((this->actor.world.pos.x * px) + (pz * this->actor.world.pos.z) + d) > 0.0f) { + reached = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2794.s") + return reached; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2808.s") +s32 EnRuppecrow_ReachedPointCounterClockwise(EnRuppecrow* this, Path* path, s32 pointIndex) { + Vec3s* points = Lib_SegmentedToVirtual(path->points); + s32 pathCount = path->count; + s32 currentPoint = pointIndex; + s32 reached = false; + f32 diffX; + f32 diffZ; + f32 px; + f32 pz; + f32 d; + Vec3f point; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2874.s") + Math_Vec3s_ToVec3f(&point, &points[currentPoint]); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2B80.s") + if (currentPoint == 0) { + diffX = points[0].x - points[1].x; + diffZ = points[0].z - points[1].z; + } else { + if (currentPoint == (pathCount - 1)) { + diffX = points[pathCount - 2].x - points[pathCount - 1].x; + diffZ = points[pathCount - 2].z - points[pathCount - 1].z; + } else { + diffX = points[currentPoint - 1].x - points[currentPoint + 1].x; + diffZ = points[currentPoint - 1].z - points[currentPoint + 1].z; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2D4C.s") + func_8017B7F8(&point, RADF_TO_BINANG(func_80086B30(diffX, diffZ)), &px, &pz, &d); + if (((this->actor.world.pos.x * px) + (pz * this->actor.world.pos.z) + d) > 0.0f) { + reached = true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2E18.s") + return reached; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE2F6C.s") +f32 EnRuppecrow_GetPointDirection(Path* path, s32 pointIndex, PosRot* world, Vec3s* direction) { + Vec3s* points; + Vec3f point; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE30F4.s") + if (path != NULL) { + points = Lib_SegmentedToVirtual(path->points); + points = &points[pointIndex]; + VEC_SET(point, points->x, points->y, points->z); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE3178.s") + direction->y = Math_Vec3f_Yaw(&world->pos, &point); + direction->x = Math_Vec3f_Pitch(&world->pos, &point); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE32DC.s") + return point.y - world->pos.y; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE3354.s") +void EnRuppecrow_ShatterIce(EnRuppecrow* this, GlobalContext* globalCtx) { + if (this->currentEffect == ENRUPPECROW_EFFECT_ICE) { + this->currentEffect = ENRUPPECROW_EFFECT_NONE; + this->unk_2C8 = 0.0f; + func_800BF7CC(globalCtx, &this->actor, this->limbPos, ENRUPPECROW_LIMB_POS_COUNT, 0x2, 0.2f, 0.2f); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE348C.s") +s32 EnRuppecrow_CanSpawnBlueRupees(GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/func_80BE35A4.s") + switch (player->transformation) { + case PLAYER_FORM_DEKU: + return false; + case PLAYER_FORM_GORON: + return true; + case PLAYER_FORM_ZORA: + return false; + case PLAYER_FORM_HUMAN: + if (player->stateFlags1 & 0x800000) { + return true; + } else { + return false; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/EnRuppecrow_Init.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/EnRuppecrow_Destroy.s") +void EnRuppecrow_UpdateRupees(EnRuppecrow* this) { + EnItem00* rupee; + s16 rupeeIndex; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/EnRuppecrow_Update.s") + for (rupeeIndex = 0; rupeeIndex < ENRUPPECROW_RUPEE_COUNT; rupeeIndex++) { + rupee = this->rupees[rupeeIndex]; + if (rupee != NULL && rupee->unk152 == 0) { + Actor_MarkForDeath(&rupee->actor); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ruppecrow/EnRuppecrow_Draw.s") +void EnRuppecrow_SpawnRupee(EnRuppecrow* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 xOffset; + EnItem00* rupee; + s16 rupeeIndex = this->rupeeIndex; + + if (!(player->stateFlags3 & 0x1000)) { + xOffset = (this->rupeeIndex & 1) ? 10.0f : -10.0f; + } else { + xOffset = 0.0f; + } + + if (EnRuppecrow_CanSpawnBlueRupees(globalCtx) && (this->rupeeIndex % 5) == 4) { + if (this->rupeeIndex == 19) { + rupee = (EnItem00*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ITEM00, + this->actor.world.pos.x + xOffset, this->actor.world.pos.y, + this->actor.world.pos.z, 0x0, 0x0, 0x0, ITEM00_RUPEE_RED); + this->rupees[rupeeIndex] = rupee; + this->rupees[rupeeIndex]->actor.gravity = -5.0f; + this->rupees[rupeeIndex]->actor.velocity.y = 0.0f; + Audio_PlayActorSound2(&this->actor, NA_SE_EV_RUPY_FALL); + rupee = this->rupees[rupeeIndex]; + rupee->unk152 = 60; + this->rupees[rupeeIndex]->actor.flags |= 0x10; + } else { + rupee = (EnItem00*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ITEM00, + this->actor.world.pos.x + xOffset, this->actor.world.pos.y, + this->actor.world.pos.z, 0x0, 0x0, 0x0, ITEM00_RUPEE_BLUE); + this->rupees[rupeeIndex] = rupee; + this->rupees[rupeeIndex]->actor.gravity = -5.0f; + this->rupees[rupeeIndex]->actor.velocity.y = 0.0f; + Audio_PlayActorSound2(&this->actor, NA_SE_EV_RUPY_FALL); + rupee = this->rupees[rupeeIndex]; + rupee->unk152 = 60; + this->rupees[rupeeIndex]->actor.flags |= 0x10; + } + } else if (this->rupeeIndex == 19) { + rupee = + (EnItem00*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ITEM00, this->actor.world.pos.x + xOffset, + this->actor.world.pos.y, this->actor.world.pos.z, 0x0, 0x0, 0x0, ITEM00_RUPEE_RED); + this->rupees[rupeeIndex] = rupee; + this->rupees[rupeeIndex]->actor.gravity = -5.0f; + this->rupees[rupeeIndex]->actor.velocity.y = 0.0f; + Audio_PlayActorSound2(&this->actor, NA_SE_EV_RUPY_FALL); + rupee = this->rupees[rupeeIndex]; + rupee->unk152 = 60; + this->rupees[rupeeIndex]->actor.flags |= 0x10; + } else { + rupee = + (EnItem00*)Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_ITEM00, this->actor.world.pos.x + xOffset, + this->actor.world.pos.y, this->actor.world.pos.z, 0x0, 0x0, 0x0, ITEM00_RUPEE_GREEN); + this->rupees[rupeeIndex] = rupee; + this->rupees[rupeeIndex]->actor.gravity = -5.0f; + this->rupees[rupeeIndex]->actor.velocity.y = 0.0f; + Audio_PlayActorSound2(&this->actor, NA_SE_EV_RUPY_FALL); + rupee = this->rupees[rupeeIndex]; + rupee->unk152 = 60; + this->rupees[rupeeIndex]->actor.flags |= 0x10; + } + + this->rupeeIndex++; +} + +void EnRuppecrow_UpdatePosition(EnRuppecrow* this, GlobalContext* globalCtx) { + Vec3s nextPointDirection; + + EnRuppecrow_GetPointDirection(this->path, this->currentPoint, &this->actor.world, &nextPointDirection); + if (this->actor.bgCheckFlags & 0x8) { + nextPointDirection.y = this->actor.wallYaw; + } + + Math_SmoothStepToS(&this->actor.world.rot.y, nextPointDirection.y, 0x4, 0x3E8, 0x1); + this->actor.shape.rot.y = this->actor.world.rot.y; + Math_SmoothStepToS(&this->actor.world.rot.x, -nextPointDirection.x, 0x4, 0x3E8, 0x1); + + if (this->isGoingCounterClockwise & 1) { + if (EnRuppecrow_ReachedPointCounterClockwise(this, this->path, this->currentPoint)) { + if (this->currentPoint <= 0) { + this->currentPoint = this->path->count - 1; + } else { + this->currentPoint--; + } + + if (this->actionFunc == EnRuppecrow_FlyWhileDroppingRupees && + (!EnRuppecrow_CanSpawnBlueRupees(globalCtx) || (this->currentPoint % -2) == 0)) { + EnRuppecrow_SpawnRupee(this, globalCtx); + } + } + } else if (EnRuppecrow_ReachedPointClockwise(this, this->path, this->currentPoint)) { + if (this->currentPoint >= this->path->count - 1) { + this->currentPoint = 0; + } else { + this->currentPoint++; + } + + if (this->actionFunc == EnRuppecrow_FlyWhileDroppingRupees && + (!EnRuppecrow_CanSpawnBlueRupees(globalCtx) || (this->currentPoint % -2) == 0)) { + EnRuppecrow_SpawnRupee(this, globalCtx); + } + } +} + +s32 EnRuppecrow_CheckPlayedMatchingSong(GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (globalCtx->msgCtx.unk1202A == 0x3) { + switch (player->transformation) { + case PLAYER_FORM_DEKU: + if (globalCtx->msgCtx.unk1202E == OCARINA_SONG_SONATA) { + return true; + } + break; + case PLAYER_FORM_GORON: + if (globalCtx->msgCtx.unk1202E == OCARINA_SONG_GORON_LULLABY) { + return true; + } + break; + case PLAYER_FORM_ZORA: + if (globalCtx->msgCtx.unk1202E == OCARINA_SONG_NEW_WAVE) { + return true; + } + break; + case PLAYER_FORM_HUMAN: + if (globalCtx->msgCtx.unk1202E == OCARINA_SONG_SONATA) { + return true; + } else if (globalCtx->msgCtx.unk1202E == OCARINA_SONG_GORON_LULLABY) { + return true; + } else if (globalCtx->msgCtx.unk1202E == OCARINA_SONG_NEW_WAVE) { + return true; + } + break; + } + } + + return false; +} + +void EnRuppecrow_UpdateSpeed(EnRuppecrow* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + switch (player->transformation) { + case PLAYER_FORM_DEKU: + this->speedModifier = 7.0f; + break; + case PLAYER_FORM_GORON: + if (player->stateFlags3 & 0x1000) { // Goron Link is curled + this->speedModifier = 19.0f; + } else { + this->speedModifier = 7.0f; + } + break; + case PLAYER_FORM_ZORA: + this->speedModifier = 7.0f; + break; + case PLAYER_FORM_HUMAN: + if (player->stateFlags1 & 0x800000) { + this->speedModifier = 16.0f; + } else { + this->speedModifier = 7.0f; + } + break; + } + + this->skelAnime.playSpeed = this->speedModifier / 6.0f; + if (this->actor.xzDistToPlayer > 800.0f) { + this->speedModifier *= 0.5f; + } else if (this->actor.xzDistToPlayer > 500.0f) { + this->speedModifier *= 0.8f; + } else if (this->actor.xzDistToPlayer < 150.0f) { + this->speedModifier *= 1.2f; + } +} + +void EnRuppecrow_HandleDeath(EnRuppecrow* this) { + f32 scale; + + this->actor.speedXZ *= Math_CosS(this->actor.world.rot.x); + this->actor.velocity.y = 0.0f; + Animation_Change(&this->skelAnime, &object_crow_Anim_0000F0, 0.4f, 0.0f, 0.0f, 0x1, -3.0f); + + this->actor.shape.yOffset = 0.0f; + this->actor.targetArrowOffset = 0.0f; + this->actor.bgCheckFlags &= ~0x1; + + scale = this->actor.scale.x * 100.0f; + this->actor.world.pos.y += 20.0f * scale; + + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KAICHO_DEAD); + + this->unk_2CC = 0.5f; + if (this->actor.colChkInfo.damageEffect == 0x3) { + this->currentEffect = ENRUPPECROW_EFFECT_ICE; + this->unk_2C8 = 1.0f; + this->iceSfxTimer = 0.75f; + } else if (this->actor.colChkInfo.damageEffect == 0x4) { + this->currentEffect = ENRUPPECROW_EFFECT_LIGHT; + this->unk_2C8 = 5.0f; + } else if (this->actor.colChkInfo.damageEffect == 0x2) { + this->currentEffect = ENRUPPECROW_EFFECT_NONE; + this->unk_2C8 = 5.0f; + } + + func_800BCB70(&this->actor, 0x4000, 0xFF, 0x0, 0x28); + if (this->actor.flags & 0x8000) { + this->actor.speedXZ = 0.0f; + } + + this->collider.base.acFlags &= ~AC_ON; + this->actor.flags |= 0x10; + this->actionFunc = EnRuppecrow_FallToDespawn; +} + +void EnRuppecrow_UpdateDamage(EnRuppecrow* this, GlobalContext* globalCtx) { + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + func_800BE258(&this->actor, this->collider.elements); + + if (this->actor.colChkInfo.damageEffect != 0x1) { + this->actor.colChkInfo.health = 0; + this->actor.flags &= ~0x1; + Enemy_StartFinishingBlow(globalCtx, &this->actor); + EnRuppecrow_HandleDeath(this); + } + } +} + +void EnRuppecrow_HandleSong(EnRuppecrow* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + EnRuppecrow_UpdatePosition(this, globalCtx); + if (this->actor.xzDistToPlayer < 1000.0f && EnRuppecrow_CheckPlayedMatchingSong(globalCtx)) { + // If Link is in front, the guay will turn around and go the other way + if (Actor_IsActorFacingLink(&this->actor, 0x4000)) { + this->isGoingCounterClockwise |= 1; + if (this->currentPoint > 0) { + this->currentPoint--; + } else { + this->currentPoint = this->path->count - 1; + } + } + + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + this->actionFunc = EnRuppecrow_HandleSongCutscene; + } + + if (player->stateFlags2 & 0x8000000) { + Math_ApproachF(&this->actor.speedXZ, 0.0f, 0.1f, 1.0f); + } else { + Math_ApproachF(&this->actor.speedXZ, 6.0f, 0.1f, 0.1f); + } + + Actor_SetVelocityAndMoveXYRotation(&this->actor); + this->yOffset += 0x1000; + this->actor.shape.yOffset = Math_SinS(this->yOffset) * 500.0f; + + if ((globalCtx->state.frames % 43) == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KAICHO_CRY); + } +} + +void EnRuppecrow_HandleSongCutscene(EnRuppecrow* this, GlobalContext* globalCtx) { + EnRuppecrow_UpdatePosition(this, globalCtx); + + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_Start(this->actor.cutscene, &this->actor); + EnRuppecrow_UpdateSpeed(this, globalCtx); + this->actionFunc = EnRuppecrow_FlyWhileDroppingRupees; + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } + + Actor_SetVelocityAndMoveXYRotation(&this->actor); +} + +void EnRuppecrow_FlyWhileDroppingRupees(EnRuppecrow* this, GlobalContext* globalCtx) { + EnRuppecrow_UpdatePosition(this, globalCtx); + + if (this->rupeeIndex >= ENRUPPECROW_RUPEE_COUNT) { + // Finished spawning rupees; fly up and then despawn + this->speedModifier = 6.0f; + + // Source of the "Termina Field Guay Glitch"; guay will no longer fall if killed after this point + this->actor.gravity = 0.0f; + + Math_ApproachF(&this->actor.speedXZ, 6.0f, 0.2f, 0.5f); + Math_ApproachF(&this->actor.velocity.y, 3.0f, 0.2f, 0.5f); + + this->actionFunc = EnRuppecrow_FlyToDespawn; + this->skelAnime.playSpeed = 1.0f; + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + } else { + if (ActorCutscene_GetCurrentIndex() != this->actor.cutscene) { + EnRuppecrow_UpdateSpeed(this, globalCtx); + Math_ApproachF(&this->actor.speedXZ, this->speedModifier, 0.2f, 0.5f); + } + + Actor_SetVelocityAndMoveXYRotation(&this->actor); + this->yOffset += 0x1000; + this->actor.shape.yOffset = Math_SinS(this->yOffset) * 500.0f; + + if ((globalCtx->state.frames % 43) == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KAICHO_CRY); + } + } +} + +void EnRuppecrow_FlyToDespawn(EnRuppecrow* this, GlobalContext* globalCtx) { + if (this->actor.bgCheckFlags & 0x8) { + this->actor.world.rot.y *= -0x1; + } + + Math_ApproachF(&this->actor.speedXZ, this->speedModifier, 0.1f, 0.1f); + Math_ApproachF(&this->actor.velocity.y, 3.0f, 0.2f, 0.5f); + + if (this->actor.world.pos.y > 1000.0f || this->actor.xzDistToPlayer > 2000.0f) { + Actor_MarkForDeath(&this->actor); + } else { + this->yOffset += 0x800; + this->actor.shape.yOffset = Math_SinS(this->yOffset) * 500.0f; + + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + + if ((globalCtx->state.frames % 43) == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KAICHO_CRY); + } + } +} + +void EnRuppecrow_FallToDespawn(EnRuppecrow* this, GlobalContext* globalCtx) { + Math_StepToF(&this->actor.speedXZ, 0.0f, 0.5f); + + if (this->currentEffect != ENRUPPECROW_EFFECT_ICE) { + Math_StepToF(&this->unk_2C8, 0.0f, 0.05f); + this->unk_2CC = (this->unk_2C8 + 1.0f) * 0.25f; + this->unk_2CC = CLAMP_MAX(this->unk_2CC, 0.5f); + } else if (!Math_StepToF(&this->iceSfxTimer, 0.5f, 0.0125f)) { + func_800B9010(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } + + this->actor.colorFilterTimer = 40; + if (!(this->actor.flags & 0x8000)) { + if (this->currentEffect != ENRUPPECROW_EFFECT_ICE) { + Math_ScaledStepToS(&this->actor.shape.rot.x, 0x4000, 0x200); + this->actor.shape.rot.z += 0x1780; + } + + if (this->actor.bgCheckFlags & 0x1 || this->actor.floorHeight == BGCHECK_Y_MIN) { + EnRuppecrow_ShatterIce(this, globalCtx); + func_800B3030(globalCtx, &this->actor.world.pos, &gZeroVec3f, &gZeroVec3f, (this->actor.scale.x * 10000.0f), + 0x0, 0x0); + + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 0xB, NA_SE_EN_EXTINCT); + Actor_MarkForDeath(&this->actor); + return; + } + } + + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); +} + +void EnRuppecrow_Init(Actor* thisx, GlobalContext* globalCtx2) { + EnRuppecrow* this = THIS; + GlobalContext* globalCtx = globalCtx2; + + Actor_ProcessInitChain(&this->actor, sInitChain); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_crow_Skel_0010C0, &object_crow_Anim_0000F0, this->joinTable, + this->morphTable, ENRUPPECROW_LIMB_COUNT); + ActorShape_Init(&this->actor.shape, 2000.0f, func_800B3FC0, 20.0f); + + Collider_InitJntSph(globalCtx, &this->collider); + Collider_InitAndSetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, &this->colliderElement); + this->collider.elements->dim.worldSphere.radius = sJntSphInit.elements->dim.modelSphere.radius; + CollisionCheck_SetInfo(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + + Actor_SetScale(&this->actor, 0.01f); + this->actor.flags |= 0x2000000; + + this->path = func_8013D648(globalCtx, ENRUPPECROW_GET_PATH(&this->actor), 0x3F); + if (this->path != NULL) { + this->actionFunc = EnRuppecrow_HandleSong; + } else { + Actor_MarkForDeath(&this->actor); + } +} + +void EnRuppecrow_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnRuppecrow* this = THIS; + + Collider_DestroyJntSph(globalCtx, &this->collider); +} + +void EnRuppecrow_Update(Actor* thisx, GlobalContext* globalCtx) { + EnRuppecrow* this = THIS; + + EnRuppecrow_UpdateDamage(this, globalCtx); + this->actionFunc(this, globalCtx); + EnRuppecrow_UpdateRupees(this); + this->actor.focus.pos = this->actor.world.pos; + SkelAnime_Update(&this->skelAnime); + EnRuppecrow_UpdateCollision(this, globalCtx); +} + +void EnRuppecrow_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnRuppecrow* this = THIS; + + func_8012C28C(globalCtx->state.gfxCtx); + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + NULL, NULL, &this->actor); +} diff --git a/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.h b/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.h index eeba6774d..4c9cafa67 100644 --- a/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.h +++ b/src/overlays/actors/ovl_En_Ruppecrow/z_en_ruppecrow.h @@ -3,15 +3,38 @@ #include "global.h" +#define ENRUPPECROW_GET_PATH(thisx) (((thisx)->params & 0xFC00) >> 0xA) + +#define ENRUPPECROW_RUPEE_COUNT 20 +#define ENRUPPECROW_LIMB_COUNT 9 +#define ENRUPPECROW_LIMB_POS_COUNT 4 + struct EnRuppecrow; typedef void (*EnRuppecrowActionFunc)(struct EnRuppecrow*, GlobalContext*); typedef struct EnRuppecrow { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x94]; - /* 0x01D8 */ EnRuppecrowActionFunc actionFunc; - /* 0x01DC */ char unk_1DC[0x128]; + /* 0x000 */ Actor actor; + /* 0x144 */ EnItem00* rupees[ENRUPPECROW_RUPEE_COUNT]; + /* 0x194 */ SkelAnime skelAnime; + /* 0x1D8 */ EnRuppecrowActionFunc actionFunc; + /* 0x1DC */ UNK_TYPE4 unk_1DC; // unused + /* 0x1E0 */ Vec3s joinTable[ENRUPPECROW_LIMB_COUNT]; + /* 0x216 */ Vec3s morphTable[ENRUPPECROW_LIMB_COUNT]; + /* 0x24C */ Path* path; + /* 0x250 */ s32 currentPoint; + /* 0x254 */ ColliderJntSph collider; + /* 0x274 */ ColliderJntSphElement colliderElement; + /* 0x2B4 */ u16 isGoingCounterClockwise; + /* 0x2B8 */ f32 speedModifier; + /* 0x2BC */ s16 rupeeIndex; + /* 0x2BE */ s16 yOffset; + /* 0x2C0 */ UNK_TYPE4 unk_2C0; // unused + /* 0x2C4 */ u8 currentEffect; + /* 0x2C8 */ f32 unk_2C8; // set but not used + /* 0x2CC */ f32 unk_2CC; // set but not used + /* 0x2D0 */ f32 iceSfxTimer; + /* 0x2D4 */ Vec3f limbPos[ENRUPPECROW_LIMB_POS_COUNT]; } EnRuppecrow; // size = 0x304 extern const ActorInit En_Ruppecrow_InitVars; diff --git a/src/overlays/actors/ovl_En_Rz/z_en_rz.c b/src/overlays/actors/ovl_En_Rz/z_en_rz.c index e87dfa556..26551895a 100644 --- a/src/overlays/actors/ovl_En_Rz/z_en_rz.c +++ b/src/overlays/actors/ovl_En_Rz/z_en_rz.c @@ -1,7 +1,7 @@ /* * File: z_en_rz.c * Overlay: ovl_En_Rz - * Description: Rosa Sister + * Description: Rosa Sisters, Judo (red) and Marilla (blue) */ #include "z_en_rz.h" diff --git a/src/overlays/actors/ovl_En_Scopecoin/z_en_scopecoin.c b/src/overlays/actors/ovl_En_Scopecoin/z_en_scopecoin.c index 2c2f68652..b90ab3db9 100644 --- a/src/overlays/actors/ovl_En_Scopecoin/z_en_scopecoin.c +++ b/src/overlays/actors/ovl_En_Scopecoin/z_en_scopecoin.c @@ -1,7 +1,7 @@ /* * File: z_en_scopecoin.c * Overlay: ovl_En_Scopecoin - * Description: Telescope Coin + * Description: Termina Field rupees visible from the telescope */ #include "z_en_scopecoin.h" diff --git a/src/overlays/actors/ovl_En_Scopenuts/z_en_scopenuts.c b/src/overlays/actors/ovl_En_Scopenuts/z_en_scopenuts.c index 400c18044..9e2a1579d 100644 --- a/src/overlays/actors/ovl_En_Scopenuts/z_en_scopenuts.c +++ b/src/overlays/actors/ovl_En_Scopenuts/z_en_scopenuts.c @@ -1,7 +1,7 @@ /* * File: z_en_scopenuts.c * Overlay: ovl_En_Scopenuts - * Description: Astral Observatory - Business Scrub in Telescope + * Description: Business Scrub that sells you a Heart Piece */ #include "z_en_scopenuts.h" diff --git a/src/overlays/actors/ovl_En_Sda/z_en_sda.c b/src/overlays/actors/ovl_En_Sda/z_en_sda.c index 2059de563..e423a2046 100644 --- a/src/overlays/actors/ovl_En_Sda/z_en_sda.c +++ b/src/overlays/actors/ovl_En_Sda/z_en_sda.c @@ -1,7 +1,7 @@ /* * File: z_en_sda.c * Overlay: ovl_En_Sda - * Description: + * Description: Dynamic Shadow for Player */ #include "z_en_sda.h" diff --git a/src/overlays/actors/ovl_En_Shn/z_en_shn.h b/src/overlays/actors/ovl_En_Shn/z_en_shn.h index 8f02bd8c5..b5d98919d 100644 --- a/src/overlays/actors/ovl_En_Shn/z_en_shn.h +++ b/src/overlays/actors/ovl_En_Shn/z_en_shn.h @@ -10,7 +10,7 @@ typedef void (*EnShnActionFunc)(struct EnShn*, GlobalContext*); typedef struct EnShn { /* 0x0000 */ Actor actor; /* 0x0144 */ EnShnActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x1A8]; + /* 0x0148 */ char unk_148[0x1A8]; } EnShn; // size = 0x2F0 extern const ActorInit En_Shn_InitVars; diff --git a/src/overlays/actors/ovl_En_Si/z_en_si.h b/src/overlays/actors/ovl_En_Si/z_en_si.h index 60a7937a9..26e33e728 100644 --- a/src/overlays/actors/ovl_En_Si/z_en_si.h +++ b/src/overlays/actors/ovl_En_Si/z_en_si.h @@ -10,7 +10,7 @@ typedef void (*EnSiActionFunc)(struct EnSi*, GlobalContext*); typedef struct EnSi { /* 0x0000 */ Actor actor; /* 0x0144 */ EnSiActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x58]; + /* 0x0148 */ char unk_148[0x58]; } EnSi; // size = 0x1A0 extern const ActorInit En_Si_InitVars; diff --git a/src/overlays/actors/ovl_En_Slime/z_en_slime.h b/src/overlays/actors/ovl_En_Slime/z_en_slime.h index 6269f331e..c24cae04e 100644 --- a/src/overlays/actors/ovl_En_Slime/z_en_slime.h +++ b/src/overlays/actors/ovl_En_Slime/z_en_slime.h @@ -10,7 +10,7 @@ typedef void (*EnSlimeActionFunc)(struct EnSlime*, GlobalContext*); typedef struct EnSlime { /* 0x0000 */ Actor actor; /* 0x0144 */ EnSlimeActionFunc actionFunc; - /* 0x0148 */ char unk_144[0xC0]; + /* 0x0148 */ char unk_148[0xC0]; } EnSlime; // size = 0x208 extern const ActorInit En_Slime_InitVars; diff --git a/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c b/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c index 53212d0bf..140fc2c71 100644 --- a/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c +++ b/src/overlays/actors/ovl_En_Sob1/z_en_sob1.c @@ -264,7 +264,7 @@ u16 EnSob1_GetWelcome(EnSob1* this, GlobalContext* globalCtx) { return 0x688; case PLAYER_MASK_BLAST: return 0x689; - case PLAYER_MASK_KAFEI: + case PLAYER_MASK_KAFEIS_MASK: return 0x68A; } } else if (this->shopType == ZORA_SHOP) { @@ -1695,7 +1695,7 @@ void EnSob1_DrawBombShopkeeper(Actor* thisx, GlobalContext* globalCtx) { EnSob1_DrawStickDirectionPrompt(globalCtx, this); frames = globalCtx->gameplayFrames; func_8012C2DC(globalCtx->state.gfxCtx); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_Scale(1.0f, 1.0f, 1.0f, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPSegment(POLY_XLU_DISP++, 0x08, diff --git a/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c b/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c index 5d045ca75..01c803995 100644 --- a/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c +++ b/src/overlays/actors/ovl_En_Ssh/z_en_ssh.c @@ -1,10 +1,11 @@ /* * File: z_en_ssh.c * Overlay: ovl_En_Ssh - * Description: Cursed Man + * Description: Cursed Man (Swamp Spider House) */ #include "z_en_ssh.h" +#include "objects/object_ssh/object_ssh.h" #define FLAGS 0x00000035 @@ -15,16 +16,15 @@ void EnSsh_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnSsh_Update(Actor* thisx, GlobalContext* globalCtx); void EnSsh_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_809755C0(EnSsh* this, GlobalContext* globalCtx); -void func_80975720(EnSsh* this, GlobalContext* globalCtx); -void func_809758B0(EnSsh* this, GlobalContext* globalCtx); -void func_80975998(EnSsh* this, GlobalContext* globalCtx); -void func_80975A98(EnSsh* this, GlobalContext* globalCtx); -void func_80975C14(EnSsh* this, GlobalContext* globalCtx); +void EnSsh_Wait(EnSsh* this, GlobalContext* globalCtx); +void EnSsh_Idle(EnSsh* this, GlobalContext* globalCtx); +void EnSsh_Land(EnSsh* this, GlobalContext* globalCtx); +void EnSsh_Drop(EnSsh* this, GlobalContext* globalCtx); +void EnSsh_Return(EnSsh* this, GlobalContext* globalCtx); +void EnSsh_Start(EnSsh* this, GlobalContext* globalCtx); -void EnSsh_SetupAction(EnSsh* this, EnSshActionFunc actionFunc); +extern AnimationHeader D_06000304; -#if 0 const ActorInit En_Ssh_InitVars = { ACTOR_EN_SSH, ACTORCAT_NPC, @@ -37,139 +37,900 @@ const ActorInit En_Ssh_InitVars = { (ActorFunc)EnSsh_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80976030 = { - { COLTYPE_HIT6, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit1 = { + { + COLTYPE_HIT6, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 32, 50, -24, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_8097605C = { 1, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 1, 0, 0, 0, MASS_IMMOVABLE }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80976068 = { - { COLTYPE_HIT6, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit2 = { + { + COLTYPE_HIT6, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 20, 60, -30, { 0, 0, 0 } }, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_80976094[1] = { +static ColliderJntSphElementInit sJntSphElementsInit[1] = { { - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x04 }, { 0x00000000, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x04 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 1, { { 0, -240, 0 }, 28 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_809760B8 = { - { COLTYPE_HIT6, AT_ON | AT_TYPE_ENEMY, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_JNTSPH, }, - 1, D_80976094, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_HIT6, + AT_ON | AT_TYPE_ENEMY, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit, }; -#endif +void EnSsh_SetupAction(EnSsh* this, EnSshActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -extern ColliderCylinderInit D_80976030; -extern CollisionCheckInfoInit2 D_8097605C; -extern ColliderCylinderInit D_80976068; -extern ColliderJntSphElementInit D_80976094[1]; -extern ColliderJntSphInit D_809760B8; +void EnSsh_SpawnShockwave(EnSsh* this, GlobalContext* globalCtx) { + Vec3f zeroVec = { 0.0f, 0.0f, 0.0f }; + Vec3f pos; -extern UNK_TYPE D_060000D8; -extern UNK_TYPE D_06000304; -extern UNK_TYPE D_06005850; + pos.x = this->actor.world.pos.x; + pos.y = this->actor.floorHeight; + pos.z = this->actor.world.pos.z; + EffectSsBlast_SpawnWhiteCustomScale(globalCtx, &pos, &zeroVec, &zeroVec, 100, 220, 8); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/EnSsh_SetupAction.s") +s32 EnSsh_CreateBlureEffect(GlobalContext* globalCtx) { + EffectBlureInit1 blureInit; + u8 sP1StartColor[4] = { 255, 255, 255, 75 }; + u8 sP2StartColor[4] = { 255, 255, 255, 75 }; + u8 sP1EndColor[4] = { 255, 255, 255, 0 }; + u8 sP2EndColor[4] = { 255, 255, 255, 0 }; + s32 i; + s32 blureIdx; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80973EFC.s") + for (i = 0; i < ARRAY_COUNT(blureInit.p1StartColor); i++) { + blureInit.p1StartColor[i] = sP1StartColor[i]; + blureInit.p2StartColor[i] = sP2StartColor[i]; + blureInit.p1EndColor[i] = sP1EndColor[i]; + blureInit.p2EndColor[i] = sP2EndColor[i]; + } + blureInit.elemDuration = 6; + blureInit.unkFlag = false; + blureInit.calcMode = 3; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80973F84.s") + Effect_Add(globalCtx, &blureIdx, 1, 0, 0, &blureInit); + return blureIdx; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974080.s") +s32 EnSsh_CheckCeilingPos(EnSsh* this, GlobalContext* globalCtx) { + CollisionPoly* poly; + s32 bgId; + Vec3f posB; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974118.s") + posB.x = this->actor.world.pos.x; + posB.y = this->actor.world.pos.y + 1000.0f; + posB.z = this->actor.world.pos.z; + if (!BgCheck_EntityLineTest1(&globalCtx->colCtx, &this->actor.world.pos, &posB, &this->ceilingPos, &poly, 0, 0, 1, + 1, &bgId)) { + return false; + } + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974220.s") +void EnSsh_AddBlureVertex(EnSsh* this) { + Vec3f p1Base = { 834.0f, 834.0f, 0.0f }; + Vec3f p2Base = { 834.0f, -584.0f, 0.0f }; + Vec3f p1; + Vec3f p2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_8097424C.s") + p1Base.x *= this->colliderScale; + p1Base.y *= this->colliderScale; + p1Base.z *= this->colliderScale; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974374.s") + p2Base.x *= this->colliderScale; + p2Base.y *= this->colliderScale; + p2Base.z *= this->colliderScale; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_809744A8.s") + Matrix_StatePush(); + Matrix_MultiplyVector3fByState(&p1Base, &p1); + Matrix_MultiplyVector3fByState(&p2Base, &p2); + Matrix_StatePop(); + EffectBlure_AddVertex(Effect_GetByIndex(this->blureIdx), &p1, &p2); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_809744C8.s") +void EnSsh_AddBlureSpace(EnSsh* this) { + EffectBlure_AddSpace(Effect_GetByIndex(this->blureIdx)); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_809744FC.s") +void EnSsh_InitColliders(EnSsh* this, GlobalContext* globalCtx) { + ColliderCylinderInit* cylinders[] = { + &sCylinderInit1, &sCylinderInit1, &sCylinderInit1, &sCylinderInit2, &sCylinderInit2, &sCylinderInit2, + }; + s32 i; + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974540.s") + for (i = 0; i < ARRAY_COUNT(this->collider1); i++) { + Collider_InitAndSetCylinder(globalCtx, &this->collider1[i], &this->actor, cylinders[i]); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974590.s") + this->collider1[0].info.bumper.dmgFlags = 0x38A9; + this->collider1[1].info.bumper.dmgFlags = ~0x83038A9; + this->collider1[2].base.colType = COLTYPE_METAL; + this->collider1[2].info.bumperFlags = (BUMP_NO_AT_INFO | BUMP_HOOKABLE | BUMP_ON); + this->collider1[2].info.elemType = ELEMTYPE_UNK2; + this->collider1[2].info.bumper.dmgFlags = ~0x83038A9; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_809745BC.s") + CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(2), &sColChkInfoInit); + Collider_InitJntSph(globalCtx, &this->collider2); + Collider_SetJntSph(globalCtx, &this->collider2, &this->actor, &sJntSphInit, this->collider2Elements); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974730.s") +f32 EnSsh_SetAnimation(EnSsh* this, s32 arg0) { + AnimationHeader* animation[] = { &object_ssh_Anim_006D78, &object_ssh_Anim_001494, &object_ssh_Anim_001494, + &object_ssh_Anim_006788, &object_ssh_Anim_001494, &object_ssh_Anim_001494, + &object_ssh_Anim_006D78 }; + f32 playerbackSpeed[] = { 1.0f, 4.0f, 1.0f, 1.0f, 8.0f, 6.0f, 2.0f }; + u8 mode[] = { + ANIMMODE_ONCE_INTERP, ANIMMODE_ONCE_INTERP, ANIMMODE_LOOP_INTERP, ANIMMODE_ONCE_INTERP, + ANIMMODE_LOOP_INTERP, ANIMMODE_LOOP_INTERP, ANIMMODE_LOOP_INTERP, + }; + f32 frameCount = Animation_GetLastFrame(animation[arg0]); + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_8097480C.s") + Animation_Change(&this->skelAnime, animation[arg0], playerbackSpeed[arg0], 0.0f, frameCount, mode[arg0], -6.0f); + return frameCount; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_809748DC.s") +void EnSsh_SetWaitAnimation(EnSsh* this) { + EnSsh_SetAnimation(this, SSH_ANIM_WAIT); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_8097497C.s") +void EnSsh_SetReturnAnimation(EnSsh* this) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALTU_UP); + EnSsh_SetAnimation(this, SSH_ANIM_UP); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_809749B8.s") +void EnSsh_SetLandAnimation(EnSsh* this) { + this->actor.world.pos.y = this->floorHeightOffset + this->actor.floorHeight; + this->animTimer = EnSsh_SetAnimation(this, SSH_ANIM_LAND); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974A24.s") +void EnSsh_SetDropAnimation(EnSsh* this) { + if (this->unkTimer == 0) { + this->animTimer = EnSsh_SetAnimation(this, SSH_ANIM_DROP); + } + this->actor.velocity.y = -10.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974B0C.s") +void EnSsh_SetStunned(EnSsh* this) { + if (this->stunTimer == 0) { + this->stateFlags |= SSH_STATE_ATTACKED; + this->stunTimer = 120; + this->actor.colorFilterTimer = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974B44.s") +void EnSsh_SetColliderScale(EnSsh* this, f32 arg1, f32 arg2) { + s32 i; + f32 radius = this->collider2.elements[0].dim.modelSphere.radius; + f32 height; + f32 yShift; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974B84.s") + radius *= arg1; + this->collider2.elements[0].dim.modelSphere.radius = radius; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974CC8.s") + for (i = 0; i < ARRAY_COUNT(this->collider1); i++) { + yShift = this->collider1[i].dim.yShift; + radius = this->collider1[i].dim.radius; + height = this->collider1[i].dim.height; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974D3C.s") + height *= arg1; + yShift *= arg1; + radius *= arg1 * arg2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974E44.s") + this->collider1[i].dim.yShift = yShift; + this->collider1[i].dim.radius = radius; + this->collider1[i].dim.height = height; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974EA0.s") + Actor_SetScale(&this->actor, 0.04f * arg1); + this->floorHeightOffset = 60.0f * arg1; + this->colliderScale = arg1 * 1.5f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80974F78.s") +s32 EnSsh_Damaged(EnSsh* this) { + if ((this->stunTimer == 120) && (this->stateFlags & SSH_STATE_STUNNED)) { + func_800BCB70(&this->actor, 0, 200, 0, this->stunTimer); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_8097502C.s") + if (DECR(this->stunTimer) != 0) { + Math_SmoothStepToS(&this->maxTurnRate, 10000, 10, 1000, 1); + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80975070.s") + this->stunTimer = 0; + this->stateFlags &= ~SSH_STATE_STUNNED; + this->spinTimer = 0; + if (this->swayTimer == 0) { + this->spinTimer = 30; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80975128.s") + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALTU_ROLL); + Audio_PlayActorSound2(&this->actor, NA_SE_VO_ST_ATTACK); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80975300.s") + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/EnSsh_Init.s") +void EnSsh_Turn(EnSsh* this, GlobalContext* globalCtx) { + if (this->hitTimer != 0) { + this->hitTimer--; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/EnSsh_Destroy.s") + if (DECR(this->spinTimer) != 0) { + this->actor.world.rot.y += (s16)(10000.0f * (this->spinTimer / 30.0f)); + } else if ((this->swayTimer == 0) && (this->stunTimer == 0)) { + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer, 4, 10000, 1); + } + this->actor.shape.rot.y = this->actor.world.rot.y; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_809755C0.s") +void EnSsh_Stunned(EnSsh* this, GlobalContext* globalCtx) { + if ((this->swayTimer == 0) && (this->stunTimer == 0)) { + Math_SmoothStepToS(&this->actor.world.rot.y, this->actor.yawTowardsPlayer ^ 0x8000, 4, this->maxTurnRate, 1); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_8097561C.s") + this->actor.shape.rot.y = this->actor.world.rot.y; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_809756D0.s") + if (this->stunTimer < 30) { + if (this->stunTimer & 1) { + this->actor.shape.rot.y += 2000; + } else { + this->actor.shape.rot.y -= 2000; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80975720.s") +void EnSsh_UpdateYaw(EnSsh* this, GlobalContext* globalCtx) { + if (this->stunTimer != 0) { + EnSsh_Stunned(this, globalCtx); + } else { + EnSsh_Turn(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_809758B0.s") +void EnSsh_Bob(EnSsh* this, GlobalContext* globalCtx) { + f32 bobVel = 0.5f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80975998.s") + if (globalCtx->state.frames & 8) { + bobVel *= -1.0f; + } + Math_SmoothStepToF(&this->actor.velocity.y, bobVel, 0.4f, 1000.0f, 0.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80975A98.s") +s32 EnSsh_IsCloseToLink(EnSsh* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + f32 yDist; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80975B6C.s") + if (this->stateFlags & SSH_STATE_GROUND_START) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80975C14.s") + if (this->unkTimer != 0) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/EnSsh_Update.s") + if (this->swayTimer != 0) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80975DBC.s") + if (this->animTimer != 0) { + return true; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/func_80975EB8.s") + if (this->actor.xzDistToPlayer > 160.0f) { + return false; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Ssh/EnSsh_Draw.s") + yDist = this->actor.world.pos.y - player->actor.world.pos.y; + if ((yDist < 0.0f) || (yDist > 400.0f)) { + return false; + } + + if (player->actor.world.pos.y < this->actor.floorHeight) { + return false; + } + + return true; +} + +s32 EnSsh_IsCloseToHome(EnSsh* this) { + f32 vel = this->actor.velocity.y; + f32 nextY = this->actor.world.pos.y + vel * 2.0f; + + if (this->actor.home.pos.y <= nextY) { + return true; + } + return false; +} + +s32 EnSsh_IsCloseToGround(EnSsh* this) { + f32 vel = this->actor.velocity.y; + f32 nextY = this->actor.world.pos.y + vel * 2.0f; + + if ((nextY - this->actor.floorHeight) <= this->floorHeightOffset) { + return true; + } + return false; +} + +void EnSsh_Sway(EnSsh* this) { + Vec3f swayVecBase; + Vec3f swayVec; + f32 temp_f20; + s16 swayAngle; + + if (this->swayTimer != 0) { + this->swayAngle += 1600; + this->swayTimer--; + if (this->swayTimer == 0) { + this->swayAngle = 0; + } + + temp_f20 = (this->swayTimer * (1.0f / 6)); + swayAngle = Math_SinS(this->swayAngle) * (temp_f20 * (0x10000 / 360.0f)); + temp_f20 = this->actor.world.pos.y - this->ceilingPos.y; + + swayVecBase.x = Math_SinS(swayAngle) * temp_f20; + swayVecBase.y = Math_CosS(swayAngle) * temp_f20; + swayVecBase.z = 0.0f; + + Matrix_StatePush(); + Matrix_InsertTranslation(this->ceilingPos.x, this->ceilingPos.y, this->ceilingPos.z, MTXMODE_NEW); + Matrix_InsertYRotation_f(this->actor.world.rot.y * (M_PI / 0x8000), MTXMODE_APPLY); + Matrix_MultiplyVector3fByState(&swayVecBase, &swayVec); + Matrix_StatePop(); + + this->actor.shape.rot.z = -(swayAngle * 2); + this->actor.world.pos.x = swayVec.x; + this->actor.world.pos.z = swayVec.z; + } +} + +void EnSsh_CheckBodyStickHit(EnSsh* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + ColliderInfo* colliderInfo = &this->collider1[0].info; + + if (player->unk_B28 != 0) { + colliderInfo->bumper.dmgFlags |= 2; + this->collider1[1].info.bumper.dmgFlags &= ~2; + this->collider1[2].info.bumper.dmgFlags &= ~2; + } else { + colliderInfo->bumper.dmgFlags &= ~2; + this->collider1[1].info.bumper.dmgFlags |= 2; + this->collider1[2].info.bumper.dmgFlags |= 2; + } +} + +s32 EnSsh_CheckHitPlayer(EnSsh* this, GlobalContext* globalCtx) { + s32 i; + s32 hit = false; + + if ((this->hitCount == 0) && (this->spinTimer == 0)) { + return false; + } + + for (i = 0; i < ARRAY_COUNT(this->collider1) / 2; i++) { + if (this->collider1[3 + i].base.ocFlags2 & OC2_HIT_PLAYER) { + this->collider1[3 + i].base.ocFlags2 &= ~OC2_HIT_PLAYER; + hit = true; + } + } + + if (!hit) { + return false; + } + + this->hitTimer = 30; + if (this->swayTimer == 0) { + this->spinTimer = this->hitTimer; + } + + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALTU_ROLL); + Audio_PlayActorSound2(&this->actor, NA_SE_VO_ST_ATTACK); + + globalCtx->damagePlayer(globalCtx, -8); + + func_800B8D98(globalCtx, &this->actor, 4.0f, this->actor.yawTowardsPlayer, 6.0f); + this->hitCount--; + return true; +} + +s32 EnSsh_CheckHitFront(EnSsh* this) { + u32 acFlags; + + if (this->collider1[2].base.acFlags) {} + acFlags = this->collider1[2].base.acFlags; + + if (!!(acFlags & AC_HIT) == 0) { + return false; + } + + this->collider1[2].base.acFlags &= ~AC_HIT; + this->invincibilityTimer = 8; + + if ((this->swayTimer == 0) && (this->hitTimer == 0) && (this->stunTimer == 0)) { + this->swayTimer = 60; + } + + return true; +} + +s32 EnSsh_CheckHitBack(EnSsh* this, GlobalContext* globalCtx) { + ColliderCylinder* collider = &this->collider1[0]; + s32 hit = false; + + if (collider->base.acFlags & AC_HIT) { + collider->base.acFlags &= ~AC_HIT; + hit = true; + } + + collider = &this->collider1[1]; + if (collider->base.acFlags & AC_HIT) { + collider->base.acFlags &= ~AC_HIT; + hit = true; + } + + if (!hit) { + return false; + } + + this->invincibilityTimer = 8; + if (this->hitCount <= 0) { + this->hitCount++; + } + + if (this->stunTimer == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + Audio_PlayActorSound2(&this->actor, NA_SE_VO_ST_DAMAGE); + } + + EnSsh_SetStunned(this); + this->stateFlags |= SSH_STATE_STUNNED; + return false; +} + +s32 EnSsh_CollisionCheck(EnSsh* this, GlobalContext* globalCtx) { + if (this->stunTimer == 0) { + EnSsh_CheckHitPlayer(this, globalCtx); + } + + if (EnSsh_CheckHitFront(this)) { + return false; + } + + if (globalCtx->actorCtx.unk2 != 0) { + this->invincibilityTimer = 8; + if (this->stunTimer == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + Audio_PlayActorSound2(&this->actor, NA_SE_VO_ST_DAMAGE); + } + EnSsh_SetStunned(this); + this->stateFlags |= SSH_STATE_STUNNED; + return false; + } + + return EnSsh_CheckHitBack(this, globalCtx); +} + +void EnSsh_SetBodyCylinderAC(EnSsh* this, GlobalContext* globalCtx) { + Collider_UpdateCylinder(&this->actor, &this->collider1[0]); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider1[0].base); +} + +void EnSsh_SetLegsCylinderAC(EnSsh* this, GlobalContext* globalCtx) { + s16 angleTowardsLink = ABS_ALT((s16)(this->actor.yawTowardsPlayer - this->actor.shape.rot.y)); + + if (angleTowardsLink < (90 * (0x10000 / 360))) { + Collider_UpdateCylinder(&this->actor, &this->collider1[2]); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider1[2].base); + } else { + Collider_UpdateCylinder(&this->actor, &this->collider1[1]); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider1[1].base); + } +} + +s32 EnSsh_SetCylinderOC(EnSsh* this, GlobalContext* globalCtx) { + Vec3f colliderOffsets[] = { { 40.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f }, { -40.0f, 0.0f, 0.0f } }; + Vec3f colliderPos; + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->collider1) / 2; i++) { + colliderPos = this->actor.world.pos; + + colliderOffsets[i].x *= this->colliderScale; + colliderOffsets[i].y *= this->colliderScale; + colliderOffsets[i].z *= this->colliderScale; + + Matrix_StatePush(); + Matrix_InsertTranslation(colliderPos.x, colliderPos.y, colliderPos.z, MTXMODE_NEW); + Matrix_InsertYRotation_f(BINANG_TO_RAD(this->initialYaw), MTXMODE_APPLY); + Matrix_MultiplyVector3fByState(&colliderOffsets[i], &colliderPos); + Matrix_StatePop(); + + this->collider1[3 + i].dim.pos.x = colliderPos.x; + this->collider1[3 + i].dim.pos.y = colliderPos.y; + this->collider1[3 + i].dim.pos.z = colliderPos.z; + + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider1[3 + i].base); + } + + return true; +} + +void EnSsh_SetColliders(EnSsh* this, GlobalContext* globalCtx) { + if (this->actor.colChkInfo.health == 0) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + return; + } + + if (this->hitTimer == 0) { + EnSsh_SetCylinderOC(this, globalCtx); + } + + if (DECR(this->invincibilityTimer) == 0) { + EnSsh_SetBodyCylinderAC(this, globalCtx); + EnSsh_SetLegsCylinderAC(this, globalCtx); + } +} + +void EnSsh_Init(Actor* thisx, GlobalContext* globalCtx) { + // @bug - this symbol no longer exists, reads from a random place in object_ssh_Tex_000190 instead + f32 frameCount = Animation_GetLastFrame(&D_06000304); + s32 pad; + EnSsh* this = THIS; + + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 30.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_ssh_Skel_006470, NULL, this->jointTable, this->morphtable, 30); + Animation_Change(&this->skelAnime, &object_ssh_Anim_001494, 1.0f, 0.0f, frameCount, ANIMMODE_LOOP_INTERP, 0.0f); + this->blureIdx = EnSsh_CreateBlureEffect(globalCtx); + EnSsh_InitColliders(this, globalCtx); + this->stateFlags = 0; + this->hitCount = 0; + EnSsh_CheckCeilingPos(this, globalCtx); + + if (!ENSSH_IS_CHILD(&this->actor)) { + this->stateFlags |= SSH_STATE_FATHER; + } + + if (!(this->stateFlags & SSH_STATE_FATHER)) { + EnSsh_SetColliderScale(this, 0.5f, 1.0f); + } else { + EnSsh_SetColliderScale(this, 0.75f, 1.0f); + } + + this->actor.gravity = 0.0f; + this->initialYaw = this->actor.world.rot.y; + EnSsh_SetupAction(this, EnSsh_Start); + if (func_8012F22C(globalCtx->sceneNum) >= 30) { + Actor_MarkForDeath(&this->actor); + } +} + +void EnSsh_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnSsh* this = THIS; + s32 i; + + Effect_Destroy(globalCtx, this->blureIdx); + + for (i = 0; i < ARRAY_COUNT(this->collider1); i++) { + Collider_DestroyCylinder(globalCtx, &this->collider1[i]); + } + + Collider_DestroyJntSph(globalCtx, &this->collider2); +} + +void EnSsh_Wait(EnSsh* this, GlobalContext* globalCtx) { + if (EnSsh_IsCloseToLink(this, globalCtx)) { + EnSsh_SetDropAnimation(this); + EnSsh_SetupAction(this, EnSsh_Drop); + } else { + EnSsh_Bob(this, globalCtx); + } +} + +void EnSsh_Talk(EnSsh* this, GlobalContext* globalCtx) { + EnSsh_Bob(this, globalCtx); + + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + switch (globalCtx->msgCtx.unk11F04) { + case 0x904: + case 0x905: + case 0x906: + case 0x908: + case 0x910: + case 0x911: + case 0x912: + case 0x914: + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + break; + + default: + func_801477B4(globalCtx); + this->actionFunc = EnSsh_Idle; + break; + } + } +} + +void func_809756D0(EnSsh* this, GlobalContext* globalCtx) { + u16 phi_a1; + + if (gSaveContext.weekEventReg[34] & 8) { + phi_a1 = 0x914; + } else { + phi_a1 = 0x910; + gSaveContext.weekEventReg[34] |= 8; + } + func_801518B0(globalCtx, phi_a1, &this->actor); +} + +void EnSsh_Idle(EnSsh* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + this->actionFunc = EnSsh_Talk; + func_809756D0(this, globalCtx); + return; + } + + if ((this->unkTimer != 0) && (DECR(this->unkTimer) == 0)) { + EnSsh_SetAnimation(this, SSH_ANIM_WAIT); + } + + if ((this->animTimer != 0) && (DECR(this->animTimer) == 0)) { + EnSsh_SetAnimation(this, SSH_ANIM_WAIT); + } + + if (!EnSsh_IsCloseToLink(this, globalCtx)) { + EnSsh_SetReturnAnimation(this); + EnSsh_SetupAction(this, EnSsh_Return); + return; + } + + if (DECR(this->sfxTimer) == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALTU_LAUGH); + this->sfxTimer = 64; + } + + EnSsh_Bob(this, globalCtx); + + if ((this->unkTimer == 0) && (this->animTimer == 0) && (this->actor.xzDistToPlayer < 100.0f) && + Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx)) { + func_800B8614(&this->actor, globalCtx, 100.0f); + } +} + +void EnSsh_Land(EnSsh* this, GlobalContext* globalCtx) { + if ((this->unkTimer != 0) && (DECR(this->unkTimer) == 0)) { + EnSsh_SetAnimation(this, SSH_ANIM_WAIT); + } + + if ((this->animTimer != 0) && (DECR(this->animTimer) == 0)) { + EnSsh_SetAnimation(this, SSH_ANIM_WAIT); + } + + if ((this->actor.floorHeight + this->floorHeightOffset) <= this->actor.world.pos.y) { + EnSsh_SetupAction(this, EnSsh_Idle); + } else { + Math_SmoothStepToF(&this->actor.velocity.y, 2.0f, 0.6f, 1000.0f, 0.0f); + } +} + +void EnSsh_Drop(EnSsh* this, GlobalContext* globalCtx) { + if ((this->unkTimer != 0) && (DECR(this->unkTimer) == 0)) { + EnSsh_SetAnimation(this, SSH_ANIM_DROP); + } + + if (!EnSsh_IsCloseToLink(this, globalCtx)) { + EnSsh_SetReturnAnimation(this); + EnSsh_SetupAction(this, EnSsh_Return); + } else if (EnSsh_IsCloseToGround(this)) { + EnSsh_SpawnShockwave(this, globalCtx); + EnSsh_SetLandAnimation(this); + EnSsh_SetupAction(this, EnSsh_Land); + } else if (DECR(this->sfxTimer) == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALTU_DOWN); + this->sfxTimer = 3; + } +} + +void EnSsh_Return(EnSsh* this, GlobalContext* globalCtx) { + f32 frameRatio = this->skelAnime.curFrame / (this->skelAnime.animLength - 1.0f); + + if (frameRatio == 1.0f) { + EnSsh_SetReturnAnimation(this); + } + + if (EnSsh_IsCloseToLink(this, globalCtx)) { + EnSsh_SetDropAnimation(this); + EnSsh_SetupAction(this, EnSsh_Drop); + } else if (EnSsh_IsCloseToHome(this)) { + EnSsh_SetWaitAnimation(this); + EnSsh_SetupAction(this, EnSsh_Wait); + } else { + this->actor.velocity.y = 4.0f * frameRatio; + } +} + +void EnSsh_UpdateColliderScale(EnSsh* this) { + if (this->stateFlags & SSH_STATE_SPIN) { + if (this->spinTimer == 0) { + this->stateFlags &= ~SSH_STATE_SPIN; + if (!(this->stateFlags & SSH_STATE_FATHER)) { + EnSsh_SetColliderScale(this, 0.5f, 1.0f); + } else { + EnSsh_SetColliderScale(this, 0.75f, 1.0f); + } + } + } else if (this->spinTimer != 0) { + this->stateFlags |= SSH_STATE_SPIN; + if (!(this->stateFlags & SSH_STATE_FATHER)) { + EnSsh_SetColliderScale(this, 0.5f, 2.0f); + } else { + EnSsh_SetColliderScale(this, 0.75f, 2.0f); + } + } +} + +void EnSsh_Start(EnSsh* this, GlobalContext* globalCtx) { + if (!EnSsh_IsCloseToGround(this)) { + EnSsh_SetupAction(this, EnSsh_Wait); + EnSsh_Wait(this, globalCtx); + } else { + EnSsh_SetLandAnimation(this); + this->stateFlags |= SSH_STATE_GROUND_START; + EnSsh_SetupAction(this, EnSsh_Land); + EnSsh_Land(this, globalCtx); + } +} + +void EnSsh_Update(Actor* thisx, GlobalContext* globalCtx) { + EnSsh* this = THIS; + + EnSsh_UpdateColliderScale(this); + + if (EnSsh_CollisionCheck(this, globalCtx)) { + return; + } + + if (this->stunTimer != 0) { + EnSsh_Damaged(this); + } else { + SkelAnime_Update(&this->skelAnime); + Actor_ApplyMovement(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); + this->actionFunc(this, globalCtx); + } + + EnSsh_UpdateYaw(this, globalCtx); + + if (DECR(this->blinkTimer) == 0) { + this->blinkTimer = Rand_S16Offset(60, 60); + } + + this->blinkState = this->blinkTimer; + if (this->blinkState >= 3) { + this->blinkState = 0; + } + + EnSsh_SetColliders(this, globalCtx); + Actor_SetHeight(&this->actor, 0.0f); +} + +s32 EnSsh_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + EnSsh* this = THIS; + + switch (limbIndex) { + case 1: + if ((this->spinTimer != 0) && (this->swayTimer == 0)) { + if (this->spinTimer >= 2) { + EnSsh_AddBlureVertex(this); + } else { + EnSsh_AddBlureSpace(this); + } + } + break; + + case 4: + if (this->stateFlags & SSH_STATE_FATHER) { + *dList = object_ssh_DL_005850; + } + break; + + case 5: + if (this->stateFlags & SSH_STATE_FATHER) { + *dList = object_ssh_DL_005210; + } + break; + + case 8: + if (this->stateFlags & SSH_STATE_FATHER) { + *dList = object_ssh_DL_005F78; + } + break; + } + return false; +} + +void EnSsh_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnSsh* this = THIS; + + if ((limbIndex == 5) && (this->stateFlags & SSH_STATE_FATHER)) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + gSPDisplayList(POLY_OPA_DISP++, object_ssh_DL_0000D8); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + Collider_UpdateSpheres(limbIndex, &this->collider2); +} + +void EnSsh_Draw(Actor* thisx, GlobalContext* globalCtx) { + static TexturePtr D_80976178[] = { object_ssh_Tex_001970, object_ssh_Tex_001DF0, object_ssh_Tex_0021F0 }; + s32 pad; + EnSsh* this = THIS; + + EnSsh_CheckBodyStickHit(this, globalCtx); + EnSsh_Sway(this); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, SEGMENTED_TO_VIRTUAL(D_80976178[this->blinkState])); + + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, EnSsh_OverrideLimbDraw, + EnSsh_PostLimbDraw, &this->actor); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Ssh/z_en_ssh.h b/src/overlays/actors/ovl_En_Ssh/z_en_ssh.h index 7d081f88c..172ecf0a5 100644 --- a/src/overlays/actors/ovl_En_Ssh/z_en_ssh.h +++ b/src/overlays/actors/ovl_En_Ssh/z_en_ssh.h @@ -7,11 +7,53 @@ struct EnSsh; typedef void (*EnSshActionFunc)(struct EnSsh*, GlobalContext*); +#define SSH_STATE_STUNNED (1 << 0) +#define SSH_STATE_GROUND_START (1 << 2) +#define SSH_STATE_ATTACKED (1 << 3) +#define SSH_STATE_SPIN (1 << 4) +#define SSH_STATE_FATHER (1 << 5) + +typedef enum { + SSH_ANIM_UNK0, // Unused animation. Possibly being knocked back? + SSH_ANIM_UP, + SSH_ANIM_WAIT, + SSH_ANIM_LAND, + SSH_ANIM_DROP, + SSH_ANIM_UNK5, // Slower version of ANIM_DROP + SSH_ANIM_UNK6 // Faster repeating version of ANIM_UNK0 +} EnSshAnimation; + +#define ENSSH_IS_CHILD(thisx) ((thisx)->params & 0xF) + typedef struct EnSsh { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1AC]; + /* 0x0144 */ SkelAnime skelAnime; + /* 0x0188 */ Vec3s jointTable[30]; + /* 0x023C */ Vec3s morphtable[30]; /* 0x02F0 */ EnSshActionFunc actionFunc; - /* 0x02F4 */ char unk_2F4[0x2D8]; + /* 0x02F4 */ ColliderCylinder collider1[6]; + /* 0x04BC */ ColliderJntSph collider2; + /* 0x04DC */ ColliderJntSphElement collider2Elements[1]; + /* 0x051C */ s16 initialYaw; + /* 0x051E */ s16 maxTurnRate; + /* 0x0520 */ s16 unkTimer; + /* 0x0522 */ s16 spinTimer; + /* 0x0524 */ s16 hitTimer; + /* 0x0526 */ s16 invincibilityTimer; + /* 0x0528 */ s16 sfxTimer; + /* 0x052A */ s16 stunTimer; + /* 0x052C */ s16 animTimer; + /* 0x052E */ s16 swayTimer; + /* 0x0530 */ s32 blureIdx; + /* 0x0534 */ f32 colliderScale; + /* 0x0538 */ f32 floorHeightOffset; + /* 0x053C */ Vec3f ceilingPos; + /* 0x0548 */ UNK_TYPE1 unk_548[0x78]; + /* 0x05C0 */ s16 swayAngle; + /* 0x05C2 */ u16 stateFlags; + /* 0x05C4 */ u8 hitCount; + /* 0x05C6 */ s16 blinkState; + /* 0x05C8 */ s16 blinkTimer; } EnSsh; // size = 0x5CC extern const ActorInit En_Ssh_InitVars; diff --git a/src/overlays/actors/ovl_En_St/z_en_st.c b/src/overlays/actors/ovl_En_St/z_en_st.c index 6f92e8e76..9798a9e6d 100644 --- a/src/overlays/actors/ovl_En_St/z_en_st.c +++ b/src/overlays/actors/ovl_En_St/z_en_st.c @@ -1,10 +1,12 @@ /* * File: z_en_st.c * Overlay: ovl_En_St - * Description: Skulltula + * Description: Skulltula (large suspended one) */ #include "z_en_st.h" +#include "objects/object_st/object_st.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x01004035 @@ -19,8 +21,8 @@ void func_808A6C04(EnSt* this, GlobalContext* globalCtx); void func_808A6D84(EnSt* this, GlobalContext* globalCtx); void func_808A6E24(EnSt* this, GlobalContext* globalCtx); void func_808A701C(EnSt* this, GlobalContext* globalCtx); +void func_808A7478(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit En_St_InitVars = { ACTOR_EN_ST, ACTORCAT_ENEMY, @@ -33,39 +35,89 @@ const ActorInit En_St_InitVars = { (ActorFunc)NULL, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_808A75B0 = { - { COLTYPE_HIT2, AT_ON | AT_TYPE_ENEMY, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x00, 0x00 }, { 0x800C3829, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit1 = { + { + COLTYPE_HIT2, + AT_ON | AT_TYPE_ENEMY, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x00, 0x00 }, + { 0x800C3829, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 18, 48, -20, { 0, 0, 0 } }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_808A75DC = { - { COLTYPE_HIT2, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x77C3C7D6, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit2 = { + { + COLTYPE_HIT2, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x77C3C7D6, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 18, 48, -20, { 0, 0, 0 } }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_808A7608 = { - { COLTYPE_METAL, AT_NONE, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK2, { 0x00000000, 0x00, 0x00 }, { 0x77C3C7D6, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit3 = { + { + COLTYPE_METAL, + AT_NONE, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_NONE, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK2, + { 0x00000000, 0x00, 0x00 }, + { 0x77C3C7D6, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 18, 48, -20, { 0, 0, 0 } }, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_808A7634 = { - { COLTYPE_HIT2, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x800C3829, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit4 = { + { + COLTYPE_HIT2, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x800C3829, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 18, 48, -20, { 0, 0, 0 } }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_808A7660 = { 2, 0, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 2, 0, 0, 0, MASS_IMMOVABLE }; -// static DamageTable sDamageTable = { -static DamageTable D_808A766C = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x1), /* Deku Stick */ DMG_ENTRY(1, 0x0), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -100,73 +152,791 @@ static DamageTable D_808A766C = { /* Powder Keg */ DMG_ENTRY(1, 0x0), }; -#endif +static ActorAnimationEntryS sAnimations[] = { + { &object_st_Anim_000304, 1.0f, 0, -1, 0, 0 }, { &object_st_Anim_005B98, 1.0f, 0, -1, 2, -4 }, + { &object_st_Anim_000304, 4.0f, 0, -1, 2, -4 }, { &object_st_Anim_000304, 1.0f, 0, -1, 0, -4 }, + { &object_st_Anim_0055A8, 1.0f, 0, -1, 2, -4 }, { &object_st_Anim_000304, 8.0f, 0, -1, 0, -4 }, + { &object_st_Anim_000304, 6.0f, 0, -1, 2, -4 }, { &object_st_Anim_005B98, 2.0f, 0, -1, 0, -4 }, +}; -extern ColliderCylinderInit D_808A75B0; -extern ColliderCylinderInit D_808A75DC; -extern ColliderCylinderInit D_808A7608; -extern ColliderCylinderInit D_808A7634; -extern CollisionCheckInfoInit2 D_808A7660; -extern DamageTable D_808A766C; +void func_808A5050(EnSt* this, GlobalContext* globalCtx) { + static Color_RGBA8 D_808A770C = { 170, 130, 90, 255 }; + static Color_RGBA8 D_808A7710 = { 100, 60, 20, 0 }; + s32 i; + Vec3f spB8; + Vec3f spAC; + Vec3f spA0; + Vec3f sp94; + s32 rand; + s16 temp_s0 = (Rand_ZeroOne() - 0.5f) * 0x10000; -extern UNK_TYPE D_06005298; + spA0.y = this->actor.floorHeight; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A5050.s") + for (i = 0; i < 16; i++, temp_s0 += 0xFFF) { + rand = (Rand_ZeroOne() * 4.0f) + 8.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A52A8.s") + sp94.x = 0.0f; + sp94.y = (Rand_ZeroOne() * 0.2f) + 0.1f; + sp94.z = Rand_ZeroOne() + 1.0f; + Lib_Vec3f_TranslateAndRotateY(&gZeroVec3f, temp_s0, &sp94, &spAC); + sp94.x = 0.0f; + sp94.y = 1.0f; + sp94.z = 5.0f; + Lib_Vec3f_TranslateAndRotateY(&gZeroVec3f, temp_s0, &sp94, &spB8); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A54B0.s") + spA0.x = this->actor.world.pos.x + (2.0f * spB8.x); + spA0.z = this->actor.world.pos.z + (2.0f * spB8.z); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A576C.s") + func_800B0EB0(globalCtx, &spA0, &spB8, &spAC, &D_808A770C, &D_808A7710, 100, 40, rand); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A5988.s") + spA0.x = this->actor.world.pos.x; + spA0.z = this->actor.world.pos.z; + spA0.y = this->actor.floorHeight; + EffectSsBlast_SpawnWhiteCustomScale(globalCtx, &spA0, &gZeroVec3f, &gZeroVec3f, 100, 220, 8); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A5AF8.s") +void func_808A52A8(EnSt* this, GlobalContext* globalCtx) { + static Color_RGBA8 D_808A7714 = { 170, 130, 90, 255 }; + static Color_RGBA8 D_808A7718 = { 100, 60, 20, 0 }; + s32 pad; + Vec3f spB8; + Vec3f spAC; + Vec3f spA0; + Vec3f sp94; + s32 i; + s16 temp_s0 = (Rand_ZeroOne() - 0.5f) * 0x10000; + s32 rand; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A5BEC.s") + spA0.y = this->actor.floorHeight; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A5CCC.s") + for (i = 0; i < 8; i++, temp_s0 += 0x1FFE) { + rand = (Rand_ZeroOne() * 4.0f) + 8.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A5D7C.s") + sp94.x = 0.0f; + sp94.y = (Rand_ZeroOne() * 0.2f) + 0.1f; + sp94.z = Rand_ZeroOne() + 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A5DCC.s") + Lib_Vec3f_TranslateAndRotateY(&gZeroVec3f, temp_s0, &sp94, &spAC); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A5F28.s") + sp94.x = 0.0f; + sp94.y = 1.0f; + sp94.z = 4.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A6064.s") + Lib_Vec3f_TranslateAndRotateY(&gZeroVec3f, temp_s0, &sp94, &spB8); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A60E0.s") + spA0.x = this->actor.world.pos.x + (2.0f * spB8.x); + spA0.z = this->actor.world.pos.z + (2.0f * spB8.z); + func_800B0EB0(globalCtx, &spA0, &spB8, &spAC, &D_808A7714, &D_808A7718, 100, 40, rand); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A61F4.s") +void func_808A54B0(EnSt* this, GlobalContext* globalCtx) { + s32 pad; + f32 temp_f0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A6220.s") + if ((this->unk_18C & 1) && (this->actor.colChkInfo.health != 0)) { + OPEN_DISPS(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A63E8.s") + gSegments[6] = PHYSICAL_TO_VIRTUAL2(globalCtx->objectCtx.status[this->unk_2C0].segment); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A6468.s") + gSPSegment(POLY_XLU_DISP++, 0x06, globalCtx->objectCtx.status[this->unk_2C0].segment); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A650C.s") + func_8012C2DC(globalCtx->state.gfxCtx); + Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, + MTXMODE_NEW); + Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Scale(0.06f, 0.12f, 0.06f, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A6580.s") + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 195, 0, 0x40, 0x20, 1, 215, 0, 8, 8)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A6A3C.s") + temp_f0 = (f32)this->unk_310 / 8; + if (temp_f0 > 1.0f) { + temp_f0 = 1.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A6A78.s") + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 170, 255, 255, (u8)(255 * temp_f0)); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_025850); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_025970); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A6C04.s") + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A6D84.s") +s32 func_808A576C(EnSt* this) { + s32 i; + s16 phi_s2 = (s16)((s16)(Rand_ZeroOne() * 1000.0f) % 12) * 0x1555; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A6E24.s") + for (i = 0; i < ARRAY_COUNT(this->unk_31C); i++, phi_s2 += 0x1555) { + if (this->unk_18E != 10) { + this->unk_31C[i] = (Rand_ZeroOne() * 16.0f) + 8.0f; + } else { + this->unk_31C[i] = 80; + } + this->unk_334[i] = this->unk_31C[i]; + this->unk_2DC[i] = 0.90000004f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A701C.s") + if ((this->unk_18E == 0) || (this->unk_18E == 1)) { + this->unk_358[i].y = ((Rand_ZeroOne() - 0.5f) * 40.0f) - 10.0f; + } else { + this->unk_358[i].y = ((Rand_ZeroOne() - 0.5f) * 30.0f) + 10.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/EnSt_Init.s") + this->unk_358[i].x = Math_SinS(phi_s2) * 18.0f; + this->unk_358[i].z = Math_CosS(phi_s2) * 18.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/EnSt_Destroy.s") + this->unk_31A = 1; + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/EnSt_Update.s") +s32 func_808A5988(EnSt* this, GlobalContext* globalCtx, s32 arg2) { + s32 ret = false; + u8 sp53; + Vec3f sp44; + f32 sp40; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A73E8.s") + if (arg2 < this->unk_31A) { + if (this->unk_31C[arg2] != 0) { + sp40 = (f32)this->unk_31C[arg2] / this->unk_334[arg2]; + sp53 = this->unk_18E; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_St/func_808A7478.s") + Math_ApproachF(&this->unk_2DC[arg2], 0.6f, 0.3f, 0.5f); + Math_Vec3f_Copy(&sp44, &this->actor.world.pos); + + sp44.x += this->unk_358[arg2].x; + sp44.y += this->unk_358[arg2].y; + sp44.z += this->unk_358[arg2].z; + + if (sp53 == 10) { + if ((this->unk_334[arg2] - this->unk_31C[arg2]) < 20) { + sp53 = 11; + } + sp40 = 1.0f; + } + func_800BE680(globalCtx, &this->actor, &sp44, 1, 0.6f, this->unk_2DC[arg2], sp40, sp53); + ret = true; + } + } + return ret; +} + +void func_808A5AF8(EnSt* this, GlobalContext* globalCtx) { + Vec3f sp54; + s32 i; + + for (i = 0; i < ARRAY_COUNT(this->unk_358); i++) { + Math_Vec3f_Copy(&sp54, &this->actor.world.pos); + sp54.x += this->unk_358[i].x; + sp54.y += this->unk_358[i].y; + sp54.z += this->unk_358[i].z; + Math_Vec3f_Copy(&this->unk_358[i], &sp54); + } + func_800BF7CC(globalCtx, &this->actor, this->unk_358, 12, 3, 0.1f, 0.3f); +} + +s16 func_808A5BEC(EnSt* this) { + s16 ret; + + if (!(this->unk_18C & 4) || (this->actor.xzDistToPlayer > 180.0f)) { + ret = this->actor.home.rot.y; + } else { + ret = this->actor.yawTowardsPlayer; + if (DECR(this->unk_30E) == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALTU_ROLL); + this->unk_18C ^= 2; + this->unk_310 = 8; + if (this->unk_18C & 1) { + this->unk_310 *= 2; + } + this->unk_30E = 30; + } + + if (this->unk_18C & 2) { + ret = BINANG_ROT180(ret); + } + } + + return ret; +} + +void func_808A5CCC(EnSt* this) { + if (this->unk_310 != 0) { + this->unk_310--; + } + + if (this->unk_310 < 8) { + Math_ApproachS(&this->actor.world.rot.y, func_808A5BEC(this), 3, 0x1FFE); + } else { + this->actor.world.rot.y += 0x2AA8; + } + this->actor.shape.rot.y = this->actor.world.rot.y; + + if (DECR(this->unk_310) == 0) { + this->unk_18C &= ~1; + } +} + +void func_808A5D7C(EnSt* this) { + if (this->unk_2C8 > 0.0f) { + this->actor.world.pos.y = this->actor.home.pos.y - 10.0f; + } else { + this->actor.world.pos.y = this->actor.floorHeight + 20.0f; + } +} + +void func_808A5DCC(EnSt* this, Color_RGB8* colour) { + if (this->unk_2D8 == 0.0f) { + Math_SmoothStepToF(&this->unk_34C, 0.0f, 0.3f, 1000.0f, 0.0f); + } else { + this->unk_34C += this->unk_2D8; + if (this->unk_34C >= 255.0f) { + this->unk_34C = 255.0f; + this->unk_2D8 *= -1.0f; + } + + if (this->unk_34C <= 0.0f) { + this->unk_34C = 0.0f; + this->unk_2D8 *= -1.0f; + } + } + + colour->r = this->unk_34C; + colour->g = 0; + colour->b = 0; +} + +s32 func_808A5F28(EnSt* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 ret = false; + + if (Player_GetMask(globalCtx) == PLAYER_MASK_STONE) { + if (this->unk_2C8 <= 0.0f) { + return false; + } + return true; + } + + if ((((this->unk_2C8 > 0.0f) && (this->actor.world.pos.y < player->actor.world.pos.y)) || + ((this->unk_2C8 > 0.0f) && (this->actor.xzDistToPlayer > 180.0f)) || + ((this->unk_2C8 < 0.0f) && (player->actor.world.pos.y <= this->actor.world.pos.y) && + (this->actor.floorHeight <= player->actor.world.pos.y) && (this->actor.xzDistToPlayer < 120.0f))) && + !(this->unk_18C & 8)) { + ret = true; + } + + return ret; +} + +s32 func_808A6064(EnSt* this) { + s32 ret = false; + + if (this->unk_2C8 > 0.0f) { + if ((this->actor.home.pos.y - 10.0f) < this->actor.world.pos.y) { + ret = true; + } + } else if (this->actor.world.pos.y < (this->actor.floorHeight + 20.0f)) { + ret = true; + } + return ret; +} + +void func_808A60E0(EnSt* this) { + s32 idx = (this->unk_2C8 > 0.0f) ? 2 : 6; + f32 sp20 = (this->unk_2C8 > 0.0f) ? 4.0f : 9.0f; + f32 sp1C; + u16 sfxId = (this->unk_2C8 < 0.0f) ? NA_SE_EN_STALTU_DOWN : NA_SE_EN_STALTU_UP; + + sp1C = this->skelAnime.curFrame / (this->skelAnime.animLength - 1.0f); + + if (sp1C == 1.0f) { + func_8013BC6C(&this->skelAnime, sAnimations, idx); + Audio_PlayActorSound2(&this->actor, sfxId); + } + + this->unk_2D4 = (1.0f - sp1C) * sp20 * this->unk_2C8; + + if (this->unk_2C8 < 0.0f) { + this->unk_2D4 = this->unk_2C8 * sp20; + } +} + +s32 func_808A61F4(EnSt* this) { + if (this->actor.colChkInfo.damage < this->actor.colChkInfo.health) { + this->actor.colChkInfo.health -= this->actor.colChkInfo.damage; + } else { + this->actor.colChkInfo.health = 0; + } + return this->actor.colChkInfo.health; +} + +void func_808A6220(EnSt* this, GlobalContext* globalCtx) { + s32 pad; + + if ((DECR(this->unk_314) == 0) && (this->actor.colChkInfo.health != 0)) { + Collider_UpdateCylinder(&this->actor, &this->collider2); + Collider_UpdateCylinder(&this->actor, &this->collider3); + Collider_UpdateCylinder(&this->actor, &this->collider4); + if ((s16)ABS_ALT(BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y)) < 0x4E00) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider3.base); + } else { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider2.base); + } + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider4.base); + } + + if (this->actor.colChkInfo.health != 0) { + Collider_UpdateCylinder(&this->actor, &this->collider1); + if (((this->unk_2C8 < 0.0f) && (this->unk_18C & 0x10)) || (this->unk_18C & 1)) { + this->collider1.dim.yShift = -40; + this->collider1.dim.radius = 56; + this->collider1.dim.height = 80; + } else { + this->collider1.dim.yShift = -20; + this->collider1.dim.radius = 18; + this->collider1.dim.height = 48; + } + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider1.base); + } +} + +void func_808A63E8(EnSt* this) { + func_8013BC6C(&this->skelAnime, sAnimations, 3); + this->unk_2C8 = 1.0f; + func_808A5D7C(this); + this->unk_30C = 0; + this->unk_18C &= ~0x10; + this->unk_2C8 = -1.0f; + this->unk_2D4 = 0.0f; + this->unk_2CC = 0.0f; + this->unk_2C4 = 1.0f; +} + +void func_808A6468(EnSt* this, GlobalContext* globalCtx) { + func_808A5050(this, globalCtx); + func_8013BC6C(&this->skelAnime, sAnimations, 4); + this->unk_18C |= (0x8 | 0x4); + this->unk_18C &= ~(0x10 | 0x2); + this->unk_2C8 = -1.0f; + func_808A5D7C(this); + this->unk_30E = 30; + this->unk_30C = 0; + this->unk_2C8 = 1.0f; + this->unk_2D8 = 30.0f; + this->unk_2D4 = 0.0f; + this->unk_2CC = 0.0f; + this->unk_2C4 = 6.0f; +} + +void func_808A650C(EnSt* this) { + s32 idx = (this->unk_2C8 > 0.0f) ? 2 : 6; + + func_8013BC6C(&this->skelAnime, sAnimations, idx); + this->unk_2CC = 0.0f; + this->unk_2D4 = 0.0f; + this->unk_2D8 = 0.0f; + this->unk_18C &= ~4; + this->unk_18C |= 0x10; +} + +s32 func_808A6580(EnSt* this, GlobalContext* globalCtx) { + Player* sp3C = GET_PLAYER(globalCtx); + s32 ret = false; + s32 i; + + if (this->unk_316 != 0) { + this->unk_316--; + } + + if (this->collider3.base.acFlags & AC_HIT) { + if (this->unk_18E == 10) { + // clang-format off + for (i = 0; i < ARRAY_COUNT(this->unk_31C); i++) { this->unk_31C[i] = 0; } + // clang-format on + + this->unk_318 = 0; + } + + if (this->actor.colChkInfo.damageEffect == 4) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, CLEAR_TAG_LARGE_LIGHT_RAYS); + } + this->collider3.base.acFlags &= ~AC_HIT; + } + + if ((this->collider2.base.acFlags & AC_HIT) || (this->collider4.base.acFlags & AC_HIT)) { + this->collider2.base.acFlags &= ~AC_HIT; + this->collider4.base.acFlags &= ~AC_HIT; + if (this->actor.colChkInfo.damageEffect == 4) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_CLEAR_TAG, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, CLEAR_TAG_LARGE_LIGHT_RAYS); + } + + if (this->unk_18E == 10) { + // clang-format off + for (i = 0; i < ARRAY_COUNT(this->unk_31C); i++) { this->unk_31C[i] = 0; } + // clang-format on + + this->unk_318 = 0; + } else if (func_808A61F4(this)) { + switch (this->actor.colChkInfo.damageEffect) { + case 1: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_COMMON_FREEZE); + this->unk_312 = 40; + func_800BCB70(&this->actor, 0, 200, 0, this->unk_312); + break; + + case 5: + this->unk_18E = 30; + this->unk_312 = 40; + func_808A576C(this); + func_800BCB70(&this->actor, 0, 200, 0, this->unk_312); + break; + + default: + Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALTU_DAMAGE); + this->unk_314 = 20; + this->unk_312 = 0; + func_800BCB70(&this->actor, 0x4000, 200, 0, this->unk_314); + func_8013BC6C(&this->skelAnime, sAnimations, 1); + this->unk_18C |= 8; + this->actionFunc = func_808A6D84; + this->unk_2C8 = -1.0f; + break; + } + } else { + if (ENST_GET_3F(&this->actor) != ENST_3F_63) { + Actor_SetSwitchFlag(globalCtx, ENST_GET_3F(&this->actor)); + } + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EN_STALTU_DEAD); + Enemy_StartFinishingBlow(globalCtx, &this->actor); + + this->actor.flags &= ~1; + + switch (this->actor.colChkInfo.damageEffect) { + case 4: + this->unk_18E = 20; + this->unk_318 = 20; + func_808A576C(this); + break; + + case 3: + this->unk_18E = 10; + this->unk_318 = 0; + func_808A576C(this); + break; + + case 2: + this->unk_18E = 0; + this->unk_318 = 20; + func_808A576C(this); + break; + + default: + this->unk_18E = 1; + this->unk_318 = 0; + break; + } + + if (this->unk_18E != 10) { + func_8013BC6C(&this->skelAnime, sAnimations, 7); + this->unk_2CC = 0.0f; + this->unk_2D4 = 0.0f; + this->actor.gravity = -1.0f; + } + this->unk_314 = 20; + this->unk_312 = 0; + func_800BCB70(&this->actor, 0x4000, 200, 0, this->unk_314); + ret = true; + } + this->unk_310 = 0; + this->unk_18C &= ~1; + } + + if ((this->collider1.base.ocFlags2 & OC2_HIT_PLAYER) || (this->collider1.base.atFlags & AT_HIT)) { + if ((this->unk_316 == 0) && (this->unk_314 == 0) && (this->unk_312 == 0) && + !(this->collider1.base.atFlags & AT_BOUNCED) && (this->actor.colChkInfo.health != 0)) { + globalCtx->damagePlayer(globalCtx, -8); + Audio_PlayActorSound2(&sp3C->actor, NA_SE_PL_BODY_HIT); + func_800B8D98(globalCtx, &this->actor, 4.0f, this->actor.yawTowardsPlayer, 6.0f); + this->unk_316 = 10; + this->unk_18C |= 1; + this->unk_30E = 0; + } + this->collider1.base.ocFlags1 &= ~OC1_HIT; + this->collider1.base.atFlags &= ~AT_HIT; + } + return ret; +} + +s32 func_808A6A3C(EnSt* this) { + s32 ret = false; + + if ((ENST_GET_1C0(&this->actor) == ENST_1C0_1) && (this->actor.colChkInfo.health != 0)) { + ret = true; + } + return ret; +} + +void func_808A6A78(EnSt* this, GlobalContext* globalCtx) { + s32 pad[2]; + + if (Object_IsLoaded(&globalCtx->objectCtx, this->unk_2C0)) { + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 8.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &object_st_Skel_005298, NULL, this->jointTable, this->morphTable, + 30); + func_8013BC6C(&this->skelAnime, sAnimations, 0); + + Collider_InitAndSetCylinder(globalCtx, &this->collider1, &this->actor, &sCylinderInit1); + Collider_InitAndSetCylinder(globalCtx, &this->collider2, &this->actor, &sCylinderInit2); + Collider_InitAndSetCylinder(globalCtx, &this->collider3, &this->actor, &sCylinderInit3); + Collider_InitAndSetCylinder(globalCtx, &this->collider4, &this->actor, &sCylinderInit4); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + + if (ENST_GET_1C0(&this->actor) == ENST_1C0_1) { + this->actor.flags |= 0x80; + } + + Actor_SetScale(&this->actor, 0.04f); + this->actor.draw = func_808A7478; + this->actor.hintId = 4; + this->actor.gravity = 0.0f; + func_808A63E8(this); + this->unk_18C = 0; + this->unk_18C &= ~0x10; + this->actionFunc = func_808A6C04; + } +} + +void func_808A6C04(EnSt* this, GlobalContext* globalCtx) { + this->unk_2CC = Math_SinS(this->unk_30C) * this->unk_2C4; + this->unk_30C += 0xE00; + Math_ApproachF(&this->unk_2C4, 1.0f, 0.1f, 0.3f); + this->actor.velocity.y = this->unk_2D4 + this->unk_2CC; + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + + if ((this->unk_18C & 8) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + func_8013BC6C(&this->skelAnime, sAnimations, 3); + this->unk_18C &= ~8; + } else if ((this->unk_310 == 0) && func_808A5F28(this, globalCtx) && !func_808A6064(this)) { + func_808A650C(this); + this->actionFunc = func_808A6D84; + } else { + if ((this->unk_316 == 0) && (this->unk_314 == 0) && (this->unk_312 == 0) && (this->unk_2C8 > 0.0f) && + (this->actor.xzDistToPlayer < 62.0f)) { + this->unk_30E = 0; + this->unk_18C |= 1; + } + func_808A5CCC(this); + } +} + +void func_808A6D84(EnSt* this, GlobalContext* globalCtx) { + func_808A60E0(this); + this->actor.velocity.y = this->unk_2D4 + this->unk_2CC; + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + if (func_808A6064(this)) { + if (this->unk_2C8 < 0.0f) { + func_808A6468(this, globalCtx); + } else { + func_808A63E8(this); + } + this->actionFunc = func_808A6C04; + } + func_808A5CCC(this); +} + +void func_808A6E24(EnSt* this, GlobalContext* globalCtx) { + s32 i; + s32 count = 0; + + if (this->unk_18E == 10) { + for (i = 0; i < ARRAY_COUNT(this->unk_31C); i++) { + if (DECR(this->unk_31C[i]) == 0) { + count++; + } + } + + if (count == ARRAY_COUNT(this->unk_31C)) { + func_8013BC6C(&this->skelAnime, sAnimations, 7); + this->unk_18E = 1; + this->unk_2CC = 0.0f; + this->unk_2D4 = 0.0f; + this->actor.gravity = -1.0f; + func_808A5AF8(this, globalCtx); + } + } else if (this->unk_18C & 0x80) { + this->actionFunc = func_808A701C; + this->actor.gravity = 0.0f; + this->unk_2CC = 0.0f; + this->unk_2D4 = 0.0f; + } else { + if (this->actor.bgCheckFlags & 1) { + this->actor.shape.yOffset = 400.0f; + this->actor.world.rot.x = 0x4000; + this->actor.shape.rot.x = this->actor.world.rot.x; + this->unk_2D0 = this->actor.velocity.y = fabsf(this->actor.velocity.y) * 0.6f; + this->actor.speedXZ = 0.0f; + + if ((s32)this->unk_2D0 != 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_EYEGOLE_ATTACK); + } else { + this->actor.velocity.y = 0.0f; + this->actionFunc = func_808A701C; + } + + if ((s32)this->actor.velocity.y >= 2) { + func_808A52A8(this, globalCtx); + } + } else { + Math_ApproachF(&this->actor.shape.yOffset, 400.0f, 0.3f, 1000.0f); + this->actor.world.rot.x += 0x1000; + if (this->actor.world.rot.x >= 0x4000) { + this->actor.world.rot.x = 0x4000; + } + this->actor.shape.rot.x = this->actor.world.rot.x; + } + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + } +} + +void func_808A701C(EnSt* this, GlobalContext* globalCtx) { + s32 i; + s32 count = 0; + + if (this->unk_18C & 0x40) { + if (DECR(this->unk_318) == 0) { + this->unk_18C |= 0x20; + } + + for (i = 0; i < ARRAY_COUNT(this->unk_31C); i++) { + if (DECR(this->unk_31C[i]) == 0) { + count++; + } + } + + if (count == ARRAY_COUNT(this->unk_31C)) { + Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.world.pos, 0); + Actor_MarkForDeath(&this->actor); + } + } else if (DECR(this->unk_318) == 0) { + this->unk_18C |= 0x40; + if (this->unk_18E == 1) { + func_808A576C(this); + this->unk_318 = 10; + } + } +} + +void EnSt_Init(Actor* thisx, GlobalContext* globalCtx) { + EnSt* this = THIS; + + this->unk_2C0 = Object_GetIndex(&globalCtx->objectCtx, GAMEPLAY_KEEP); + if (((ENST_GET_3F(&this->actor) != ENST_3F_63) && Flags_GetSwitch(globalCtx, ENST_GET_3F(&this->actor))) || + (this->unk_2C0 < 0)) { + Actor_MarkForDeath(&this->actor); + } else { + this->actionFunc = func_808A6A78; + } +} + +void EnSt_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnSt* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider1); + Collider_DestroyCylinder(globalCtx, &this->collider2); + Collider_DestroyCylinder(globalCtx, &this->collider3); + Collider_DestroyCylinder(globalCtx, &this->collider4); +} + +void EnSt_Update(Actor* thisx, GlobalContext* globalCtx) { + EnSt* this = THIS; + + if (this->actor.flags & 0x8000) { + SkelAnime_Update(&this->skelAnime); + this->unk_18C |= 0x80; + return; + } + + if (!(this->actor.flags & 0x80) && func_808A6A3C(this)) { + this->actor.flags |= 0x80; + } + + if (func_808A6580(this, globalCtx)) { + this->actionFunc = func_808A6E24; + } else if (DECR(this->unk_312) == 0) { + this->actionFunc(this, globalCtx); + if (this->unk_18E != 10) { + SkelAnime_Update(&this->skelAnime); + } + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 12.0f, 0.0f, 5); + } else if (this->unk_312 < 20) { + s16 idx = (this->unk_312 % 2) ? -1 : 1; + + idx *= 0x800; + idx += this->actor.world.rot.y; + this->actor.shape.rot.y = idx; + + if (this->unk_18E == 30) { + if (this->unk_312 == 1) { + s32 i; + + // clang-format off + for (i = 0; i < ARRAY_COUNT(this->unk_31C); i++) { this->unk_31C[i] = 0; } + // clang-format on + } + } + } + + Actor_SetHeight(&this->actor, 0.0f); + func_808A6220(this, globalCtx); +} + +s32 EnSt_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx, + Gfx** gfx) { + EnSt* this = THIS; + Color_RGB8 sp20; + + if (limbIndex == 4) { + func_808A5DCC(this, &sp20); + + gDPPipeSync((*gfx)++); + gDPSetEnvColor((*gfx)++, sp20.r, sp20.g, sp20.b, 0); + } + return false; +} + +void func_808A7478(Actor* thisx, GlobalContext* globalCtx) { + EnSt* this = THIS; + s32 i; + s32 count; + + if (!(this->unk_18C & 0x20)) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (func_808A6A3C(this)) { + func_8012C2DC(globalCtx->state.gfxCtx); + POLY_XLU_DISP = SkelAnime_Draw(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + EnSt_OverrideLimbDraw, NULL, &this->actor, POLY_XLU_DISP); + } else { + func_8012C28C(globalCtx->state.gfxCtx); + POLY_OPA_DISP = SkelAnime_Draw(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + EnSt_OverrideLimbDraw, NULL, &this->actor, POLY_OPA_DISP); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + + for (i = 0, count = 0; i < ARRAY_COUNT(this->unk_31C); i++) { + count += func_808A5988(this, globalCtx, i); + } + + if (count != 0) { + this->unk_31A += 2; + } + + func_808A54B0(this, globalCtx); +} diff --git a/src/overlays/actors/ovl_En_St/z_en_st.h b/src/overlays/actors/ovl_En_St/z_en_st.h index 0ad88efef..a82ff397b 100644 --- a/src/overlays/actors/ovl_En_St/z_en_st.h +++ b/src/overlays/actors/ovl_En_St/z_en_st.h @@ -7,11 +7,45 @@ struct EnSt; typedef void (*EnStActionFunc)(struct EnSt*, GlobalContext*); +#define ENST_GET_3F(thisx) (((thisx)->params & 0x3F) & 0xFF) +#define ENST_GET_1C0(thisx) ((((thisx)->params & 0x1C0) >> 6) & 0xFF) + +#define ENST_3F_63 63 +#define ENST_1C0_1 1 + typedef struct EnSt { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; - /* 0x0188 */ EnStActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x3C4]; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ EnStActionFunc actionFunc; + /* 0x18C */ u16 unk_18C; + /* 0x18E */ u8 unk_18E; + /* 0x190 */ ColliderCylinder collider1; + /* 0x1DC */ ColliderCylinder collider2; + /* 0x228 */ ColliderCylinder collider3; + /* 0x274 */ ColliderCylinder collider4; + /* 0x2C0 */ s8 unk_2C0; + /* 0x2C4 */ f32 unk_2C4; + /* 0x2C8 */ f32 unk_2C8; + /* 0x2CC */ f32 unk_2CC; + /* 0x2D0 */ f32 unk_2D0; + /* 0x2D4 */ f32 unk_2D4; + /* 0x2D8 */ f32 unk_2D8; + /* 0x2DC */ f32 unk_2DC[12]; + /* 0x30C */ s16 unk_30C; + /* 0x30E */ s16 unk_30E; + /* 0x310 */ s16 unk_310; + /* 0x312 */ s16 unk_312; + /* 0x314 */ s16 unk_314; + /* 0x316 */ s16 unk_316; + /* 0x318 */ s16 unk_318; + /* 0x31A */ s16 unk_31A; + /* 0x31C */ s16 unk_31C[12]; + /* 0x334 */ s16 unk_334[12]; + /* 0x34C */ f32 unk_34C; + /* 0x350 */ UNK_TYPE1 unk_350[0x8]; + /* 0x358 */ Vec3f unk_358[12]; + /* 0x3E8 */ Vec3s jointTable[30]; + /* 0x49C */ Vec3s morphTable[30]; } EnSt; // size = 0x550 extern const ActorInit En_St_InitVars; diff --git a/src/overlays/actors/ovl_En_Sth2/z_en_sth2.c b/src/overlays/actors/ovl_En_Sth2/z_en_sth2.c index 42bfe2363..97b463567 100644 --- a/src/overlays/actors/ovl_En_Sth2/z_en_sth2.c +++ b/src/overlays/actors/ovl_En_Sth2/z_en_sth2.c @@ -1,7 +1,7 @@ /* * File: z_en_sth2.c * Overlay: ovl_En_Sth2 - * Description: + * Description: Guy waving at the telescope in Termina Field */ #include "z_en_sth2.h" diff --git a/src/overlays/actors/ovl_En_Stream/z_en_stream.c b/src/overlays/actors/ovl_En_Stream/z_en_stream.c index 8e72ac31c..9ce7ac906 100644 --- a/src/overlays/actors/ovl_En_Stream/z_en_stream.c +++ b/src/overlays/actors/ovl_En_Stream/z_en_stream.c @@ -1,10 +1,11 @@ /* * File: z_en_stream.c * Overlay: ovl_En_Stream - * Description: + * Description: Unused water vortex from OoT */ #include "z_en_stream.h" +#include "objects/object_stream/object_stream.h" #define FLAGS 0x00000010 @@ -15,9 +16,8 @@ void EnStream_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnStream_Update(Actor* thisx, GlobalContext* globalCtx); void EnStream_Draw(Actor* thisx, GlobalContext* globalCtx); -void EnStream_SetupAction(EnStream* this, EnStreamActionFunc actionFunc); +void EnStream_WaitForPlayer(EnStream* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Stream_InitVars = { ACTOR_EN_STREAM, ACTORCAT_BG, @@ -30,29 +30,120 @@ const ActorInit En_Stream_InitVars = { (ActorFunc)EnStream_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80965B20[] = { +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 20, ICHAIN_STOP), }; -#endif +void EnStream_SetupAction(EnStream* this, EnStreamActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -extern InitChainEntry D_80965B20[]; +void EnStream_Init(Actor* thisx, GlobalContext* globalCtx) { + EnStream* this = THIS; -extern UNK_TYPE D_06000950; + this->size = EN_STREAM_SIZE(&this->actor); + Actor_ProcessInitChain(&this->actor, sInitChain); + if (this->size != EN_STREAM_SIZE_NORMAL && this->size == EN_STREAM_SIZE_SMALL) { + this->actor.scale.y = 0.01f; + } + EnStream_SetupAction(this, EnStream_WaitForPlayer); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stream/EnStream_SetupAction.s") +void EnStream_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stream/EnStream_Init.s") +s32 EnStream_PlayerIsInRange(Vec3f* vortexWorldPos, Vec3f* playerWorldPos, Vec3f* posDifference, f32 vortexYScale) { + s32 ret = EN_STREAM_PLAYER_OUTSIDE_RANGE; + f32 smallConstant = 28.0f; + f32 upperBounds = 160 * vortexYScale * 50.0f; + f32 lowerBounds = 0 * vortexYScale * 50.0f; + f32 xzDist; + f32 range; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stream/EnStream_Destroy.s") + posDifference->x = playerWorldPos->x - vortexWorldPos->x; + posDifference->y = playerWorldPos->y - vortexWorldPos->y; + posDifference->z = playerWorldPos->z - vortexWorldPos->z; + xzDist = sqrtf(SQ(posDifference->x) + SQ(posDifference->z)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stream/func_809656D4.s") + if (lowerBounds <= posDifference->y && posDifference->y <= upperBounds) { + posDifference->y -= lowerBounds; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stream/func_809657F4.s") + range = ((75.0f - smallConstant) * (posDifference->y / (upperBounds - lowerBounds))) + 28.0f; + if (xzDist <= range) { + ret = EN_STREAM_PLAYER_WITHIN_RANGE_INSIDE_VORTEX; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stream/func_8096597C.s") + if (posDifference->y <= lowerBounds && xzDist <= 28.0f) { + ret = EN_STREAM_PLAYER_WITHIN_RANGE_BELOW_VORTEX; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stream/EnStream_Update.s") + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Stream/EnStream_Draw.s") +void EnStream_SuckPlayer(EnStream* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 pad48; + Vec3f posDifference; + f32 xzDist; + f32 yDistWithOffset; + s32 pad30[2]; + + if (EnStream_PlayerIsInRange(&this->actor.world.pos, &player->actor.world.pos, &posDifference, + this->actor.scale.y) != EN_STREAM_PLAYER_OUTSIDE_RANGE) { + xzDist = sqrtf(SQ(posDifference.x) + SQ(posDifference.z)); + yDistWithOffset = player->actor.world.pos.y - (this->actor.world.pos.y - 90.0f); + player->unk_B84 = Math_Atan2S(-posDifference.x, -posDifference.z); + if (xzDist > 3.0f) { + Math_SmoothStepToF(&player->unk_B80, 3.0f, 0.5f, xzDist, 0.0f); + } else { + player->unk_B80 = 0.0f; + Math_SmoothStepToF(&player->actor.world.pos.x, this->actor.world.pos.x, 0.5f, 3.0f, 0.0f); + Math_SmoothStepToF(&player->actor.world.pos.z, this->actor.world.pos.z, 0.5f, 3.0f, 0.0f); + } + if (yDistWithOffset > 0.0f) { + Math_SmoothStepToF(&player->actor.velocity.y, -3.0f, 0.7f, yDistWithOffset, 0.0f); + if (posDifference.y < -70.0f) { + player->stateFlags2 |= 0x80000000; + } + } + } else { + EnStream_SetupAction(this, EnStream_WaitForPlayer); + } +} + +void EnStream_WaitForPlayer(EnStream* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 pad; + Vec3f temp; + + if (EnStream_PlayerIsInRange(&this->actor.world.pos, &player->actor.world.pos, &temp, this->actor.scale.y) != + EN_STREAM_PLAYER_OUTSIDE_RANGE) { + EnStream_SetupAction(this, EnStream_SuckPlayer); + } +} + +void EnStream_Update(Actor* thisx, GlobalContext* globalCtx) { + EnStream* this = THIS; + + this->actionFunc(this, globalCtx); + func_800B8FE8(&this->actor, NA_SE_EV_WHIRLPOOL - SFX_FLAG); +} + +void EnStream_Draw(Actor* thisx, GlobalContext* globalCtx) { + u32 multipliedFrames; + u32 frames = globalCtx->gameplayFrames; + Gfx* gfx; + + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + gfx = POLY_XLU_DISP; + gSPMatrix(&gfx[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + multipliedFrames = frames * 20; + gSPSegment(&gfx[1], 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, frames * 30, -multipliedFrames, 64, 64, 1, multipliedFrames, + -multipliedFrames, 64, 64)); + gSPDisplayList(&gfx[2], gWaterVortexDL); + POLY_XLU_DISP = &gfx[3]; + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Stream/z_en_stream.h b/src/overlays/actors/ovl_En_Stream/z_en_stream.h index 3166c4aa2..3948b70c9 100644 --- a/src/overlays/actors/ovl_En_Stream/z_en_stream.h +++ b/src/overlays/actors/ovl_En_Stream/z_en_stream.h @@ -3,14 +3,33 @@ #include "global.h" +/** + * Even in OoT, where this actor was used, every single instance of it had + * a params of 0x0000, so it's hard to know how they intended to use this. + * In the final game, only an EN_STREAM_SIZE of 1 does anything different. + */ +#define EN_STREAM_SIZE(thisx) ((thisx)->params & 0xFF) + +typedef enum { + /* 0 */ EN_STREAM_SIZE_NORMAL, + /* 1 */ EN_STREAM_SIZE_SMALL, +} EnStreamSize; + +typedef enum { + /* 0 */ EN_STREAM_PLAYER_OUTSIDE_RANGE, + /* 1 */ EN_STREAM_PLAYER_WITHIN_RANGE_INSIDE_VORTEX, + /* 2 */ EN_STREAM_PLAYER_WITHIN_RANGE_BELOW_VORTEX, +} EnStreamPlayerLocation; + struct EnStream; typedef void (*EnStreamActionFunc)(struct EnStream*, GlobalContext*); typedef struct EnStream { - /* 0x0000 */ Actor actor; - /* 0x0144 */ EnStreamActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x8]; + /* 0x000 */ Actor actor; + /* 0x144 */ EnStreamActionFunc actionFunc; + /* 0x148 */ s32 size; + /* 0x14C */ UNK_TYPE1 unk_14C[0x4]; } EnStream; // size = 0x150 extern const ActorInit En_Stream_InitVars; diff --git a/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c b/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c index 0e6b20f3d..7e4bbcc2d 100644 --- a/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c +++ b/src/overlays/actors/ovl_En_Suttari/z_en_suttari.c @@ -331,7 +331,7 @@ void func_80BAAB78(EnSuttari* this, GlobalContext* globalCtx) { case 0: if (gSaveContext.weekEventReg[0x51] & 1) { this->textId = 0x1455; - ((EnElf*)GET_PLAYER(globalCtx)->tatlActor)->unk264 |= 8; + ((EnElf*)GET_PLAYER(globalCtx)->tatlActor)->unk_264 |= 8; this->flags2 |= 1; } else { this->textId = 0x1450; @@ -353,7 +353,7 @@ void func_80BAAB78(EnSuttari* this, GlobalContext* globalCtx) { case 0x1453: this->flags1 |= 0x400; gSaveContext.weekEventReg[0x51] |= 1; - ((EnElf*)GET_PLAYER(globalCtx)->tatlActor)->unk264 |= 8; + ((EnElf*)GET_PLAYER(globalCtx)->tatlActor)->unk_264 |= 8; this->flags2 |= 1; this->textId = 0x1454; break; @@ -411,7 +411,7 @@ void func_80BAAFDC(EnSuttari* this, GlobalContext* globalCtx) { Matrix_MultiplyVector3fByState(&effectVelOffset, &effectVel); Matrix_StatePop(); if (this->unk3F0 == 0) { - EffectSsSolderSrchBall_Spawn(globalCtx, &effectPos, &effectVel, &D_801D15B0, 50, &this->unk3F0, 1); + EffectSsSolderSrchBall_Spawn(globalCtx, &effectPos, &effectVel, &gZeroVec3f, 50, &this->unk3F0, 1); } if (this->unk3F0 == 1) { play_sound(NA_SE_SY_FOUND); @@ -443,7 +443,7 @@ void func_80BAB1A0(EnSuttari* this, GlobalContext* globalCtx) { Matrix_MultiplyVector3fByState(&effectVelOffset, &effectVel); Matrix_StatePop(); if (this->unk3F0 == 0) { - EffectSsSolderSrchBall_Spawn(globalCtx, &effectPos, &effectVel, &D_801D15B0, 50, &this->unk3F0, 1); + EffectSsSolderSrchBall_Spawn(globalCtx, &effectPos, &effectVel, &gZeroVec3f, 50, &this->unk3F0, 1); } if (this->unk3F0 == 1) { play_sound(NA_SE_SY_FOUND); @@ -689,7 +689,7 @@ s32 func_80BABDD8(EnSuttari* this, GlobalContext* globalCtx, struct_80133038_arg if (this->unk428 == 10 || this->unk428 == 11 || this->unk428 == 2) { return 0; } - sp48 = (EnDoor*)func_8013BB7C(&this->actor, globalCtx, ACTORCAT_DOOR, ACTOR_EN_DOOR); + sp48 = (EnDoor*)SubS_FindNearestActor(&this->actor, globalCtx, ACTORCAT_DOOR, ACTOR_EN_DOOR); sp24 = D_80BAE8F8[unkStruct->unk0]; if ((sp48 != NULL) && (sp24 >= 0)) { this->unk404 = func_8013BB34(globalCtx, sp47, sp24); @@ -755,7 +755,7 @@ s32 func_80BABFD4(EnSuttari* this, GlobalContext* globalCtx) { func_8013AF00(sp7C, 3, this->unk404->count + 3); if (this->unk42C == 0) { - sp58 = D_801D15B0; + sp58 = gZeroVec3f; func_8013B6B0(this->unk404, &this->unk414, &this->unk424, this->unk41C, this->unk418, &this->unk420, sp7C, &sp58, this->unk42A); func_8013B878(globalCtx, this->unk404, this->unk420, &sp58); @@ -771,7 +771,7 @@ s32 func_80BABFD4(EnSuttari* this, GlobalContext* globalCtx) { sp50 = this->unk420; sp58 = this->actor.world.pos; } - this->unk408 = D_801D15B0; + this->unk408 = gZeroVec3f; if (func_8013B6B0(this->unk404, &this->unk414, &this->unk424, this->unk41C, this->unk418, &this->unk420, sp7C, &this->unk408, this->unk42A)) { this->unk430 = 1; @@ -1318,7 +1318,7 @@ void func_80BADA9C(EnSuttari* this, GlobalContext* globalCtx) { } this->flags1 &= ~0x400; if (this->flags2 & 1) { - ((EnElf*)GET_PLAYER(globalCtx)->tatlActor)->unk264 |= 0x10; + ((EnElf*)GET_PLAYER(globalCtx)->tatlActor)->unk_264 |= 0x10; this->flags2 &= ~1; } globalCtx->msgCtx.unk11F22 = 0x43; diff --git a/src/overlays/actors/ovl_En_Sw/z_en_sw.c b/src/overlays/actors/ovl_En_Sw/z_en_sw.c index 221de8501..204d251d1 100644 --- a/src/overlays/actors/ovl_En_Sw/z_en_sw.c +++ b/src/overlays/actors/ovl_En_Sw/z_en_sw.c @@ -174,11 +174,11 @@ void func_808D8940(EnSw* this, GlobalContext* globalCtx) { sp94.x = 0.0f; sp94.y = (Rand_ZeroOne() * 0.2f) + 0.1f; sp94.z = Rand_ZeroOne() + 1.0f; - Lib_Vec3f_TranslateAndRotateY(&D_801D15B0, temp_s0, &sp94, &spAC); + Lib_Vec3f_TranslateAndRotateY(&gZeroVec3f, temp_s0, &sp94, &spAC); sp94.x = 0.0f; sp94.y = 0.7f; sp94.z = 2.0f; - Lib_Vec3f_TranslateAndRotateY(&D_801D15B0, temp_s0, &sp94, &spB8); + Lib_Vec3f_TranslateAndRotateY(&gZeroVec3f, temp_s0, &sp94, &spB8); spA0.x = this->actor.world.pos.x + (2.0f * spB8.x); spA0.z = this->actor.world.pos.z + (2.0f * spB8.z); func_800B0EB0(globalCtx, &spA0, &spB8, &spAC, &D_808DBAA4, &D_808DBAA8, 60, 30, temp_f4); @@ -1148,7 +1148,7 @@ void func_808DB2E0(EnSw* this, GlobalContext* globalCtx) { Audio_PlayActorSound2(&this->actor, NA_SE_EN_STALTURA_BOUND); } else { func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, 5); - Math_Vec3f_Copy(&this->actor.velocity, &D_801D15B0); + Math_Vec3f_Copy(&this->actor.velocity, &gZeroVec3f); this->unk_410 &= ~(0x10 | 0x1); this->actionFunc = func_808DB100; } diff --git a/src/overlays/actors/ovl_En_Sw/z_en_sw.h b/src/overlays/actors/ovl_En_Sw/z_en_sw.h index 975e4e36d..4c30b4965 100644 --- a/src/overlays/actors/ovl_En_Sw/z_en_sw.h +++ b/src/overlays/actors/ovl_En_Sw/z_en_sw.h @@ -43,7 +43,7 @@ typedef struct EnSw { /* 0x047C */ s16 unk_47C[12]; /* 0x0494 */ s16 unk_494; /* 0x0496 */ s16 unk_496; - /* 0x0468 */ s16 unk_498; + /* 0x0498 */ s16 unk_498; /* 0x049C */ s32 unk_49C; /* 0x04A0 */ s32 unk_4A0; } EnSw; // size = 0x4A4 diff --git a/src/overlays/actors/ovl_En_Talk/z_en_talk.c b/src/overlays/actors/ovl_En_Talk/z_en_talk.c index 2d054f808..d85e293dc 100644 --- a/src/overlays/actors/ovl_En_Talk/z_en_talk.c +++ b/src/overlays/actors/ovl_En_Talk/z_en_talk.c @@ -13,11 +13,9 @@ void EnTalk_Init(Actor* thisx, GlobalContext* globalCtx); void EnTalk_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnTalk_Update(Actor* thisx, GlobalContext* globalCtx); - void func_80BDE058(EnTalk* this, GlobalContext* globalCtx); void func_80BDE090(EnTalk* this, GlobalContext* globalCtx); -#if 0 const ActorInit En_Talk_InitVars = { ACTOR_EN_TALK, ACTORCAT_ITEMACTION, @@ -30,14 +28,42 @@ const ActorInit En_Talk_InitVars = { (ActorFunc)NULL, }; -#endif +void EnTalk_Init(Actor* thisx, GlobalContext* globalCtx) { + EnTalk* this = THIS; + s8 targetMode = this->actor.home.rot.x - 0x1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk/EnTalk_Init.s") + if (targetMode >= 0 && targetMode < 7) { + this->actor.targetMode = targetMode; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk/EnTalk_Destroy.s") + Actor_SetScale(&this->actor, 1.0f); + this->actionFunc = func_80BDE090; + this->actor.textId = ENTALK_GET_TEXT_ID(&this->actor); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk/func_80BDE058.s") +void EnTalk_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk/func_80BDE090.s") +void func_80BDE058(EnTalk* this, GlobalContext* globalCtx) { + if (func_800B867C(&this->actor, globalCtx)) { + this->actionFunc = func_80BDE090; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk/EnTalk_Update.s") +void func_80BDE090(EnTalk* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + this->actionFunc = func_80BDE058; + return; + } + + if ((this->actor.xzDistToPlayer < 40.0f && Actor_IsLinkFacingActor(&this->actor, 0x3000, globalCtx)) || + this->actor.isTargeted) { + func_800B8614(&this->actor, globalCtx, 120.0f); + } +} + +void EnTalk_Update(Actor* thisx, GlobalContext* globalCtx) { + EnTalk* this = THIS; + + this->actionFunc(this, globalCtx); +} diff --git a/src/overlays/actors/ovl_En_Talk/z_en_talk.h b/src/overlays/actors/ovl_En_Talk/z_en_talk.h index 764127f76..629a5c0e2 100644 --- a/src/overlays/actors/ovl_En_Talk/z_en_talk.h +++ b/src/overlays/actors/ovl_En_Talk/z_en_talk.h @@ -3,6 +3,8 @@ #include "global.h" +#define ENTALK_GET_TEXT_ID(thisx) (((thisx)->params & 0x3F) + 0x1C00) + struct EnTalk; typedef void (*EnTalkActionFunc)(struct EnTalk*, GlobalContext*); diff --git a/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.c b/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.c index 0c5dbfa71..5b9e6079b 100644 --- a/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.c +++ b/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.c @@ -5,6 +5,7 @@ */ #include "z_en_talk_gibud.h" +#include "objects/object_rd/object_rd.h" #define FLAGS 0x00000415 @@ -15,7 +16,81 @@ void EnTalkGibud_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnTalkGibud_Update(Actor* thisx, GlobalContext* globalCtx); void EnTalkGibud_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void EnTalkGibud_SetupIdle(EnTalkGibud* this); +void EnTalkGibud_Idle(EnTalkGibud* this, GlobalContext* globalCtx); +void EnTalkGibud_SetupAttemptPlayerStun(EnTalkGibud* this); +void EnTalkGibud_AttemptPlayerStun(EnTalkGibud* this, GlobalContext* globalCtx); +void EnTalkGibud_SetupWalkToPlayer(EnTalkGibud* this); +void EnTalkGibud_WalkToPlayer(EnTalkGibud* this, GlobalContext* globalCtx); +void EnTalkGibud_SetupGrab(EnTalkGibud* this); +void EnTalkGibud_Grab(EnTalkGibud* this, GlobalContext* globalCtx); +void EnTalkGibud_SetupGrabFail(EnTalkGibud* this); +void EnTalkGibud_GrabFail(EnTalkGibud* this, GlobalContext* globalCtx); +void EnTalkGibud_SetupTurnAwayAndShakeHead(EnTalkGibud* this); +void EnTalkGibud_TurnAwayAndShakeHead(EnTalkGibud* this, GlobalContext* globalCtx); +void EnTalkGibud_SetupWalkToHome(EnTalkGibud* this); +void EnTalkGibud_WalkToHome(EnTalkGibud* this, GlobalContext* globalCtx); +void EnTalkGibud_Stunned(EnTalkGibud* this, GlobalContext* globalCtx); +void EnTalkGibud_SetupDamage(EnTalkGibud* this); +void EnTalkGibud_Damage(EnTalkGibud* this, GlobalContext* globalCtx); +void EnTalkGibud_SetupDead(EnTalkGibud* this); +void EnTalkGibud_Dead(EnTalkGibud* this, GlobalContext* globalCtx); +void EnTalkGibud_SetupRevive(EnTalkGibud* this); +void EnTalkGibud_Revive(EnTalkGibud* this, GlobalContext* globalCtx); +void EnTalkGibud_PassiveIdle(EnTalkGibud* this, GlobalContext* globalCtx); +void EnTalkGibud_SetupTalk(EnTalkGibud* this); +void EnTalkGibud_Talk(EnTalkGibud* this, GlobalContext* globalCtx); +void EnTalkGibud_SetupDisappear(EnTalkGibud* this); +void EnTalkGibud_Disappear(EnTalkGibud* this, GlobalContext* globalCtx); +void EnTalkGibud_FacePlayerWhenTalking(EnTalkGibud* this, GlobalContext* globalCtx); +s32 EnTalkGibud_PlayerInRangeWithCorrectState(EnTalkGibud* this, GlobalContext* globalCtx); +s32 EnTalkGibud_PlayerOutOfRange(EnTalkGibud* this, GlobalContext* globalCtx); +void EnTalkGibud_TurnTowardsPlayer(EnTalkGibud* this, GlobalContext* globalCtx); +s32 EnTalkGibud_MoveToIdealGrabPositionAndRotation(EnTalkGibud* this, GlobalContext* globalCtx); + +typedef struct { + /* 0x0 */ s32 itemActionParam; + /* 0x4 */ s32 item; + /* 0x8 */ s32 amount; + /* 0xC */ s16 isBottledItem; +} EnTalkGibudRequestedItem; + +typedef enum { + /* 0 */ EN_TALK_GIBUD_ANIMATION_GRAB_ATTACK, + /* 1 */ EN_TALK_GIBUD_ANIMATION_GRAB_END, + /* 2 */ EN_TALK_GIBUD_ANIMATION_GRAB_START, + /* 3 */ EN_TALK_GIBUD_ANIMATION_LOOK_AWAY, + /* 4 */ EN_TALK_GIBUD_ANIMATION_CROUCH_WIPING_TEARS, + /* 5 */ EN_TALK_GIBUD_ANIMATION_CROUCH_CRYING, + /* 6 */ EN_TALK_GIBUD_ANIMATION_DEATH, + /* 7 */ EN_TALK_GIBUD_ANIMATION_DAMAGE, + /* 8 */ EN_TALK_GIBUD_ANIMATION_CROUCH_END, + /* 9 */ EN_TALK_GIBUD_ANIMATION_IDLE, + /* 10 */ EN_TALK_GIBUD_ANIMATION_WALK, + /* 11 */ EN_TALK_GIBUD_ANIMATION_DANCE_SQUAT, + /* 12 */ EN_TALK_GIBUD_ANIMATION_DANCE_PIROUETTE, + /* 13 */ EN_TALK_GIBUD_ANIMATION_DANCE_CLAP, +} EnTalkGibudAnimations; + +typedef enum { + /* 0 */ EN_TALK_GIBUD_REQUESTED_ITEM_MET, + /* 1 */ EN_TALK_GIBUD_REQUESTED_ITEM_NOT_ENOUGH_AMMO, + /* 2 */ EN_TALK_GIBUD_REQUESTED_ITEM_NOT_MET, +} EnTalkGibudRequestedItemState; + +typedef enum { + /* 0 */ EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_BLUE_POTION, + /* 1 */ EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_BEANS, + /* 2 */ EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_SPRING_WATER, + /* 3 */ EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_FISH, + /* 4 */ EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_BUGS, + /* 5 */ EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_DEKU_NUTS, + /* 6 */ EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_BOMBS, + /* 7 */ EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_HOT_SPRING_WATER, + /* 8 */ EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_BIG_POE, + /* 9 */ EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_MILK, +} EnTalkGibudRequestedItemIndex; + const ActorInit En_Talk_Gibud_InitVars = { ACTOR_EN_TALK_GIBUD, ACTORCAT_ENEMY, @@ -28,166 +103,1056 @@ const ActorInit En_Talk_Gibud_InitVars = { (ActorFunc)EnTalkGibud_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B01350 = { - { COLTYPE_HIT0, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK1, { 0x00000000, 0x00, 0x00 }, { 0xF7EFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON | BUMP_HOOKABLE, OCELEM_ON, }, +static ActorAnimationEntry sAnimations[] = { + { &object_rd_Anim_006678, 1.0f, 0.0f, 0.0f, 0, -8.0f }, { &object_rd_Anim_006B08, 0.5f, 0.0f, 0.0f, 3, 0.0f }, + { &object_rd_Anim_006EEC, 1.0f, 0.0f, 0.0f, 2, -8.0f }, { &object_rd_Anim_0073A4, 0.0f, 0.0f, 0.0f, 2, -8.0f }, + { &object_rd_Anim_007BBC, 1.0f, 0.0f, 0.0f, 2, -8.0f }, { &object_rd_Anim_0081A8, 1.0f, 0.0f, 0.0f, 0, -8.0f }, + { &object_rd_Anim_009298, 1.0f, 0.0f, 0.0f, 2, -8.0f }, { &object_rd_Anim_009900, 1.0f, 0.0f, 0.0f, 2, -8.0f }, + { &object_rd_Anim_00A450, 1.0f, 0.0f, 0.0f, 2, -8.0f }, { &object_rd_Anim_00ABE0, 1.0f, 0.0f, 0.0f, 0, -8.0f }, + { &object_rd_Anim_0113EC, 0.4f, 0.0f, 0.0f, 1, -8.0f }, { &object_rd_Anim_01216C, 1.0f, 0.0f, 0.0f, 0, -8.0f }, + { &object_rd_Anim_0118D8, 1.0f, 0.0f, 0.0f, 0, -8.0f }, { &object_rd_Anim_011DB8, 1.0f, 0.0f, 0.0f, 0, -8.0f }, +}; + +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_HIT0, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK1, + { 0x00000000, 0x00, 0x00 }, + { 0xF7EFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON | BUMP_HOOKABLE, + OCELEM_ON, + }, { 20, 70, 0, { 0, 0, 0 } }, }; -// static DamageTable sDamageTable = { -static DamageTable D_80B0137C = { - /* Deku Nut */ DMG_ENTRY(0, 0x0), - /* Deku Stick */ DMG_ENTRY(2, 0xF), - /* Horse trample */ DMG_ENTRY(0, 0x0), - /* Explosives */ DMG_ENTRY(1, 0xF), - /* Zora boomerang */ DMG_ENTRY(0, 0xD), - /* Normal arrow */ DMG_ENTRY(0, 0xD), - /* UNK_DMG_0x06 */ DMG_ENTRY(2, 0xF), - /* Hookshot */ DMG_ENTRY(0, 0xD), - /* Goron punch */ DMG_ENTRY(1, 0xF), - /* Sword */ DMG_ENTRY(1, 0xF), - /* Goron pound */ DMG_ENTRY(1, 0xF), - /* Fire arrow */ DMG_ENTRY(1, 0x2), - /* Ice arrow */ DMG_ENTRY(0, 0xD), - /* Light arrow */ DMG_ENTRY(2, 0x4), - /* Goron spikes */ DMG_ENTRY(1, 0xF), - /* Deku spin */ DMG_ENTRY(0, 0x1), - /* Deku bubble */ DMG_ENTRY(0, 0xD), - /* Deku launch */ DMG_ENTRY(2, 0xF), - /* UNK_DMG_0x12 */ DMG_ENTRY(0, 0x0), - /* Zora barrier */ DMG_ENTRY(0, 0xC), - /* Normal shield */ DMG_ENTRY(0, 0x0), - /* Light ray */ DMG_ENTRY(0, 0xE), - /* Thrown object */ DMG_ENTRY(1, 0xF), - /* Zora punch */ DMG_ENTRY(1, 0xF), - /* Spin attack */ DMG_ENTRY(1, 0xF), - /* Sword beam */ DMG_ENTRY(0, 0x0), - /* Normal Roll */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x1B */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x1C */ DMG_ENTRY(0, 0x0), - /* Unblockable */ DMG_ENTRY(0, 0x0), - /* UNK_DMG_0x1E */ DMG_ENTRY(0, 0x0), - /* Powder Keg */ DMG_ENTRY(1, 0xF), +typedef enum { + /* 0x0 */ EN_TALK_GIBUD_DMGEFF_NONE, // Does not interact with the Gibdo/Redead at all + /* 0x1 */ EN_TALK_GIBUD_DMGEFF_STUN, // Stuns without applying any effect + /* 0x2 */ EN_TALK_GIBUD_DMGEFF_FIRE_ARROW, // Damages and changes a Gibdo into a Redead + /* 0x4 */ EN_TALK_GIBUD_DMGEFF_LIGHT_ARROW = 0x4, // Damages and applies a light effect + /* 0xC */ EN_TALK_GIBUD_DMGEFF_ZORA_MAGIC = 0xC, // Stuns and applies an electric effect + /* 0xD */ EN_TALK_GIBUD_DMGEFF_RECOIL, // Deals no damage, but displays hit mark and recoil animation + /* 0xE */ EN_TALK_GIBUD_DMGEFF_LIGHT_RAY, // Instantly kills a Redead on contact + /* 0xF */ EN_TALK_GIBUD_DMGEFF_DAMAGE, // Deals damage and plays the damage animation +} EnTalkGibudDamageEffect; + +static DamageTable sDamageTable = { + /* Deku Nut */ DMG_ENTRY(0, EN_TALK_GIBUD_DMGEFF_NONE), + /* Deku Stick */ DMG_ENTRY(2, EN_TALK_GIBUD_DMGEFF_DAMAGE), + /* Horse trample */ DMG_ENTRY(0, EN_TALK_GIBUD_DMGEFF_NONE), + /* Explosives */ DMG_ENTRY(1, EN_TALK_GIBUD_DMGEFF_DAMAGE), + /* Zora boomerang */ DMG_ENTRY(0, EN_TALK_GIBUD_DMGEFF_RECOIL), + /* Normal arrow */ DMG_ENTRY(0, EN_TALK_GIBUD_DMGEFF_RECOIL), + /* UNK_DMG_0x06 */ DMG_ENTRY(2, EN_TALK_GIBUD_DMGEFF_DAMAGE), + /* Hookshot */ DMG_ENTRY(0, EN_TALK_GIBUD_DMGEFF_RECOIL), + /* Goron punch */ DMG_ENTRY(1, EN_TALK_GIBUD_DMGEFF_DAMAGE), + /* Sword */ DMG_ENTRY(1, EN_TALK_GIBUD_DMGEFF_DAMAGE), + /* Goron pound */ DMG_ENTRY(1, EN_TALK_GIBUD_DMGEFF_DAMAGE), + /* Fire arrow */ DMG_ENTRY(1, EN_TALK_GIBUD_DMGEFF_FIRE_ARROW), + /* Ice arrow */ DMG_ENTRY(0, EN_TALK_GIBUD_DMGEFF_RECOIL), + /* Light arrow */ DMG_ENTRY(2, EN_TALK_GIBUD_DMGEFF_LIGHT_ARROW), + /* Goron spikes */ DMG_ENTRY(1, EN_TALK_GIBUD_DMGEFF_DAMAGE), + /* Deku spin */ DMG_ENTRY(0, EN_TALK_GIBUD_DMGEFF_STUN), + /* Deku bubble */ DMG_ENTRY(0, EN_TALK_GIBUD_DMGEFF_RECOIL), + /* Deku launch */ DMG_ENTRY(2, EN_TALK_GIBUD_DMGEFF_DAMAGE), + /* UNK_DMG_0x12 */ DMG_ENTRY(0, EN_TALK_GIBUD_DMGEFF_NONE), + /* Zora barrier */ DMG_ENTRY(0, EN_TALK_GIBUD_DMGEFF_ZORA_MAGIC), + /* Normal shield */ DMG_ENTRY(0, EN_TALK_GIBUD_DMGEFF_NONE), + /* Light ray */ DMG_ENTRY(0, EN_TALK_GIBUD_DMGEFF_LIGHT_RAY), + /* Thrown object */ DMG_ENTRY(1, EN_TALK_GIBUD_DMGEFF_DAMAGE), + /* Zora punch */ DMG_ENTRY(1, EN_TALK_GIBUD_DMGEFF_DAMAGE), + /* Spin attack */ DMG_ENTRY(1, EN_TALK_GIBUD_DMGEFF_DAMAGE), + /* Sword beam */ DMG_ENTRY(0, EN_TALK_GIBUD_DMGEFF_NONE), + /* Normal Roll */ DMG_ENTRY(0, EN_TALK_GIBUD_DMGEFF_NONE), + /* UNK_DMG_0x1B */ DMG_ENTRY(0, EN_TALK_GIBUD_DMGEFF_NONE), + /* UNK_DMG_0x1C */ DMG_ENTRY(0, EN_TALK_GIBUD_DMGEFF_NONE), + /* Unblockable */ DMG_ENTRY(0, EN_TALK_GIBUD_DMGEFF_NONE), + /* UNK_DMG_0x1E */ DMG_ENTRY(0, EN_TALK_GIBUD_DMGEFF_NONE), + /* Powder Keg */ DMG_ENTRY(1, EN_TALK_GIBUD_DMGEFF_DAMAGE), }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80B0139C = { 8, 0, 0, 0, MASS_HEAVY }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 8, 0, 0, 0, MASS_HEAVY }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B01448[] = { +static EnTalkGibudRequestedItem sRequestedItemTable[] = { + { PLAYER_AP_BOTTLE_POTION_BLUE, ITEM_POTION_BLUE, 1, true }, + { PLAYER_AP_MAGIC_BEANS, ITEM_MAGIC_BEANS, 5, false }, + { PLAYER_AP_BOTTLE_SPRING_WATER, ITEM_SPRING_WATER, 1, true }, + { PLAYER_AP_BOTTLE_FISH, ITEM_FISH, 1, true }, + { PLAYER_AP_BOTTLE_BUG, ITEM_BUG, 1, true }, + { PLAYER_AP_NUT, ITEM_NUT, 10, false }, + { PLAYER_AP_BOMB, ITEM_BOMB, 10, false }, + { PLAYER_AP_BOTTLE_HOT_SPRING_WATER, ITEM_HOT_SPRING_WATER, 1, true }, + { PLAYER_AP_BOTTLE_BIG_POE, ITEM_BIG_POE, 1, true }, + { PLAYER_AP_BOTTLE_MILK, ITEM_MILK_BOTTLE, 1, true }, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(targetArrowOffset, 2000, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 10, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -3500, ICHAIN_STOP), }; -#endif +static Vec3f sVelocity = { 0.0f, 0.0f, 0.0f }; -extern ColliderCylinderInit D_80B01350; -extern DamageTable D_80B0137C; -extern CollisionCheckInfoInit2 D_80B0139C; -extern InitChainEntry D_80B01448[]; +static Vec3f sAccel = { 0.0f, 0.600000023842f, 0.0f }; -extern UNK_TYPE D_06009298; -extern UNK_TYPE D_0600ABE0; -extern UNK_TYPE D_06010B88; +void EnTalkGibud_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnTalkGibud* this = THIS; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/EnTalkGibud_Init.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + this->actor.targetMode = 0; + this->actor.hintId = 0x2D; + this->actor.textId = 0; + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 28.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_rd_Skel_0053E8, &object_rd_Anim_00ABE0, this->jointTable, + this->morphTable, EN_TALK_GIBUD_LIMB_MAX); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, &sDamageTable, &sColChkInfoInit); + this->playerStunWaitTimer = 0; + this->grabState = EN_TALK_GIBUD_GRAB_START; + this->grabWaitTimer = 0; + this->itemActionParam = PLAYER_AP_NONE; + this->effectTimer = 0; + this->effectType = 0; + this->isTalking = false; + this->type = EN_TALK_GIBUD_TYPE_GIBDO; + this->requestedItemIndex = EN_TALK_GIBUD_REQUESTED_ITEM_INDEX(thisx); + this->switchFlag = EN_TALK_GIBUD_SWITCH_FLAG(thisx); + this->effectAlpha = 0.0f; + this->effectScale = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/EnTalkGibud_Destroy.s") + for (i = 0; i < ARRAY_COUNT(this->limbPos); i++) { + this->limbPos[i] = gZeroVec3f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFEB38.s") + if (this->requestedItemIndex < EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_BLUE_POTION) { + this->requestedItemIndex = EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_BLUE_POTION; + } + if (this->requestedItemIndex > EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_MILK) { + this->requestedItemIndex = EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_MILK; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFEB7C.s") + if (this->switchFlag == 0xFF) { + this->switchFlag = -1; + } + if (this->switchFlag != -1 && Flags_GetSwitch(globalCtx, this->switchFlag)) { + Actor_MarkForDeath(&this->actor); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFEC08.s") + EnTalkGibud_SetupIdle(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFEC4C.s") +void EnTalkGibud_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnTalkGibud* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFED08.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFED7C.s") +void EnTalkGibud_SetupIdle(EnTalkGibud* this) { + func_800BDC5C(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_IDLE); + this->actionFunc = EnTalkGibud_Idle; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFEFD4.s") +/** + * This is the idle for when the player is not wearing the Gibdo Mask. The + * Gibdo will attack the player if they get too close. + */ +void EnTalkGibud_Idle(EnTalkGibud* this, GlobalContext* globalCtx) { + if (this->actor.xzDistToPlayer <= 150.0f && func_800B715C(globalCtx)) { + EnTalkGibud_SetupAttemptPlayerStun(this); + } + Math_SmoothStepToS(&this->headRotation.y, 0, 1, 0x64, 0); + Math_SmoothStepToS(&this->upperBodyRotation.y, 0, 1, 0x64, 0); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF030.s") +void EnTalkGibud_SetupAttemptPlayerStun(EnTalkGibud* this) { + func_800BDC5C(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_IDLE); + this->actionFunc = EnTalkGibud_AttemptPlayerStun; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF22C.s") +void EnTalkGibud_AttemptPlayerStun(EnTalkGibud* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s16 rot = this->actor.shape.rot.y + this->headRotation.y + this->upperBodyRotation.y; + s16 yaw = BINANG_SUB(this->actor.yawTowardsPlayer, rot); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF288.s") + if (ABS_ALT(yaw) < 0x2008) { + player->actor.freezeTimer = 60; + func_8013ECE0(this->actor.xzDistToPlayer, 255, 20, 150); + func_80123E90(globalCtx, &this->actor); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_AIM); + EnTalkGibud_SetupWalkToPlayer(this); + } + EnTalkGibud_TurnTowardsPlayer(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF330.s") +void EnTalkGibud_SetupWalkToPlayer(EnTalkGibud* this) { + func_800BDC5C(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_WALK); + this->actor.speedXZ = 0.4f; + if (this->actionFunc == EnTalkGibud_AttemptPlayerStun) { + this->playerStunWaitTimer = 80; + } else { + this->playerStunWaitTimer = 20; + } + this->actionFunc = EnTalkGibud_WalkToPlayer; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF378.s") +void EnTalkGibud_WalkToPlayer(EnTalkGibud* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF45C.s") + Math_ScaledStepToS(&this->actor.shape.rot.y, this->actor.yawTowardsPlayer, 0xFA); + this->actor.world.rot = this->actor.shape.rot; + Math_SmoothStepToS(&this->headRotation.y, 0, 1, 100, 0); + Math_SmoothStepToS(&this->upperBodyRotation.y, 0, 1, 100, 0); + if (EnTalkGibud_PlayerInRangeWithCorrectState(this, globalCtx) && Actor_IsActorFacingLink(&this->actor, 0x38E3)) { + if (this->grabWaitTimer == 0 && this->actor.xzDistToPlayer <= 45.0f) { + player->actor.freezeTimer = 0; + if (gSaveContext.playerForm == PLAYER_FORM_GORON || gSaveContext.playerForm == PLAYER_FORM_DEKU) { + // If the Gibdo/Redead tries to grab Goron or Deku Link, it will fail to + // do so. It will appear to take damage and shake its head side-to-side. + EnTalkGibud_SetupGrabFail(this); + } else if (globalCtx->grabPlayer(globalCtx, player)) { + EnTalkGibud_SetupGrab(this); + } + } else { + if (this->playerStunWaitTimer == 0) { + player->actor.freezeTimer = 40; + this->playerStunWaitTimer = 60; + func_8013ECE0(this->actor.xzDistToPlayer, 255, 20, 150); + func_80123E90(globalCtx, &this->actor); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_AIM); + } else { + this->playerStunWaitTimer--; + } + } + } else if (this->grabWaitTimer == 0 && this->actor.xzDistToPlayer <= 45.0f) { + EnTalkGibud_SetupWalkToHome(this); + } else if (EnTalkGibud_PlayerOutOfRange(this, globalCtx)) { + EnTalkGibud_SetupWalkToHome(this); + } + if (this->grabWaitTimer > 0) { + this->grabWaitTimer--; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF4AC.s") + if (Animation_OnFrame(&this->skelAnime, 10.0f) || Animation_OnFrame(&this->skelAnime, 22.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_RIZA_WALK); + } else if (!(globalCtx->gameplayFrames & 0x5F)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_CRY); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF618.s") +void EnTalkGibud_SetupGrab(EnTalkGibud* this) { + func_800BDC5C(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_GRAB_START); + this->grabDamageTimer = 0; + this->actor.flags &= ~1; + this->grabState = EN_TALK_GIBUD_GRAB_START; + this->actionFunc = EnTalkGibud_Grab; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF6A0.s") +void EnTalkGibud_Grab(EnTalkGibud* this, GlobalContext* globalCtx) { + // This function needs to have two different temps for Player to match, + // but you don't have to necessarily use them both. This is just the most + // likely scenario; they got an Actor* pointer in the first temp, then + // casted it to Player* in the second temp. + Actor* playerActor = &GET_PLAYER(globalCtx)->actor; + Player* player = (Player*)playerActor; + s32 inPositionToAttack; + u16 damageSfxId; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF700.s") + switch (this->grabState) { + case EN_TALK_GIBUD_GRAB_START: + inPositionToAttack = EnTalkGibud_MoveToIdealGrabPositionAndRotation(this, globalCtx); + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame) && inPositionToAttack == true) { + this->grabState = EN_TALK_GIBUD_GRAB_ATTACK; + func_800BDC5C(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_GRAB_ATTACK); + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF76C.s") + case EN_TALK_GIBUD_GRAB_ATTACK: + if (this->grabDamageTimer == 20) { + s16 requiredScopeTemp; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF880.s") + damageSfxId = player->ageProperties->unk_92 + NA_SE_VO_LI_DAMAGE_S; + globalCtx->damagePlayer(globalCtx, -8); + func_800B8E58(playerActor, damageSfxId); + func_8013ECE0(this->actor.xzDistToPlayer, 240, 1, 12); + this->grabDamageTimer = 0; + } else { + this->grabDamageTimer++; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF8E4.s") + if (Animation_OnFrame(&this->skelAnime, 0.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_ATTACK); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFF9CC.s") + if (!(player->stateFlags2 & 0x80) || player->unk_B62 != 0) { + if (player->unk_B62 != 0 && (player->stateFlags2 & 0x80)) { + player->stateFlags2 &= ~0x80; + player->unk_AE8 = 100; + } + func_800BDC5C(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_GRAB_END); + this->actor.flags |= 1; + this->grabState = EN_TALK_GIBUD_GRAB_RELEASE; + this->grabDamageTimer = 0; + } + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFFA68.s") + case EN_TALK_GIBUD_GRAB_RELEASE: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->grabWaitTimer = 20; + this->actor.shape.yOffset = 0.0f; + EnTalkGibud_SetupWalkToPlayer(this); + } else { + Math_SmoothStepToF(&this->actor.shape.yOffset, 0.0f, 1.0f, 400.0f, 0.0f); + } + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFFAB0.s") +void EnTalkGibud_SetupGrabFail(EnTalkGibud* this) { + func_800BDC5C(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_DAMAGE); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_DAMAGE); + this->actionFunc = EnTalkGibud_GrabFail; + this->actor.speedXZ = -2.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFFC10.s") +void EnTalkGibud_GrabFail(EnTalkGibud* this, GlobalContext* globalCtx) { + if (this->actor.speedXZ < 0.0f) { + this->actor.speedXZ += 0.15f; + } + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + Math_SmoothStepToS(&this->headRotation.y, 0, 1, 0x12C, 0); + Math_SmoothStepToS(&this->upperBodyRotation.y, 0, 1, 0x12C, 0); + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->actor.world.rot.y = this->actor.shape.rot.y; + EnTalkGibud_SetupTurnAwayAndShakeHead(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFFC9C.s") +void EnTalkGibud_SetupTurnAwayAndShakeHead(EnTalkGibud* this) { + this->headShakeTimer = 0; + func_800BDC5C(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_WALK); + this->actionFunc = EnTalkGibud_TurnAwayAndShakeHead; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFFD3C.s") +void EnTalkGibud_TurnAwayAndShakeHead(EnTalkGibud* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->actor.world.rot.y, BINANG_ROT180(this->actor.yawTowardsPlayer), 5, 3500, 200); + this->actor.shape.rot.y = this->actor.world.rot.y; + if (this->headShakeTimer > 60) { + EnTalkGibud_SetupWalkToHome(this); + this->playerStunWaitTimer = 0; + } else { + this->headRotation.y = + Math_SinS(this->headShakeTimer * 4000) * (0x256F * ((60 - this->headShakeTimer) / 60.0f)); + this->headShakeTimer++; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFFE3C.s") +void EnTalkGibud_SetupWalkToHome(EnTalkGibud* this) { + func_800BDC5C(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_WALK); + this->actor.speedXZ = 0.4f; + this->actionFunc = EnTalkGibud_WalkToHome; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFFE94.s") +void EnTalkGibud_WalkToHome(EnTalkGibud* this, GlobalContext* globalCtx) { + Math_SmoothStepToS(&this->headRotation.y, 0, 1, 100, 0); + Math_SmoothStepToS(&this->upperBodyRotation.y, 0, 1, 100, 0); + if (Actor_XZDistanceToPoint(&this->actor, &this->actor.home.pos) < 5.0f) { + if (this->actor.speedXZ > 0.2f) { + this->actor.speedXZ -= 0.2f; + } else { + this->actor.speedXZ = 0.0f; + } + Math_SmoothStepToS(&this->actor.shape.rot.y, this->actor.home.rot.y, 1, 200, 10); + this->actor.world.rot.y = this->actor.shape.rot.y; + if (this->actor.world.rot.y == this->actor.home.rot.y) { + EnTalkGibud_SetupIdle(this); + } + } else { + Math_ScaledStepToS(&this->actor.shape.rot.y, Actor_YawToPoint(&this->actor, &this->actor.home.pos), 450); + this->actor.world.rot = this->actor.shape.rot; + } + if (EnTalkGibud_PlayerInRangeWithCorrectState(this, globalCtx)) { + if (gSaveContext.playerForm != PLAYER_FORM_GORON && gSaveContext.playerForm != PLAYER_FORM_DEKU && + Actor_IsActorFacingLink(&this->actor, 0x38E3)) { + EnTalkGibud_SetupWalkToPlayer(this); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFFFA4.s") +void EnTalkGibud_SetupStunned(EnTalkGibud* this) { + this->stunTimer = 10; + this->actor.speedXZ = 0.0f; + this->actor.world.rot.y = this->actor.shape.rot.y; + if (this->effectTimer != 0) { + func_800BCB70(&this->actor, 0, 0xC8, 0, 0x28); + } else { + func_800BCB70(&this->actor, 0, 0xC8, 0, 0x28); + } + this->actionFunc = EnTalkGibud_Stunned; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80AFFFBC.s") +void EnTalkGibud_Stunned(EnTalkGibud* this, GlobalContext* globalCtx) { + if (this->actor.colorFilterTimer == 0) { + if (this->actor.colChkInfo.health == 0) { + EnTalkGibud_SetupDead(this); + } else { + EnTalkGibud_SetupDamage(this); + } + } + if (this->stunTimer != 0) { + this->stunTimer--; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B000FC.s") +void EnTalkGibud_SetupDamage(EnTalkGibud* this) { + func_800BDC5C(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_DAMAGE); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_DAMAGE); + this->stunTimer = 0; + this->grabWaitTimer = 0; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + this->actionFunc = EnTalkGibud_Damage; + this->actor.speedXZ = -2.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B00158.s") +void EnTalkGibud_Damage(EnTalkGibud* this, GlobalContext* globalCtx) { + if (this->actor.speedXZ < 0.0f) { + this->actor.speedXZ += 0.15f; + } + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->unk_3F7 = -1; + this->actor.world.rot.y = this->actor.shape.rot.y; + if (this->effectTimer > 0 && this->effectType == 0 && this->type == EN_TALK_GIBUD_TYPE_GIBDO) { + this->actor.hintId = 0x2A; + this->actor.flags &= ~(0x8 | 0x1); + this->actor.flags |= (0x4 | 0x1); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_rd_Skel_010B88, NULL, this->jointTable, + this->morphTable, EN_TALK_GIBUD_LIMB_MAX); + this->type = EN_TALK_GIBUD_TYPE_REDEAD; + } + if (EnTalkGibud_PlayerOutOfRange(this, globalCtx)) { + EnTalkGibud_SetupWalkToHome(this); + } else { + EnTalkGibud_SetupWalkToPlayer(this); + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B00384.s") +void EnTalkGibud_SetupDead(EnTalkGibud* this) { + func_800BDC5C(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_DEATH); + this->actor.flags &= ~1; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_DEAD); + this->deathTimer = 0; + this->actionFunc = EnTalkGibud_Dead; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B0040C.s") +void EnTalkGibud_Dead(EnTalkGibud* this, GlobalContext* globalCtx) { + if (this->deathTimer > 300) { + EnTalkGibud_SetupRevive(this); + } else { + Math_SmoothStepToS(&this->headRotation.y, 0, 1, 250, 0); + Math_SmoothStepToS(&this->upperBodyRotation.y, 0, 1, 250, 0); + this->deathTimer++; + } + if (this->deathTimer == 20 && this->effectTimer > 0 && this->effectType == 0 && + this->type == EN_TALK_GIBUD_TYPE_GIBDO) { + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_rd_Skel_010B88, NULL, this->jointTable, + this->morphTable, EN_TALK_GIBUD_LIMB_MAX); + this->type = EN_TALK_GIBUD_TYPE_REDEAD; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B00484.s") +void EnTalkGibud_SetupRevive(EnTalkGibud* this) { + Animation_Change(&this->skelAnime, &object_rd_Anim_009298, -1.0f, Animation_GetLastFrame(&object_rd_Anim_009298), + 0.0f, 2, -8.0f); + this->actor.flags |= 1; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_REVERSE); + this->deathTimer = 0; + this->actor.world.rot.y = this->actor.shape.rot.y; + this->actionFunc = EnTalkGibud_Revive; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B004D0.s") +void EnTalkGibud_Revive(EnTalkGibud* this, GlobalContext* globalCtx) { + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->actor.colChkInfo.health = 8; + EnTalkGibud_SetupIdle(this); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B005EC.s") +void EnTalkGibud_GetTextIdForRequestedItem(EnTalkGibud* this, GlobalContext* globalCtx) { + switch (this->requestedItemIndex) { + case EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_BLUE_POTION: + func_801518B0(globalCtx, 0x138C, &this->actor); + this->textId = 0x138C; + break; + case EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_BEANS: + func_801518B0(globalCtx, 0x138D, &this->actor); + this->textId = 0x138D; + break; + case EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_SPRING_WATER: + func_801518B0(globalCtx, 0x138E, &this->actor); + this->textId = 0x138E; + break; + case EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_FISH: + func_801518B0(globalCtx, 0x138F, &this->actor); + this->textId = 0x138F; + break; + case EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_BUGS: + func_801518B0(globalCtx, 0x1390, &this->actor); + this->textId = 0x1390; + break; + case EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_DEKU_NUTS: + func_801518B0(globalCtx, 0x1391, &this->actor); + this->textId = 0x1391; + break; + case EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_BOMBS: + func_801518B0(globalCtx, 0x1392, &this->actor); + this->textId = 0x1392; + break; + case EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_HOT_SPRING_WATER: + func_801518B0(globalCtx, 0x1393, &this->actor); + this->textId = 0x1393; + break; + case EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_BIG_POE: + func_801518B0(globalCtx, 0x1394, &this->actor); + this->textId = 0x1394; + break; + case EN_TALK_GIBUD_REQUESTED_ITEM_INDEX_MILK: + func_801518B0(globalCtx, 0x1395, &this->actor); + this->textId = 0x1395; + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B00760.s") +void EnTalkGibud_GetNextTextBoxId(EnTalkGibud* this, GlobalContext* globalCtx) { + if (func_80147624(globalCtx)) { + switch (this->textId) { + case 0x1388: + EnTalkGibud_GetTextIdForRequestedItem(this, globalCtx); + break; + case 0x138C: + case 0x138D: + case 0x138E: + case 0x138F: + case 0x1390: + case 0x1391: + case 0x1392: + case 0x1393: + case 0x1394: + case 0x1395: + // Prompts the player to choose an item + func_801518B0(globalCtx, 0xFF, &this->actor); + this->textId = 0xFF; + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B008BC.s") +s32 EnTalkGibud_PresentedItemMatchesRequest(EnTalkGibud* this, GlobalContext* globalCtx, s32 presentedItemActionParam) { + EnTalkGibudRequestedItem* requestedItem = &sRequestedItemTable[this->requestedItemIndex]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B008FC.s") + if (requestedItem->itemActionParam == presentedItemActionParam) { + if (!requestedItem->isBottledItem) { + if (AMMO(requestedItem->item) >= requestedItem->amount) { + return EN_TALK_GIBUD_REQUESTED_ITEM_MET; + } else { + return EN_TALK_GIBUD_REQUESTED_ITEM_NOT_ENOUGH_AMMO; + } + } + if (func_80114F2C(requestedItem->item)) { + return EN_TALK_GIBUD_REQUESTED_ITEM_MET; + } + } + return EN_TALK_GIBUD_REQUESTED_ITEM_NOT_MET; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B0094C.s") +void EnTalkGibud_CheckPresentedItem(EnTalkGibud* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 itemActionParam; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B00B8C.s") + if (this->itemActionParam == PLAYER_AP_NONE) { + itemActionParam = func_80123810(globalCtx); + if (itemActionParam != PLAYER_AP_NONE) { + this->itemActionParam = itemActionParam; + } + if (this->itemActionParam > PLAYER_AP_NONE) { + switch (EnTalkGibud_PresentedItemMatchesRequest(this, globalCtx, this->itemActionParam)) { + case EN_TALK_GIBUD_REQUESTED_ITEM_MET: + player->actor.textId = 0x138A; + this->textId = 0x138A; + break; + case EN_TALK_GIBUD_REQUESTED_ITEM_NOT_ENOUGH_AMMO: + player->actor.textId = 0x138B; + this->textId = 0x138B; + break; + case EN_TALK_GIBUD_REQUESTED_ITEM_NOT_MET: + player->actor.textId = 0x1389; + this->textId = 0x1389; + break; + default: + break; + } + func_801477B4(globalCtx); + } else if (this->itemActionParam < PLAYER_AP_NONE) { + func_801518B0(globalCtx, 0x1389, &this->actor); + this->textId = 0x1389; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B00C94.s") +void EnTalkGibud_SetupPassiveIdle(EnTalkGibud* this) { + this->isTalking = false; + if (this->actionFunc != EnTalkGibud_Talk) { + func_800BDC5C(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_IDLE); + } + this->actionFunc = EnTalkGibud_PassiveIdle; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B00D9C.s") +/** + * This is the idle for when the player is wearing the Gibdo Mask. The + * Gibdo will not attempt to attack the player and can be spoken to. + */ +void EnTalkGibud_PassiveIdle(EnTalkGibud* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + this->isTalking = true; + func_801518B0(globalCtx, 0x1388, &this->actor); + this->textId = 0x1388; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_REDEAD_AIM); + EnTalkGibud_SetupTalk(this); + } else if (this->actor.xzDistToPlayer < 100.0f && !(this->collider.base.acFlags & AC_HIT)) { + func_800E9250(globalCtx, &this->actor, &this->headRotation, &this->upperBodyRotation, this->actor.focus.pos); + func_800B8614(&this->actor, globalCtx, 100.0f); + } else { + Math_SmoothStepToS(&this->headRotation.y, 0, 1, 100, 0); + Math_SmoothStepToS(&this->upperBodyRotation.y, 0, 1, 100, 0); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/EnTalkGibud_Update.s") +void EnTalkGibud_SetupTalk(EnTalkGibud* this) { + this->itemActionParam = PLAYER_AP_NONE; + this->actionFunc = EnTalkGibud_Talk; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B00F08.s") +void EnTalkGibud_Talk(EnTalkGibud* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + EnTalkGibudRequestedItem* requestedItem; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/func_80B00F64.s") + switch (func_80152498(&globalCtx->msgCtx)) { + case 0: + case 1: + case 2: + case 3: + case 4: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + break; + case 5: + EnTalkGibud_GetNextTextBoxId(this, globalCtx); + break; + case 6: + if (func_80147624(globalCtx)) { + if (this->textId == 0x138A) { + // Remove the requested item/amount from the player's inventory + requestedItem = &sRequestedItemTable[this->requestedItemIndex]; + if (!requestedItem->isBottledItem) { + func_80115A14(requestedItem->item, -requestedItem->amount); + } else { + func_80123D50(globalCtx, player, ITEM_BOTTLE, PLAYER_AP_BOTTLE); + } + player->stateFlags1 |= 0x20; + player->stateFlags1 |= 0x20000000; + this->actor.flags |= 0x100000; + EnTalkGibud_SetupDisappear(this); + } else { + EnTalkGibud_SetupPassiveIdle(this); + } + } + break; + case 16: + EnTalkGibud_CheckPresentedItem(this, globalCtx); + break; + } + EnTalkGibud_FacePlayerWhenTalking(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Talk_Gibud/EnTalkGibud_Draw.s") +void EnTalkGibud_SetupDisappear(EnTalkGibud* this) { + func_800BDC5C(&this->skelAnime, sAnimations, EN_TALK_GIBUD_ANIMATION_IDLE); + this->actor.flags &= ~1; + this->disappearanceTimer = 40; + this->actionFunc = EnTalkGibud_Disappear; +} + +void EnTalkGibud_Disappear(EnTalkGibud* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f velocity = sVelocity; + Vec3f accel = sAccel; + Vec3f pos; + s32 numFlamesToSpawn; + s32 i; + + if (this->disappearanceTimer > 0) { + numFlamesToSpawn = CLAMP_MAX(this->disappearanceTimer, 3); + for (i = 0; i < numFlamesToSpawn; i++) { + pos = this->actor.world.pos; + pos.x += Rand_Centered() * 20.0f; + pos.y += 50.0f + (Rand_Centered() * 50.0f); + pos.z += Rand_Centered() * 20.0f; + velocity.x += Rand_Centered() * 1.5f; + velocity.z += Rand_Centered() * 1.5f; + func_800B3030(globalCtx, &pos, &velocity, &accel, 100, 0, 1); + } + func_800B9010(&this->actor, NA_SE_EN_COMMON_EXTINCT_LEV - SFX_FLAG); + player->stateFlags1 |= 0x20000000; + this->disappearanceTimer--; + } else { + if (this->switchFlag != -1) { + Actor_SetSwitchFlag(globalCtx, this->switchFlag); + } + player->stateFlags1 &= ~0x20; + player->stateFlags1 &= ~0x20000000; + Actor_MarkForDeath(&this->actor); + } +} + +void EnTalkGibud_FacePlayerWhenTalking(EnTalkGibud* this, GlobalContext* globalCtx) { + s16 target = this->actor.yawTowardsPlayer; + + Math_ScaledStepToS(&this->actor.shape.rot.y, target, 0x320); + target -= this->actor.shape.rot.y; + this->actor.world.rot.y = this->actor.shape.rot.y; + Math_ScaledStepToS(&this->upperBodyRotation.y, target, 0x258); + target -= this->upperBodyRotation.y; + Math_ScaledStepToS(&this->headRotation.y, target, 0x190); +} + +s32 EnTalkGibud_PlayerInRangeWithCorrectState(EnTalkGibud* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if ((Actor_DistanceToPoint(&player->actor, &this->actor.home.pos) < 150.0f) && !(player->stateFlags1 & 0x2C6080) && + !(player->stateFlags2 & 0x4080)) { + return true; + } + + return false; +} + +/** + * Gibdos/Redeads have a very short range around their home where they will + * engage with the player. If the player is out of this range, they will simply + * walk back to their home. + */ +s32 EnTalkGibud_PlayerOutOfRange(EnTalkGibud* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (Actor_DistanceToPoint(&player->actor, &this->actor.home.pos) >= 150.0f) { + return true; + } + + return false; +} + +void EnTalkGibud_CheckForGibdoMask(EnTalkGibud* this, GlobalContext* globalCtx) { + if (this->actionFunc != EnTalkGibud_Grab && this->actionFunc != EnTalkGibud_Dead && + this->actionFunc != EnTalkGibud_Disappear && this->actionFunc != EnTalkGibud_Revive && + this->actionFunc != EnTalkGibud_Damage && this->actionFunc != EnTalkGibud_Talk) { + if (this->actionFunc != EnTalkGibud_PassiveIdle) { + if (Player_GetMask(globalCtx) == PLAYER_MASK_GIBDO) { + this->actor.flags &= ~(0x4 | 0x1); + this->actor.flags |= (0x8 | 0x1); + this->actor.hintId = 0xFF; + this->actor.textId = 0; + EnTalkGibud_SetupPassiveIdle(this); + } + } else if (Player_GetMask(globalCtx) != PLAYER_MASK_GIBDO) { + this->actor.flags &= ~(0x8 | 0x1); + this->actor.flags |= (0x4 | 0x1); + if (this->type == EN_TALK_GIBUD_TYPE_REDEAD) { + this->actor.hintId = 0x2A; + } else { + this->actor.hintId = 0x2D; + } + this->actor.textId = 0; + EnTalkGibud_SetupWalkToHome(this); + } + } +} + +void EnTalkGibud_TurnTowardsPlayer(EnTalkGibud* this, GlobalContext* globalCtx) { + s16 headAngle = (this->actor.yawTowardsPlayer - this->actor.shape.rot.y) - this->upperBodyRotation.y; + s16 upperBodyAngle = CLAMP(headAngle, -500, 500); + + headAngle -= this->headRotation.y; + headAngle = CLAMP(headAngle, -500, 500); + + if (BINANG_SUB(this->actor.yawTowardsPlayer, this->actor.shape.rot.y) >= 0) { + this->upperBodyRotation.y += ABS_ALT(upperBodyAngle); + this->headRotation.y += ABS_ALT(headAngle); + } else { + this->upperBodyRotation.y -= ABS_ALT(upperBodyAngle); + this->headRotation.y -= ABS_ALT(headAngle); + } + + this->upperBodyRotation.y = CLAMP(this->upperBodyRotation.y, -0x495F, 0x495F); + this->headRotation.y = CLAMP(this->headRotation.y, -0x256F, 0x256F); +} + +/** + * Returns true if the Gibdo is in the correct position and rotation to start + * performing its grab attack. Regardless of what this returns, the Gibdo is + * moved closer to this ideal position and rotation. + */ +s32 EnTalkGibud_MoveToIdealGrabPositionAndRotation(EnTalkGibud* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f targetPos; + f32 distanceFromTargetPos; + f32 distanceFromTargetYOffset = 0.0f; + s16 distanceFromTargetAngle; + + targetPos = player->actor.world.pos; + targetPos.x -= 25.0f * Math_SinS(player->actor.shape.rot.y); + targetPos.z -= 25.0f * Math_CosS(player->actor.shape.rot.y); + distanceFromTargetPos = Math_Vec3f_StepTo(&this->actor.world.pos, &targetPos, 10.0f); + distanceFromTargetAngle = Math_SmoothStepToS(&this->actor.shape.rot.y, player->actor.shape.rot.y, 1, 0x1770, 0x64); + this->actor.world.rot.y = this->actor.shape.rot.y; + if (gSaveContext.playerForm == PLAYER_FORM_HUMAN) { + distanceFromTargetYOffset = Math_SmoothStepToF(&this->actor.shape.yOffset, -1500.0f, 1.0f, 150.0f, 0.0f); + } + + if (distanceFromTargetPos == 0.0f && ABS_ALT(distanceFromTargetAngle) < 100 && distanceFromTargetYOffset == 0.0f) { + return true; + } + + return false; +} + +void EnTalkGibud_PlayAnimation(EnTalkGibud* this, GlobalContext* globalCtx) { + if (this->actionFunc != EnTalkGibud_Stunned) { + SkelAnime_Update(&this->skelAnime); + } +} + +void EnTalkGibud_MoveWithGravity(EnTalkGibud* this, GlobalContext* globalCtx) { + if (this->actionFunc == EnTalkGibud_WalkToPlayer || this->actionFunc == EnTalkGibud_WalkToHome || + this->actionFunc == EnTalkGibud_Damage) { + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + } +} + +void EnTalkGibud_CheckDamageEffect(EnTalkGibud* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + Actor_ApplyDamage(&this->actor); + + switch (this->actor.colChkInfo.damageEffect) { + case EN_TALK_GIBUD_DMGEFF_DAMAGE: + func_800BCB70(&this->actor, 0x4000, 255, 0, 8); + if (player->unk_ADC != 0) { + this->unk_3F7 = player->unk_ADD; + } + this->actor.shape.yOffset = 0.0f; + if (this->actor.colChkInfo.health == 0) { + EnTalkGibud_SetupDead(this); + } else { + EnTalkGibud_SetupDamage(this); + } + break; + + case EN_TALK_GIBUD_DMGEFF_LIGHT_RAY: + if (this->type == EN_TALK_GIBUD_TYPE_REDEAD) { + this->actor.colChkInfo.health = 0; + this->actor.shape.yOffset = 0.0f; + EnTalkGibud_SetupDead(this); + } + break; + + case EN_TALK_GIBUD_DMGEFF_FIRE_ARROW: + func_800BCB70(&this->actor, 0x4000, 255, 0, 8); + if (this->actor.colChkInfo.health == 0) { + EnTalkGibud_SetupDead(this); + } else { + EnTalkGibud_SetupDamage(this); + } + this->effectTimer = 180; + this->effectType = 0; + this->effectAlpha = 1.0f; + break; + + case EN_TALK_GIBUD_DMGEFF_LIGHT_ARROW: + func_800BCB70(&this->actor, 0x4000, 255, 0, 8); + if (this->actor.colChkInfo.health == 0) { + EnTalkGibud_SetupDead(this); + } else { + EnTalkGibud_SetupDamage(this); + } + this->effectTimer = 60; + this->effectType = 20; + this->effectAlpha = 1.0f; + break; + + case EN_TALK_GIBUD_DMGEFF_ZORA_MAGIC: + if (this->actionFunc != EnTalkGibud_Grab && + (this->actionFunc != EnTalkGibud_Stunned || this->stunTimer == 0)) { + this->effectAlpha = 1.0f; + this->effectTimer = 40; + this->effectType = 30; + EnTalkGibud_SetupStunned(this); + } + break; + + case EN_TALK_GIBUD_DMGEFF_STUN: + if ((this->actionFunc != EnTalkGibud_Stunned) || this->stunTimer == 0) { + EnTalkGibud_SetupStunned(this); + } + break; + } + } +} + +void EnTalkGibud_CheckCollision(EnTalkGibud* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (this->actionFunc != EnTalkGibud_Dead && this->actionFunc != EnTalkGibud_Disappear && + this->actionFunc != EnTalkGibud_Revive && + (this->actionFunc != EnTalkGibud_Grab || this->grabState == EN_TALK_GIBUD_GRAB_RELEASE)) { + if (this->isTalking != true) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + if ((this->actionFunc != EnTalkGibud_Damage || + (player->unk_ADC != 0 && player->unk_ADD != this->unk_3F7)) && + (this->actionFunc != EnTalkGibud_Stunned || this->stunTimer == 0)) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + } + } +} + +/** + * If the Gibdo is starting a grab and is touching a wall, the player is moved + * away from that wall with this function. This can happen when the player's + * back is close to a wall before being grabbed. The Gibdo changes its own + * position to match the player's position at the start of a grab, so moving + * the player like this will help prevent the Gibdo from looking like it's + * clipping into the wall as it grabs onto the player. + */ +void EnTalkGibud_MoveGrabbedPlayerAwayFromWall(EnTalkGibud* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f targetPos; + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 30.0f, 20.0f, 35.0f, 29); + if (this->actionFunc == EnTalkGibud_Grab && this->grabState == EN_TALK_GIBUD_GRAB_START && + (this->actor.bgCheckFlags & 8)) { + targetPos = player->actor.world.pos; + targetPos.x += 10.0f * Math_SinS(this->actor.wallYaw); + targetPos.z += 10.0f * Math_CosS(this->actor.wallYaw); + Math_Vec3f_StepTo(&player->actor.world.pos, &targetPos, 5.0f); + } +} + +void EnTalkGibud_UpdateEffect(EnTalkGibud* this, GlobalContext* globalCtx) { + if (this->effectTimer > 0) { + this->effectTimer--; + } + if (this->effectTimer < 20) { + Math_SmoothStepToF(&this->effectScale, 0.0f, 0.5f, 0.03f, 0.0f); + this->effectAlpha = this->effectTimer * 0.05f; + } else { + Math_SmoothStepToF(&this->effectScale, 0.5f, 0.1f, 0.02f, 0.0f); + } +} + +void EnTalkGibud_Update(Actor* thisx, GlobalContext* globalCtx) { + EnTalkGibud* this = THIS; + + EnTalkGibud_CheckForGibdoMask(this, globalCtx); + EnTalkGibud_CheckDamageEffect(this, globalCtx); + this->actionFunc(this, globalCtx); + EnTalkGibud_PlayAnimation(this, globalCtx); + EnTalkGibud_MoveWithGravity(this, globalCtx); + EnTalkGibud_CheckCollision(this, globalCtx); + EnTalkGibud_MoveGrabbedPlayerAwayFromWall(this, globalCtx); + EnTalkGibud_UpdateEffect(this, globalCtx); + this->actor.focus.pos = this->actor.world.pos; + this->actor.focus.pos.y += 50.0f; +} + +s32 EnTalkGibud_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx, Gfx** gfx) { + EnTalkGibud* this = THIS; + + if (limbIndex == EN_TALK_GIBUD_LIMB_UPPER_BODY_ROOT) { + rot->y += this->upperBodyRotation.y; + } else if (limbIndex == EN_TALK_GIBUD_LIMB_HEAD_ROOT) { + rot->y += this->headRotation.y; + } + + return false; +} + +void EnTalkGibud_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, + Gfx** gfx) { + EnTalkGibud* this = THIS; + + if ((this->effectTimer != 0) && + ((limbIndex == EN_TALK_GIBUD_LIMB_LEFT_THIGH) || (limbIndex == EN_TALK_GIBUD_LIMB_LEFT_LOWER_LEG) || + (limbIndex == EN_TALK_GIBUD_LIMB_LEFT_FOOT) || (limbIndex == EN_TALK_GIBUD_LIMB_RIGHT_THIGH) || + (limbIndex == EN_TALK_GIBUD_LIMB_RIGHT_LOWER_LEG) || (limbIndex == EN_TALK_GIBUD_LIMB_RIGHT_FOOT) || + (limbIndex == EN_TALK_GIBUD_LIMB_TORSO) || (limbIndex == EN_TALK_GIBUD_LIMB_LEFT_SHOULDER_AND_UPPER_ARM) || + (limbIndex == EN_TALK_GIBUD_LIMB_LEFT_FOREARM) || (limbIndex == EN_TALK_GIBUD_LIMB_LEFT_HAND) || + (limbIndex == EN_TALK_GIBUD_LIMB_RIGHT_SHOULDER_AND_UPPER_ARM) || + (limbIndex == EN_TALK_GIBUD_LIMB_RIGHT_FOREARM) || (limbIndex == EN_TALK_GIBUD_LIMB_RIGHT_HAND) || + (limbIndex == EN_TALK_GIBUD_LIMB_HEAD) || (limbIndex == EN_TALK_GIBUD_LIMB_PELVIS))) { + Matrix_GetStateTranslation(&this->limbPos[this->limbIndex]); + this->limbIndex++; + } +} + +void EnTalkGibud_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnTalkGibud* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + this->limbIndex = 0; + if (this->actor.shape.shadowAlpha == 255) { + func_8012C28C(globalCtx->state.gfxCtx); + + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 0, this->actor.shape.shadowAlpha); + gSPSegment(POLY_OPA_DISP++, 0x08, D_801AEFA0); + + POLY_OPA_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnTalkGibud_OverrideLimbDraw, + EnTalkGibud_PostLimbDraw, &this->actor, POLY_OPA_DISP); + } else { + func_8012C2DC(globalCtx->state.gfxCtx); + + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, this->actor.shape.shadowAlpha); + gSPSegment(POLY_XLU_DISP++, 0x08, D_801AEF88); + + POLY_XLU_DISP = SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, EnTalkGibud_OverrideLimbDraw, + EnTalkGibud_PostLimbDraw, &this->actor, POLY_XLU_DISP); + } + if (this->effectTimer > 0) { + func_800BE680(globalCtx, &this->actor, this->limbPos, ARRAY_COUNT(this->limbPos), this->effectScale, 0.5f, + this->effectAlpha, this->effectType); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.h b/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.h index 57c0d2ae9..2c154ea89 100644 --- a/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.h +++ b/src/overlays/actors/ovl_En_Talk_Gibud/z_en_talk_gibud.h @@ -3,15 +3,86 @@ #include "global.h" +#define EN_TALK_GIBUD_REQUESTED_ITEM_INDEX(thisx) ((thisx)->params & 0xF) +#define EN_TALK_GIBUD_SWITCH_FLAG(thisx) (((thisx)->params & 0xFF0) >> 4) + +typedef enum { + /* 0 */ EN_TALK_GIBUD_TYPE_GIBDO, + /* 1 */ EN_TALK_GIBUD_TYPE_REDEAD, +} EnTalkGibudType; + +typedef enum { + /* 0 */ EN_TALK_GIBUD_GRAB_START, + /* 1 */ EN_TALK_GIBUD_GRAB_ATTACK, + /* 2 */ EN_TALK_GIBUD_GRAB_RELEASE, +} EnTalkGibudGrabState; + +typedef enum { + /* 0 */ EN_TALK_GIBUD_LIMB_NONE, + /* 1 */ EN_TALK_GIBUD_LIMB_ROOT, // Root of Left Leg Root, Right Leg Root, Upper Body Root, and Pelvis + /* 2 */ EN_TALK_GIBUD_LIMB_LEFT_LEG_ROOT, + /* 3 */ EN_TALK_GIBUD_LIMB_LEFT_THIGH, + /* 4 */ EN_TALK_GIBUD_LIMB_LEFT_LOWER_LEG, + /* 5 */ EN_TALK_GIBUD_LIMB_LEFT_FOOT_ROOT, + /* 6 */ EN_TALK_GIBUD_LIMB_LEFT_FOOT, + /* 7 */ EN_TALK_GIBUD_LIMB_RIGHT_LEG_ROOT, + /* 8 */ EN_TALK_GIBUD_LIMB_RIGHT_THIGH, + /* 9 */ EN_TALK_GIBUD_LIMB_RIGHT_LOWER_LEG, + /* 10 */ EN_TALK_GIBUD_LIMB_RIGHT_FOOT_ROOT, + /* 11 */ EN_TALK_GIBUD_LIMB_RIGHT_FOOT, + /* 12 */ EN_TALK_GIBUD_LIMB_UPPER_BODY_ROOT, + /* 13 */ EN_TALK_GIBUD_LIMB_UPPER_BODY, // Root of Torso + /* 14 */ EN_TALK_GIBUD_LIMB_TORSO, // Root of Left Arm Root, Right Arm Root, and Head Root + /* 15 */ EN_TALK_GIBUD_LIMB_LEFT_ARM_ROOT, + /* 16 */ EN_TALK_GIBUD_LIMB_LEFT_SHOULDER_AND_UPPER_ARM, + /* 17 */ EN_TALK_GIBUD_LIMB_LEFT_FOREARM, + /* 18 */ EN_TALK_GIBUD_LIMB_LEFT_HAND, + /* 19 */ EN_TALK_GIBUD_LIMB_RIGHT_ARM_ROOT, + /* 20 */ EN_TALK_GIBUD_LIMB_RIGHT_SHOULDER_AND_UPPER_ARM, + /* 21 */ EN_TALK_GIBUD_LIMB_RIGHT_FOREARM, + /* 22 */ EN_TALK_GIBUD_LIMB_RIGHT_HAND, + /* 23 */ EN_TALK_GIBUD_LIMB_HEAD_ROOT, + /* 24 */ EN_TALK_GIBUD_LIMB_HEAD, + /* 25 */ EN_TALK_GIBUD_LIMB_PELVIS, + /* 26 */ EN_TALK_GIBUD_LIMB_MAX, +} EnTalkGibudLimbs; + struct EnTalkGibud; typedef void (*EnTalkGibudActionFunc)(struct EnTalkGibud*, GlobalContext*); typedef struct EnTalkGibud { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x90]; - /* 0x01D4 */ EnTalkGibudActionFunc actionFunc; - /* 0x01D8 */ char unk_1D8[0x220]; + /* 0x000 */ Actor actor; + /* 0x144 */ ColliderCylinder collider; + /* 0x190 */ SkelAnime skelAnime; + /* 0x1D4 */ EnTalkGibudActionFunc actionFunc; + /* 0x1D8 */ Vec3f limbPos[15]; + /* 0x28C */ s32 limbIndex; + /* 0x290 */ s32 requestedItemIndex; + /* 0x294 */ s32 itemActionParam; + /* 0x298 */ s32 switchFlag; + /* 0x29C */ f32 effectAlpha; + /* 0x2A0 */ f32 effectScale; + /* 0x2A4 */ Vec3s jointTable[EN_TALK_GIBUD_LIMB_MAX]; + /* 0x340 */ Vec3s morphTable[EN_TALK_GIBUD_LIMB_MAX]; + /* 0x3DC */ s16 textId; + /* 0x3DE */ Vec3s headRotation; + /* 0x3E4 */ Vec3s upperBodyRotation; + /* 0x3EA */ union { + s16 playerStunWaitTimer; // Cannot stun the player if this is non-zero + s16 grabDamageTimer; + s16 headShakeTimer; + s16 stunTimer; + s16 deathTimer; + s16 disappearanceTimer; + }; + /* 0x3EC */ s16 grabState; + /* 0x3EE */ s16 grabWaitTimer; // Cannot grab the player if this is non-zero + /* 0x3F0 */ s16 effectTimer; + /* 0x3F2 */ s16 type; + /* 0x3F4 */ s16 isTalking; + /* 0x3F6 */ u8 effectType; + /* 0x3F7 */ s8 unk_3F7; // related to player->unk_ADD } EnTalkGibud; // size = 0x3F8 extern const ActorInit En_Talk_Gibud_InitVars; diff --git a/src/overlays/actors/ovl_En_Tanron2/z_en_tanron2.h b/src/overlays/actors/ovl_En_Tanron2/z_en_tanron2.h index 22dd08e89..5e9512c7c 100644 --- a/src/overlays/actors/ovl_En_Tanron2/z_en_tanron2.h +++ b/src/overlays/actors/ovl_En_Tanron2/z_en_tanron2.h @@ -10,7 +10,7 @@ typedef void (*EnTanron2ActionFunc)(struct EnTanron2*, GlobalContext*); typedef struct EnTanron2 { /* 0x0000 */ Actor actor; /* 0x0144 */ EnTanron2ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0xB4]; + /* 0x0148 */ char unk_148[0xB4]; } EnTanron2; // size = 0x1FC extern const ActorInit En_Tanron2_InitVars; diff --git a/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.c b/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.c index 2de774191..313a0a1fd 100644 --- a/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.c +++ b/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.c @@ -1,10 +1,11 @@ /* * File: z_en_tanron3.c * Overlay: ovl_En_Tanron3 - * Description: Small Fish summoned by Gyorg + * Description: Small fish summoned by Gyorg */ #include "z_en_tanron3.h" +#include "overlays/actors/ovl_Boss_03/z_boss_03.h" #define FLAGS 0x00000035 @@ -15,7 +16,14 @@ void EnTanron3_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnTanron3_Update(Actor* thisx, GlobalContext* globalCtx); void EnTanron3_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void EnTanron3_SetupLive(EnTanron3* this, GlobalContext* globalCtx); +void EnTanron3_Live(EnTanron3* this, GlobalContext* globalCtx); +void EnTanron3_Die(EnTanron3* this, GlobalContext* globalCtx); + +static Vec3f sZeroVec[] = { 0.0f, 0.0f, 0.0f }; + +static Boss03* sGyorg = NULL; + const ActorInit En_Tanron3_InitVars = { ACTOR_EN_TANRON3, ACTORCAT_BOSS, @@ -28,39 +36,419 @@ const ActorInit En_Tanron3_InitVars = { (ActorFunc)EnTanron3_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80BB9750 = { - { COLTYPE_HIT3, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK3, { 0xF7CFFFFF, 0x00, 0x02 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_HIT3, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x02 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 7, 10, -5, { 0, 0, 0 } }, }; -#endif +// This actor has two colliders (one for AC and one for AT), but uses the same +// ColliderCylinderInit for both of them, leaving this one totally unused. +static ColliderCylinderInit sUnusedCylinderInit = { + { + COLTYPE_HIT3, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK3, + { 0xF7CFFFFF, 0x00, 0x02 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, + { 20, 20, -10, { 0, 0, 0 } }, +}; -extern ColliderCylinderInit D_80BB9750; +extern FlexSkeletonHeader D_0600DA20; +extern AnimationHeader D_0600DAAC; -extern UNK_TYPE D_0600DAAC; +void EnTanron3_CreateEffect(GlobalContext* globalCtx, Vec3f* effectPos) { + UnkTanron3Effect* effectPtr = (UnkTanron3Effect*)globalCtx->specialEffects; + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/func_80BB85A0.s") + for (i = 0; i < 150; i++, effectPtr++) { + if ((effectPtr->type == 0) || (effectPtr->type == 1)) { + effectPtr->type = 2; + effectPtr->pos = *effectPos; + effectPtr->velocity = *sZeroVec; + effectPtr->accel = *sZeroVec; + effectPtr->accel.y = -2.0f; + effectPtr->unk_34.x = 0.1f; + effectPtr->unk_34.y = 0.0f; + effectPtr->unk_34.z = Rand_ZeroFloat(2 * M_PI); + effectPtr->unk_02 = Rand_ZeroFloat(100.0f); + effectPtr->velocity.x = randPlusMinusPoint5Scaled(25.0f); + effectPtr->velocity.z = randPlusMinusPoint5Scaled(25.0f); + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/EnTanron3_Init.s") +void EnTanron3_Init(Actor* thisx, GlobalContext* globalCtx) { + EnTanron3* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/EnTanron3_Destroy.s") + this->actor.gravity = -1.0f; + Collider_InitAndSetCylinder(globalCtx, &this->atCollider, &this->actor, &sCylinderInit); + Collider_InitAndSetCylinder(globalCtx, &this->acCollider, &this->actor, &sCylinderInit); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600DA20, &D_0600DAAC, this->jointTable, this->morphTable, 10); + Actor_SetScale(&this->actor, 0.02f); + EnTanron3_SetupLive(this, globalCtx); + this->actor.flags &= ~1; + this->currentRotationAngle = Rand_ZeroFloat(500000.0f); + this->waterSurfaceYPos = 430.0f; + sGyorg = (Boss03*)this->actor.parent; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/func_80BB87D4.s") +void EnTanron3_Destroy(Actor* thisx, GlobalContext* globalCtx) { + sGyorg->unk_252--; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/func_80BB897C.s") +void EnTanron3_SpawnBubbles(EnTanron3* this, GlobalContext* globalCtx) { + static Color_RGBA8 sPrimColor = { 100, 55, 55, 255 }; + static Color_RGBA8 sEnvColor = { 50, 10, 10, 255 }; + s32 i; + Vec3f velocity; + Vec3f acceleration; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/func_80BB8A48.s") + for (i = 0; i < 20; i++) { + Matrix_InsertYRotation_f(Rand_ZeroFloat(2 * M_PI), MTXMODE_NEW); + Matrix_RotateStateAroundXAxis(Rand_ZeroFloat(2 * M_PI)); + Matrix_GetStateTranslationAndScaledZ(Rand_ZeroFloat(3.0f) + 2.0f, &velocity); + acceleration.x = velocity.x * -0.05f; + acceleration.y = velocity.y * -0.05f; + acceleration.z = velocity.z * -0.05f; + EffectSsDtBubble_SpawnCustomColor(globalCtx, &this->actor.world.pos, &velocity, &acceleration, &sPrimColor, + &sEnvColor, Rand_ZeroFloat(30.0f) + 70.0f, Rand_ZeroFloat(5.0f) + 15.0f, 0); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/func_80BB91D4.s") +void EnTanron3_SetupLive(EnTanron3* this, GlobalContext* globalCtx) { + this->actionFunc = EnTanron3_Live; + Animation_MorphToLoop(&this->skelAnime, &D_0600DAAC, -10.0f); + this->rotationStep = 0; + this->rotationScale = 5; + this->workTimer[TANRON3_WORK_TIMER_PICK_NEW_DEVIATION] = 50; + this->actor.speedXZ = 5.0f; + this->speedMaxStep = 0.5f; + this->deviation.x = randPlusMinusPoint5Scaled(500.0f); + this->deviation.y = randPlusMinusPoint5Scaled(100.0f); + this->deviation.z = randPlusMinusPoint5Scaled(500.0f); + Math_Vec3f_Copy(&this->targetPos, &this->actor.world.pos); + this->timer = Rand_ZeroFloat(100.0f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/func_80BB9288.s") +/** + * This controls the vast majority of the fish's behavior while it's alive, including: + * - deciding whether to be hostile or not + * - determing whether the fish is beached or not + * - swimming towards the player to attack them + * - swimming around idly if the player is out of range + * - flopping around on land if it beaches itself + */ +void EnTanron3_Live(EnTanron3* this, GlobalContext* globalCtx) { + s32 atanTemp; + f32 xDistance; + f32 yDistance; + f32 zDistance; + f32 xzDistance; + f32 extraScaleY = 0.0f; + Player* player = GET_PLAYER(globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/func_80BB9308.s") + this->skelAnime.curFrame = 4.0f; + if ((player->actor.bgCheckFlags & 1) && player->actor.shape.feetPos[0].y >= 438.0f) { + // Player is standing on the central platform, so stop chasing them + this->isNonHostile = true; + } else if (this->isNonHostile && this->workTimer[TANRON3_WORK_TIMER_WAIT] == 0 && !(this->timer & 0x1F)) { + xDistance = this->targetPos.x - player->actor.world.pos.x; + zDistance = this->targetPos.z - player->actor.world.pos.z; + if (sqrtf(SQ(xDistance) + SQ(zDistance)) < 500.0f) { + // Player is in the water and close enough, so start chasing them + this->isNonHostile = false; + this->workTimer[TANRON3_WORK_TIMER_ATTACK] = 150; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/EnTanron3_Update.s") + if (this->actor.world.pos.y < this->waterSurfaceYPos) { + // The fish is below the water's surface, so it's no longer beached if it was before + this->isBeached = false; + switch (this->isNonHostile) { + case false: + this->targetSpeedXZ = 5.0f; + this->targetRotationStep = 0x1000; + this->nextRotationAngle = 0x3A98; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/func_80BB95FC.s") + Math_Vec3f_Copy(&this->targetPos, &player->actor.world.pos); + if (!(this->timer & 0xF)) { + if (Rand_ZeroOne() < 0.5f && this->actor.xzDistToPlayer <= 200.0f) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_PIRANHA_ATTACK); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tanron3/EnTanron3_Draw.s") + // If the player gets eaten by Gyorg, or if the attack timer ran out, + // stop chasing the player for a little bit. + if (this->workTimer[TANRON3_WORK_TIMER_ATTACK] == 0 || (player->stateFlags2 & 0x80)) { + this->workTimer[TANRON3_WORK_TIMER_WAIT] = 150; + this->isNonHostile = true; + } + break; + case true: + if (sGyorg->unk_324 != 0 && !(this->timer & 0x7)) { + this->nextRotationAngle = 0x4E20; + this->actor.speedXZ = 6.0f; + } else { + this->nextRotationAngle = 0x1F40; + } + this->targetRotationStep = 0x200; + this->targetSpeedXZ = 2.0f; + + // If the fish is idly swimming around, this code will make it spin in a circle. + // Its target is constantly updated, so it constantly rotates to face it, and its + // momentum keeps it spinning. This code can also be reached when the fish "give up" + // on attacking the player; in that case, this code will make it turn in the + // opposite direction and swim away. In both cases, the fish's target y-position + // will be slightly above the halfway point of the water. + atanTemp = Math_FAtan2F(this->targetPos.z, this->targetPos.x); + Matrix_RotateY(atanTemp, MTXMODE_NEW); + Matrix_GetStateTranslationAndScaledZ(700.0f, &this->targetPos); + this->targetPos.y = 250.0f; + + extraScaleY = 150.0f; + break; + } + + if (this->workTimer[TANRON3_WORK_TIMER_OUT_OF_WATER] == 0) { + if (this->workTimer[TANRON3_WORK_TIMER_PICK_NEW_DEVIATION] == 0 && this->actor.speedXZ > 1.0f) { + this->workTimer[TANRON3_WORK_TIMER_PICK_NEW_DEVIATION] = Rand_ZeroFloat(20.0f); + this->deviation.x = randPlusMinusPoint5Scaled(100.0f); + this->deviation.y = randPlusMinusPoint5Scaled(50.0f + extraScaleY); + this->deviation.z = randPlusMinusPoint5Scaled(100.0f); + } + this->targetPosWithDeviation.y = this->targetPos.y + this->deviation.y + 50.0f; + } + + this->targetPosWithDeviation.x = this->targetPos.x + this->deviation.x; + this->targetPosWithDeviation.z = this->targetPos.z + this->deviation.z; + xDistance = this->targetPosWithDeviation.x - this->actor.world.pos.x; + yDistance = this->targetPosWithDeviation.y - this->actor.world.pos.y; + zDistance = this->targetPosWithDeviation.z - this->actor.world.pos.z; + + // Rotate the fish to look towards its target + xzDistance = sqrtf(SQ(xDistance) + SQ(zDistance)); + atanTemp = Math_FAtan2F(xzDistance, -yDistance); + Math_ApproachS(&this->actor.world.rot.x, atanTemp, this->rotationScale, this->rotationStep); + atanTemp = Math_FAtan2F(zDistance, xDistance); + Math_SmoothStepToS(&this->actor.world.rot.y, atanTemp, this->rotationScale, this->rotationStep, 0); + Math_ApproachS(&this->rotationStep, this->targetRotationStep, 1, 0x100); + + Math_ApproachF(&this->actor.speedXZ, this->targetSpeedXZ, 1.0f, this->speedMaxStep); + Actor_SetVelocityAndMoveXYRotationReverse(&this->actor); + } else { + switch (this->isBeached) { + case false: + // Fish is above water but hasn't touched land before + this->actor.gravity = -1.0f; + this->targetPosWithDeviation.y = this->waterSurfaceYPos - 50.0f; + this->workTimer[TANRON3_WORK_TIMER_OUT_OF_WATER] = 25; + Math_ApproachS(&this->actor.world.rot.x, 0x3000, 5, 0xBD0); + if (this->actor.bgCheckFlags & 8) { + this->actor.speedXZ = 0.0f; + if (this->actor.velocity.y > 0.0f) { + this->actor.velocity.y = -1.0f; + } + } + if (this->actor.bgCheckFlags & 1) { + // Fish has touched land + this->isBeached = true; + } + break; + case true: + this->nextRotationAngle = 0x3A98; + this->actor.gravity = -1.5f; + if (this->actor.bgCheckFlags & 1) { + // Fish is still touching land, so it's still beached. Randomly flop around + this->actor.velocity.y = Rand_ZeroFloat(5.0f) + 5.0f; + this->actor.speedXZ = Rand_ZeroFloat(2.0f) + 2.0f; + if (Rand_ZeroOne() < 0.5f) { + this->targetShapeRotation.x = + (s16)randPlusMinusPoint5Scaled(500.0f) + this->targetShapeRotation.x + 0x8000; + } + if (Rand_ZeroOne() < 0.5f) { + this->targetShapeRotation.z = + (s16)randPlusMinusPoint5Scaled(500.0f) + this->targetShapeRotation.z + 0x8000; + } + if (Rand_ZeroOne() < 0.5f) { + this->targetShapeRotation.y = (s16)Rand_ZeroFloat(0x10000); + } + this->actor.world.rot.y = Math_FAtan2F(this->actor.world.pos.z, this->actor.world.pos.x) + + (s16)randPlusMinusPoint5Scaled(0xCE20); + } + + Math_ApproachS(&this->actor.shape.rot.y, this->targetShapeRotation.y, 3, 0x500); + Math_ApproachS(&this->actor.shape.rot.x, this->targetShapeRotation.x, 3, 0xC00); + Math_ApproachS(&this->actor.shape.rot.z, this->targetShapeRotation.z, 3, 0xC00); + if ((Rand_ZeroOne() < 0.5f) & !(this->timer & 0x3)) { + Vec3f effectPos; + + effectPos.x = randPlusMinusPoint5Scaled(30.0f) + this->actor.world.pos.x; + effectPos.y = this->actor.world.pos.y; + effectPos.z = randPlusMinusPoint5Scaled(30.0f) + this->actor.world.pos.z; + EnTanron3_CreateEffect(globalCtx, &effectPos); + } + break; + } + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + } + + this->currentRotationAngle += this->nextRotationAngle; + this->trunkRotation = Math_SinS(this->currentRotationAngle) * 5000.0f; + this->bodyRotation = Math_SinS(this->currentRotationAngle + 0x6978) * 5000.0f; + this->tailRotation = Math_SinS(this->currentRotationAngle) * 5000.0f; + if (!this->isBeached) { + this->actor.shape.rot = this->actor.world.rot; + } +} + +void EnTanron3_SetupDie(EnTanron3* this, GlobalContext* globalCtx) { + f32 xDistance; + f32 yDistance; + f32 zDistance; + Player* player = GET_PLAYER(globalCtx); + + this->actionFunc = EnTanron3_Die; + xDistance = this->actor.world.pos.x - player->actor.world.pos.x; + yDistance = this->actor.world.pos.y - player->actor.world.pos.y + 30.0f; + zDistance = this->actor.world.pos.z - player->actor.world.pos.z; + this->actor.world.rot.x = Math_FAtan2F(sqrtf(SQ(xDistance) + SQ(zDistance)), -yDistance); + this->actor.world.rot.y = Math_FAtan2F(zDistance, xDistance); + this->workTimer[TANRON3_WORK_TIMER_DIE] = 6; + this->actor.speedXZ = 10.0f; + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KONB_MINI_DEAD); +} + +void EnTanron3_Die(EnTanron3* this, GlobalContext* globalCtx) { + Actor_SetVelocityAndMoveXYRotationReverse(&this->actor); + if (this->workTimer[TANRON3_WORK_TIMER_DIE] == 0) { + EnTanron3_SpawnBubbles(this, globalCtx); + Actor_MarkForDeath(&this->actor); + if (Rand_ZeroOne() < 0.3f) { + Item_DropCollectibleRandom(globalCtx, NULL, &this->actor.world.pos, 0x60); + } + } +} + +void EnTanron3_CheckCollisions(EnTanron3* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (player->actor.world.pos.y > 350.0f) { + if (this->atCollider.base.atFlags & AT_HIT) { + this->atCollider.base.atFlags &= ~AT_HIT; + func_800B8D50(globalCtx, NULL, 3.0f, Math_FAtan2F(-player->actor.world.pos.z, -player->actor.world.pos.x), + 5.0f, 0); + } + } + if (this->acCollider.base.acFlags & AC_HIT) { + this->acCollider.base.acFlags &= ~AC_HIT; + if (this->deathTimer == 0) { + this->deathTimer = 15; + this->fogTimer = 15; + EnTanron3_SetupDie(this, globalCtx); + sGyorg->unk_324 = 20; + } + } +} + +void EnTanron3_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnTanron3* this = THIS; + s16 i; + Vec3f splashPos; + + if (KREG(63) == 0) { + this->timer++; + + for (i = 0; i < TANRON3_WORK_TIMER_MAX; i++) { + if (this->workTimer[i] != 0) { + this->workTimer[i]--; + } + } + if (this->deathTimer != 0) { + this->deathTimer--; + } + if (this->fogTimer != 0) { + this->fogTimer--; + } + + this->actionFunc(this, globalCtx); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 10.0f, 20.0f, 5); + + // The fish has either just entered or just exited the water, so create a splash effect + if (((this->actor.prevPos.y < this->waterSurfaceYPos) && (this->waterSurfaceYPos <= this->actor.world.pos.y)) || + ((this->actor.prevPos.y > this->waterSurfaceYPos) && (this->waterSurfaceYPos >= this->actor.world.pos.y))) { + splashPos.x = this->actor.world.pos.x; + splashPos.y = this->waterSurfaceYPos + 10.0f; + splashPos.z = this->actor.world.pos.z; + EffectSsGSplash_Spawn(globalCtx, &splashPos, NULL, NULL, 1, 500); + Audio_PlayActorSound2(&this->actor, NA_SE_EV_OUT_OF_WATER); + } + } + + EnTanron3_CheckCollisions(this, globalCtx); + Collider_UpdateCylinder(&this->actor, &this->atCollider); + Collider_UpdateCylinder(&this->actor, &this->acCollider); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->atCollider.base); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->acCollider.base); + + if ((s8)sGyorg->actor.colChkInfo.health <= 0 && this->actionFunc != EnTanron3_Die) { + EnTanron3_SetupDie(this, globalCtx); + this->workTimer[TANRON3_WORK_TIMER_DIE] = 0; + } +} + +s32 EnTanron3_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, + Actor* thisx) { + EnTanron3* this = THIS; + + if (limbIndex == 1) { + rot->y += this->bodyRotation; + } + if (limbIndex == 3) { + rot->y += this->tailRotation; + } + if (limbIndex == 4) { + rot->y += this->trunkRotation; + } + return false; +} + +void EnTanron3_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnTanron3* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + func_8012C28C(globalCtx->state.gfxCtx); + if ((this->fogTimer % 2) != 0) { + POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 255, 0, 0, 255, 900, 1099); + } + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnTanron3_OverrideLimbDraw, NULL, &this->actor); + POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP); + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.h b/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.h index 885d65af9..9a2cb25da 100644 --- a/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.h +++ b/src/overlays/actors/ovl_En_Tanron3/z_en_tanron3.h @@ -7,10 +7,53 @@ struct EnTanron3; typedef void (*EnTanron3ActionFunc)(struct EnTanron3*, GlobalContext*); +#define TANRON3_WORK_TIMER_PICK_NEW_DEVIATION 0 +#define TANRON3_WORK_TIMER_DIE 0 +#define TANRON3_WORK_TIMER_OUT_OF_WATER 1 +#define TANRON3_WORK_TIMER_ATTACK 2 +#define TANRON3_WORK_TIMER_WAIT 2 +#define TANRON3_WORK_TIMER_MAX 3 + +typedef struct { + /* 0x00 */ u8 type; + /* 0x02 */ s16 unk_02; + /* 0x04 */ Vec3f pos; + /* 0x10 */ Vec3f velocity; + /* 0x1C */ Vec3f accel; + /* 0x28 */ char unk_28[0xC]; + /* 0x34 */ Vec3f unk_34; + /* 0x40 */ char unk_40[0x4]; +} UnkTanron3Effect; + typedef struct EnTanron3 { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1B4]; - /* 0x02F8 */ EnTanron3ActionFunc actionFunc; + /* 0x000 */ Actor actor; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ Vec3s jointTable[10]; + /* 0x1C4 */ Vec3s morphTable[10]; + /* 0x200 */ s16 timer; + /* 0x202 */ u8 isNonHostile; // If true, the fish will not move towards the player to attack them + /* 0x203 */ u8 isBeached; // If true, the fish is on the central platform flopping around + /* 0x204 */ s16 workTimer[TANRON3_WORK_TIMER_MAX]; + /* 0x20A */ s16 deathTimer; + /* 0x20C */ s16 fogTimer; + /* 0x210 */ Vec3f targetPosWithDeviation; // The destination that the fish actually ends up moving towards + /* 0x21C */ Vec3f targetPos; // The exact destination where the fish wants to be located + /* 0x228 */ Vec3f deviation; // A random amount of "noise" added to targetPos + /* 0x234 */ s16 rotationStep; + /* 0x236 */ s16 targetRotationStep; + /* 0x238 */ s16 rotationScale; + /* 0x23C */ f32 targetSpeedXZ; + /* 0x240 */ f32 speedMaxStep; + /* 0x244 */ f32 waterSurfaceYPos; + /* 0x248 */ Vec3s targetShapeRotation; + /* 0x250 */ s32 currentRotationAngle; + /* 0x254 */ s32 nextRotationAngle; + /* 0x258 */ s16 tailRotation; + /* 0x25A */ s16 trunkRotation; + /* 0x25C */ s16 bodyRotation; + /* 0x260 */ ColliderCylinder atCollider; + /* 0x2AC */ ColliderCylinder acCollider; + /* 0x2F8 */ EnTanron3ActionFunc actionFunc; } EnTanron3; // size = 0x2FC extern const ActorInit En_Tanron3_InitVars; diff --git a/src/overlays/actors/ovl_En_Test/z_en_test.c b/src/overlays/actors/ovl_En_Test/z_en_test.c index 516cf8258..2f13b6640 100644 --- a/src/overlays/actors/ovl_En_Test/z_en_test.c +++ b/src/overlays/actors/ovl_En_Test/z_en_test.c @@ -1,7 +1,7 @@ /* * File: z_en_test.c * Overlay: ovl_En_Test - * Description: + * Description: Various crater marks (e.g., Goron Link punch/pound, Moon's Tear crash, etc.) */ #include "z_en_test.h" diff --git a/src/overlays/actors/ovl_En_Test4/z_en_test4.c b/src/overlays/actors/ovl_En_Test4/z_en_test4.c index e872cc98a..9e1417c84 100644 --- a/src/overlays/actors/ovl_En_Test4/z_en_test4.c +++ b/src/overlays/actors/ovl_En_Test4/z_en_test4.c @@ -1,7 +1,7 @@ /* * File: z_en_test4.c * Overlay: ovl_En_Test4 - * Description: Day transition effects + * Description: Three-Day Timer */ #include "z_en_test4.h" diff --git a/src/overlays/actors/ovl_En_Test5/z_en_test5.c b/src/overlays/actors/ovl_En_Test5/z_en_test5.c index 69d550c8a..f1ec4e817 100644 --- a/src/overlays/actors/ovl_En_Test5/z_en_test5.c +++ b/src/overlays/actors/ovl_En_Test5/z_en_test5.c @@ -1,7 +1,7 @@ /* * File: z_en_test5.c * Overlay: ovl_En_Test5 - * Description: Spring Water + * Description: Spring Water Modifier */ #include "z_en_test5.h" @@ -13,12 +13,9 @@ void EnTest5_Init(Actor* thisx, GlobalContext* globalCtx); void EnTest5_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnTest5_Update(Actor* thisx, GlobalContext* globalCtx); - -void func_80A90478(EnTest5* this, GlobalContext* globalCtx); - +void EnTest5_HandleBottleAction(EnTest5* this, GlobalContext* globalCtx); void EnTest5_SetupAction(EnTest5* this, EnTest5ActionFunc actionFunc); -#if 0 const ActorInit En_Test5_InitVars = { ACTOR_EN_TEST5, ACTORCAT_ITEMACTION, @@ -31,14 +28,82 @@ const ActorInit En_Test5_InitVars = { (ActorFunc)NULL, }; -#endif +void EnTest5_SetupAction(EnTest5* this, EnTest5ActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test5/EnTest5_SetupAction.s") +void EnTest5_Init(Actor* thisx, GlobalContext* globalCtx2) { + EnTest5* this = THIS; + GlobalContext* globalCtx = globalCtx2; + WaterBox* water; + f32 ySurface; // Unused -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test5/EnTest5_Init.s") + // If not spawned above a water source, immediately despawn + if (!WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, this->actor.world.pos.x, this->actor.world.pos.z, + &ySurface, &water)) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test5/EnTest5_Destroy.s") + Math_Vec3s_ToVec3f(&this->minPos, &water->minPos); + this->xLength = (f32)water->xLength; + this->zLength = (f32)water->zLength; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test5/func_80A90478.s") + EnTest5_SetupAction(this, EnTest5_HandleBottleAction); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Test5/EnTest5_Update.s") +void EnTest5_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +void EnTest5_HandleBottleAction(EnTest5* this, GlobalContext* globalCtx) { + Player* player; + Vec3f playerPosRelativeToWater; + + if (Actor_HasParent(&this->actor, globalCtx)) { + this->actor.parent = NULL; + return; + } + + player = GET_PLAYER(globalCtx); + + if (player->unk_388 == NULL || player->unk_384 != GI_MAX) { + Math_Vec3f_DistXYZAndStoreDiff(&this->minPos, &player->actor.world.pos, &playerPosRelativeToWater); + + // Make sure that the player is within the bounds of the water and deep enough to grab some + if (playerPosRelativeToWater.x >= 0.0f && playerPosRelativeToWater.x <= this->xLength && + playerPosRelativeToWater.z >= 0.0f && playerPosRelativeToWater.z <= this->zLength && + fabsf(playerPosRelativeToWater.y) < 100.0f && player->actor.depthInWater > 12.0f) { + func_800B8A1C(&this->actor, globalCtx, GI_MAX, this->actor.xzDistToPlayer, + fabsf(this->actor.playerHeightRel)); + } + } +} + +void EnTest5_Update(Actor* thisx, GlobalContext* globalCtx2) { + EnTest5* this = THIS; + GlobalContext* globalCtx = globalCtx2; + Vec3f steamPos; + CollisionPoly* poly; // Unused + s32 pad; // Unused + + this->actionFunc(this, globalCtx); + + // If it's the hot spring variant, generate steam clouds + if (ENTEST5_IS_HOT_SPRING(&this->actor) && (globalCtx->state.frames % 4) == 0) { + steamPos.x = (Rand_ZeroOne() * this->xLength) + this->minPos.x; + steamPos.y = this->minPos.y + 100.0f; + steamPos.z = (Rand_ZeroOne() * this->zLength) + this->minPos.z; + + if ((BgCheck_EntityRaycastFloor2(globalCtx, &globalCtx->colCtx, &poly, &steamPos) + 10.0f) < this->minPos.y) { + Vec3f steamVel; + + steamPos.y = this->minPos.y + 10.0f; + steamVel.y = 0.5f; + steamVel.x = 0.0f; + steamVel.z = 0.0f; + + EffectSsIceSmoke_Spawn(globalCtx, &steamPos, &steamVel, &gZeroVec3f, + (s16)((-200) - (s32)(Rand_ZeroOne() * 50.0f))); + } + } +} diff --git a/src/overlays/actors/ovl_En_Test5/z_en_test5.h b/src/overlays/actors/ovl_En_Test5/z_en_test5.h index 79ea87356..539f5b3c2 100644 --- a/src/overlays/actors/ovl_En_Test5/z_en_test5.h +++ b/src/overlays/actors/ovl_En_Test5/z_en_test5.h @@ -3,14 +3,18 @@ #include "global.h" -struct EnTest5; +#define ENTEST5_IS_HOT_SPRING(thisx) ((thisx)->params != 0) + +struct EnTest5; // SpringWaterModifier typedef void (*EnTest5ActionFunc)(struct EnTest5*, GlobalContext*); typedef struct EnTest5 { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x14]; - /* 0x0158 */ EnTest5ActionFunc actionFunc; + /* 0x0144 */ Vec3f minPos; + /* 0x0150 */ f32 xLength; + /* 0x0154 */ f32 zLength; + /* 0x0158 */ EnTest5ActionFunc actionFunc; } EnTest5; // size = 0x15C extern const ActorInit En_Test5_InitVars; diff --git a/src/overlays/actors/ovl_En_Test6/z_en_test6.c b/src/overlays/actors/ovl_En_Test6/z_en_test6.c index 918a503f4..04365b5dd 100644 --- a/src/overlays/actors/ovl_En_Test6/z_en_test6.c +++ b/src/overlays/actors/ovl_En_Test6/z_en_test6.c @@ -1,7 +1,7 @@ /* * File: z_en_test6.c * Overlay: ovl_En_Test6 - * Description: + * Description: Song of Time effects (Return to DotFD, invert, skip forward) */ #include "z_en_test6.h" diff --git a/src/overlays/actors/ovl_En_Test6/z_en_test6.h b/src/overlays/actors/ovl_En_Test6/z_en_test6.h index 94f255622..9cee7cf1d 100644 --- a/src/overlays/actors/ovl_En_Test6/z_en_test6.h +++ b/src/overlays/actors/ovl_En_Test6/z_en_test6.h @@ -10,7 +10,7 @@ typedef void (*EnTest6ActionFunc)(struct EnTest6*, GlobalContext*); typedef struct EnTest6 { /* 0x0000 */ Actor actor; /* 0x0144 */ EnTest6ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x140]; + /* 0x0148 */ char unk_148[0x140]; } EnTest6; // size = 0x288 extern const ActorInit En_Test6_InitVars; diff --git a/src/overlays/actors/ovl_En_Test7/z_en_test7.c b/src/overlays/actors/ovl_En_Test7/z_en_test7.c index a5bca6c56..81ab55e27 100644 --- a/src/overlays/actors/ovl_En_Test7/z_en_test7.c +++ b/src/overlays/actors/ovl_En_Test7/z_en_test7.c @@ -1,7 +1,7 @@ /* * File: z_en_test7.c * Overlay: ovl_En_Test7 - * Description: + * Description: Soaring effects (wings, sphere, etc) */ #include "z_en_test7.h" diff --git a/src/overlays/actors/ovl_En_Tg/z_en_tg.h b/src/overlays/actors/ovl_En_Tg/z_en_tg.h index 706618774..de0c6fd2e 100644 --- a/src/overlays/actors/ovl_En_Tg/z_en_tg.h +++ b/src/overlays/actors/ovl_En_Tg/z_en_tg.h @@ -10,7 +10,7 @@ typedef void (*EnTgActionFunc)(struct EnTg*, GlobalContext*); typedef struct EnTg { /* 0x0000 */ Actor actor; /* 0x0144 */ EnTgActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x400]; + /* 0x0148 */ char unk_148[0x400]; } EnTg; // size = 0x548 extern const ActorInit En_Tg_InitVars; diff --git a/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c b/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c index 64374e36c..f2ae5333c 100644 --- a/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c +++ b/src/overlays/actors/ovl_En_Thiefbird/z_en_thiefbird.c @@ -401,12 +401,12 @@ s32 func_80C10E98(GlobalContext* globalCtx) { sp64.y = player->actor.world.pos.y + 20.0f; sp64.z = (Math_CosS(phi_s3) * 40.0f) + player->actor.world.pos.z; if (dropItem00Ids[i] != ITEM00_NO_DROP) { - EnItem00* temp_s1_5 = Item_DropCollectible(globalCtx, &sp64, dropItem00Ids[i]); + Actor* temp_s1_5 = Item_DropCollectible(globalCtx, &sp64, dropItem00Ids[i]); if (temp_s1_5 != NULL) { - temp_s1_5->actor.velocity.y = Rand_ZeroFloat(3.0f) + 6.0f; - temp_s1_5->actor.speedXZ = Rand_ZeroFloat(3.0f) + 3.0f; - temp_s1_5->actor.world.rot.y = phi_s3; + temp_s1_5->velocity.y = Rand_ZeroFloat(3.0f) + 6.0f; + temp_s1_5->speedXZ = Rand_ZeroFloat(3.0f) + 3.0f; + temp_s1_5->world.rot.y = phi_s3; } phi_s3 += (s16)(0x10000 / (spB0 + spAC + phi_s0_2 + spA0 + phi_s2 + spA8)); } @@ -429,7 +429,7 @@ void func_80C11338(EnThiefbird* this, GlobalContext* globalCtx) { this->unk_3EC = NULL; do { - item = (EnItem00*)func_ActorCategoryIterateById(globalCtx, &item->actor, ACTORCAT_MISC, ACTOR_EN_ITEM00); + item = (EnItem00*)SubS_FindActor(globalCtx, &item->actor, ACTORCAT_MISC, ACTOR_EN_ITEM00); if (item != NULL) { if (item->unk152 > 0) { if (Actor_XZDistanceBetweenActors(&player->actor, &item->actor) > 10.0f) { @@ -658,7 +658,7 @@ void func_80C11DF0(EnThiefbird* this, GlobalContext* globalCtx) { if ((this->actor.bgCheckFlags & 1) || (this->actor.floorHeight == BGCHECK_Y_MIN)) { for (i = 0; i < ARRAY_COUNT(this->unk_350); i++) { - func_800B3030(globalCtx, &this->unk_350[i], &D_801D15B0, &D_801D15B0, 0x8C, 0, 0); + func_800B3030(globalCtx, &this->unk_350[i], &gZeroVec3f, &gZeroVec3f, 0x8C, 0, 0); } Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 11, NA_SE_EN_EXTINCT); @@ -1078,7 +1078,7 @@ void EnThiefbird_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dLi OPEN_DISPS(globalCtx->state.gfxCtx); gfx = POLY_OPA_DISP; - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); gSPMatrix(&gfx[0], Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(&gfx[1], this->unk_3E4); POLY_OPA_DISP = &gfx[2]; @@ -1136,7 +1136,7 @@ void func_80C13354(EnThiefbird* this, GlobalContext* globalCtx2) { for (i = 0; i < ARRAY_COUNT(this->unk_3F0); i++, ptr++) { if (ptr->unk_22 != 0) { Matrix_InsertTranslation(ptr->unk_00.x, ptr->unk_00.y, ptr->unk_00.z, MTXMODE_NEW); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); Matrix_RotateY(ptr->unk_1E, MTXMODE_APPLY); Matrix_InsertZRotation_s(ptr->unk_20, MTXMODE_APPLY); Matrix_InsertTranslation(0.0f, -10.0f, 0.0f, MTXMODE_APPLY); diff --git a/src/overlays/actors/ovl_En_Tite/z_en_tite.c b/src/overlays/actors/ovl_En_Tite/z_en_tite.c index 61a12cfb0..bcf8547ef 100644 --- a/src/overlays/actors/ovl_En_Tite/z_en_tite.c +++ b/src/overlays/actors/ovl_En_Tite/z_en_tite.c @@ -266,7 +266,7 @@ void func_80893BCC(EnTite* this, GlobalContext* globalCtx) { sp7C.x = ptr->x + randPlusMinusPoint5Scaled(1.0f); sp7C.y = ptr->y + randPlusMinusPoint5Scaled(1.0f); sp7C.z = ptr->z + randPlusMinusPoint5Scaled(1.0f); - func_800B0DE0(globalCtx, &sp7C, &D_801D15B0, &D_80896B64, &D_80896B3C, &D_80896B40, + func_800B0DE0(globalCtx, &sp7C, &gZeroVec3f, &D_80896B64, &D_80896B3C, &D_80896B40, (s32)Rand_ZeroFloat(16.0f) + 80, 15); } } @@ -677,7 +677,7 @@ void func_808951B8(EnTite* this, GlobalContext* globalCtx) { if (this->unk_2BC == 0) { for (i = 0; i < ARRAY_COUNT(this->unk_2D0); i++) { - func_800B3030(globalCtx, &this->unk_2D0[i], &D_801D15B0, &D_801D15B0, 40, 7, 1); + func_800B3030(globalCtx, &this->unk_2D0[i], &gZeroVec3f, &gZeroVec3f, 40, 7, 1); Audio_PlaySoundAtPosition(globalCtx, &this->unk_2D0[i], 11, NA_SE_EN_EXTINCT); } Actor_MarkForDeath(&this->actor); @@ -816,7 +816,7 @@ void func_8089595C(EnTite* this, GlobalContext* globalCtx) { sp2C.x = randPlusMinusPoint5Scaled(20.0f) + this->actor.world.pos.x; sp2C.y = this->actor.world.pos.y + 15.0f; sp2C.z = randPlusMinusPoint5Scaled(20.0f) + this->actor.world.pos.z; - func_800B0DE0(globalCtx, &sp2C, &D_801D15B0, &D_80896B44, &D_80896B3C, &D_80896B40, 500, 50); + func_800B0DE0(globalCtx, &sp2C, &gZeroVec3f, &D_80896B44, &D_80896B3C, &D_80896B40, 500, 50); } void func_80895A10(EnTite* this) { diff --git a/src/overlays/actors/ovl_En_Tk/z_en_tk.c b/src/overlays/actors/ovl_En_Tk/z_en_tk.c index 07bf625d2..1792736d7 100644 --- a/src/overlays/actors/ovl_En_Tk/z_en_tk.c +++ b/src/overlays/actors/ovl_En_Tk/z_en_tk.c @@ -405,7 +405,7 @@ s32 func_80AECE60(EnTk* this, GlobalContext* globalCtx) { func_8013AF00(spA0, 3, this->unk_3C8->count + 3); if (!(this->unk_3CE & 4)) { - sp7C = D_801D15B0; + sp7C = gZeroVec3f; func_8013B6B0(this->unk_3C8, &this->unk_3E0, &this->unk_3F0, this->unk_3E8, this->unk_3E4, &this->unk_3EC, spA0, &sp7C, this->unk_3D0); func_8013B878(globalCtx, this->unk_3C8, this->unk_3EC, &sp7C); @@ -428,7 +428,7 @@ s32 func_80AECE60(EnTk* this, GlobalContext* globalCtx) { sp7C = this->actor.world.pos; } - this->unk_3D4 = D_801D15B0; + this->unk_3D4 = gZeroVec3f; if (func_8013B6B0(this->unk_3C8, &this->unk_3E0, &this->unk_3F0, this->unk_3E8, this->unk_3E4, &this->unk_3EC, spA0, &this->unk_3D4, this->unk_3D0)) { @@ -450,7 +450,7 @@ s32 func_80AECE60(EnTk* this, GlobalContext* globalCtx) { door1 = NULL; label: do { - door1 = func_ActorCategoryIterateById(globalCtx, door1, ACTORCAT_DOOR, ACTOR_EN_DOOR); + door1 = SubS_FindActor(globalCtx, door1, ACTORCAT_DOOR, ACTOR_EN_DOOR); if (door1 != NULL) { if (Actor_XZDistanceBetweenActors(&this->actor, door1) <= 120.0f) { if (ABS(BINANG_SUB(Actor_YawToPoint(&this->actor, &door1->world.pos), this->actor.shape.rot.y)) <= @@ -466,7 +466,7 @@ s32 func_80AECE60(EnTk* this, GlobalContext* globalCtx) { } else { door2 = NULL; do { - door2 = func_ActorCategoryIterateById(globalCtx, door2, ACTORCAT_DOOR, ACTOR_EN_DOOR); + door2 = SubS_FindActor(globalCtx, door2, ACTORCAT_DOOR, ACTOR_EN_DOOR); if (door2 != NULL) { if (Actor_XZDistanceBetweenActors(&this->actor, door2) <= 160.0f) { sp4C4 = (EnDoor*)door2; @@ -682,7 +682,7 @@ void func_80AED940(EnTk* this, GlobalContext* globalCtx) { actor = NULL; do { - actor = func_ActorCategoryIterateById(globalCtx, actor, ACTORCAT_NPC, ACTOR_EN_TK); + actor = SubS_FindActor(globalCtx, actor, ACTORCAT_NPC, ACTOR_EN_TK); if (actor != NULL) { if (ENTK_GET_F(actor) == 1) { Math_Vec3f_Copy(&this->unk_2EC, &actor->world.pos); @@ -933,7 +933,7 @@ void func_80AEE374(EnTk* this, GlobalContext* globalCtx) { sp30.unk_00 = NULL; sp30.unk_04 = FLT_MAX; - func_8013E640(globalCtx, &this->actor, NULL, ACTORCAT_NPC, ACTOR_EN_TK, &sp30, func_80AEE300); + SubS_FindActorCustom(globalCtx, &this->actor, NULL, ACTORCAT_NPC, ACTOR_EN_TK, &sp30, func_80AEE300); if (sp30.unk_00 == 0) { Actor_MarkForDeath(&this->actor); } else { @@ -971,7 +971,7 @@ void func_80AEE4D0(EnTk* this, GlobalContext* globalCtx) { if (Animation_OnFrame(&this->skelAnime, 37.0f)) { bigPoe = NULL; do { - bigPoe = func_ActorCategoryIterateById(globalCtx, bigPoe, ACTORCAT_PROP, ACTOR_EN_BIGPO); + bigPoe = SubS_FindActor(globalCtx, bigPoe, ACTORCAT_PROP, ACTOR_EN_BIGPO); if (bigPoe != NULL) { if ((bigPoe->params == 3) && (Actor_DistanceBetweenActors(&this->actor, bigPoe) < 80.0f)) { diff --git a/src/overlays/actors/ovl_En_Torch/z_en_torch.c b/src/overlays/actors/ovl_En_Torch/z_en_torch.c index 786942bcf..b5c891af0 100644 --- a/src/overlays/actors/ovl_En_Torch/z_en_torch.c +++ b/src/overlays/actors/ovl_En_Torch/z_en_torch.c @@ -1,7 +1,7 @@ /* * File: z_en_torch.c * Overlay: ovl_En_Torch - * Description: Treasure chest (grotto) + * Description: Grotto chest spawner */ #include "z_en_torch.h" diff --git a/src/overlays/actors/ovl_En_Trt/z_en_trt.c b/src/overlays/actors/ovl_En_Trt/z_en_trt.c index a03072c52..e6cd134b5 100644 --- a/src/overlays/actors/ovl_En_Trt/z_en_trt.c +++ b/src/overlays/actors/ovl_En_Trt/z_en_trt.c @@ -1712,11 +1712,11 @@ void EnTrt_UpdateHeadYawAndPitch(EnTrt* this, GlobalContext* globalCtx) { void EnTrt_UpdateHeadPosAndRot(s16 pitch, s16 yaw, Vec3f* pos, Vec3s* rot, s32 isFullyAwake) { Vec3f newPos; - Vec3f D_801D15B0tmp = D_801D15B0; + Vec3f zeroVec = gZeroVec3f; Vec3s newRot; MtxF currentState; - Matrix_MultiplyVector3fByState(&D_801D15B0tmp, &newPos); + Matrix_MultiplyVector3fByState(&zeroVec, &newPos); Matrix_CopyCurrentState(¤tState); func_8018219C(¤tState, &newRot, MTXMODE_NEW); *pos = newPos; diff --git a/src/overlays/actors/ovl_En_Trt2/z_en_trt2.c b/src/overlays/actors/ovl_En_Trt2/z_en_trt2.c index 9306f4cc8..e74a5dd4d 100644 --- a/src/overlays/actors/ovl_En_Trt2/z_en_trt2.c +++ b/src/overlays/actors/ovl_En_Trt2/z_en_trt2.c @@ -1,7 +1,7 @@ /* * File: z_en_trt2.c * Overlay: ovl_En_Trt2 - * Description: + * Description: Kotake in Southern Swamp and Woods of Mystery */ #include "z_en_trt2.h" diff --git a/src/overlays/actors/ovl_En_Trt2/z_en_trt2.h b/src/overlays/actors/ovl_En_Trt2/z_en_trt2.h index 69fb439fd..11320af0c 100644 --- a/src/overlays/actors/ovl_En_Trt2/z_en_trt2.h +++ b/src/overlays/actors/ovl_En_Trt2/z_en_trt2.h @@ -10,7 +10,7 @@ typedef void (*EnTrt2ActionFunc)(struct EnTrt2*, GlobalContext*); typedef struct EnTrt2 { /* 0x0000 */ Actor actor; /* 0x0144 */ EnTrt2ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x294]; + /* 0x0148 */ char unk_148[0x294]; } EnTrt2; // size = 0x3DC extern const ActorInit En_Trt2_InitVars; diff --git a/src/overlays/actors/ovl_En_Tru/z_en_tru.c b/src/overlays/actors/ovl_En_Tru/z_en_tru.c index 240a4f236..cbb31ebc3 100644 --- a/src/overlays/actors/ovl_En_Tru/z_en_tru.c +++ b/src/overlays/actors/ovl_En_Tru/z_en_tru.c @@ -5,6 +5,7 @@ */ #include "z_en_tru.h" +#include "objects/object_tru/object_tru.h" #define FLAGS 0x00000039 @@ -15,10 +16,46 @@ void EnTru_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnTru_Update(Actor* thisx, GlobalContext* globalCtx); void EnTru_Draw(Actor* thisx, GlobalContext* globalCtx); +s32 func_80A875AC(Actor* thisx, GlobalContext* globalCtx); +s32 func_80A8777C(Actor* thisx, GlobalContext* globalCtx); +s32 func_80A87880(Actor* thisx, GlobalContext* globalCtx); +s32 func_80A87B48(Actor* thisx, GlobalContext* globalCtx); +s32 func_80A87DC0(Actor* thisx, GlobalContext* globalCtx); void func_80A87FD0(EnTru* this, GlobalContext* globalCtx); void func_80A881E0(EnTru* this, GlobalContext* globalCtx); -#if 0 +static UNK_TYPE D_80A88910[] = { + 0x0E08520C, + 0x16100000, +}; + +static UNK_TYPE D_80A88918[] = { + 0x0900000E, + 0x08630C12, + 0x16100000, +}; + +static UNK_TYPE D_80A88924[] = { + 0x0E08660C, + 0x10000000, +}; + +static UNK_TYPE D_80A8892C[] = { + 0x09000004, 0x00050E08, 0x650C1000, 0x1010000B, 0x0E08530C, 0x0F08540C, 0x1900040E, 0x08560C11, + 0x10100E00, 0xFF2B0000, 0x001E0027, 0x2C08640C, 0x2F00000C, 0x15090000, 0x0E08570C, 0x15090000, + 0x0E08580C, 0x15090000, 0x12102C08, 0x550C2F00, 0x000C100E, 0x08550C10, +}; + +static UNK_TYPE D_80A88984[] = { + 0x2CFFFF09, 0x00000E08, 0x640C1509, 0x00000E08, 0x570C1509, 0x00000E08, 0x580C1509, 0x00001210, +}; + +static UNK_TYPE D_80A889A4[] = { + 0x2CFFFF09, + 0x00000E08, + 0x550C1000, +}; + const ActorInit En_Tru_InitVars = { ACTOR_EN_TRU, ACTORCAT_NPC, @@ -31,91 +68,1193 @@ const ActorInit En_Tru_InitVars = { (ActorFunc)EnTru_Draw, }; -// static ColliderSphereInit sSphereInit = { -static ColliderSphereInit D_80A8B2A0 = { - { COLTYPE_NONE, AT_NONE, AC_NONE, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_SPHERE, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000000, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_NONE, OCELEM_ON, }, +#include "overlays/ovl_En_Tru/ovl_En_Tru.c" + +static Vec3f D_80A8B250 = { 0.0f, 0.02f, 0.0f }; + +static Color_RGBA8 D_80A8B25C[] = { + { 255, 20, 60, 0 }, { 255, 235, 160, 0 }, { 20, 60, 255, 0 }, + { 100, 100, 100, 0 }, { 255, 255, 200, 0 }, { 100, 100, 100, 0 }, +}; + +static f32 D_80A8B274[] = { 60.0f, 255.0f, 60.0f }; + +static UNK_TYPE D_80A8B280[] = { + &D_0408F7E0, &D_0408F3E0, &D_0408EFE0, &D_0408EBE0, &D_0408E7E0, &D_0408E3E0, &D_0408DFE0, &D_0408DBE0, +}; + +static ColliderSphereInit sSphereInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_NONE, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_SPHERE, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000000, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_NONE, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 32 }, 100 }, }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80A8B2CC = { 1, 20, 0, 0, MASS_IMMOVABLE }; +static CollisionCheckInfoInit2 sColChkInfoInit = { 1, 20, 0, 0, MASS_IMMOVABLE }; +static ActorAnimationEntryS D_80A8B2D8[] = { + { &object_tru_Anim_00F9A0, 1.0f, 0, -1, 0, 0 }, { &object_tru_Anim_00F9A0, 1.0f, 0, -1, 0, -4 }, + { &object_tru_Anim_0108AC, 1.0f, 0, -1, 2, -4 }, { &object_tru_Anim_009348, 1.0f, 0, -1, 2, 0 }, + { &object_tru_Anim_00EEDC, 1.0f, 0, -1, 0, -4 }, { &object_tru_Anim_015CA0, 1.0f, 0, -1, 0, 0 }, + { &object_tru_Anim_015CA0, 1.0f, 0, -1, 0, -4 }, { &object_tru_Anim_014728, 1.0f, 0, -1, 2, 0 }, + { &object_tru_Anim_01B5C4, 1.0f, 0, -1, 2, 0 }, { &object_tru_Anim_007FA0, 1.0f, 0, -1, 2, -4 }, + { &object_tru_Anim_016B4C, 1.0f, 0, -1, 0, -4 }, { &object_tru_Anim_011F88, 1.0f, 0, -1, 2, -4 }, + { &object_tru_Anim_00446C, 1.0f, 0, -1, 0, 0 }, { &object_tru_Anim_003698, 1.0f, 0, -1, 2, -4 }, + { &object_tru_Anim_002BD8, 1.0f, 0, -1, 0, 0 }, { &object_tru_Anim_00446C, 1.0f, 0, -1, 0, 0 }, +}; + +static Vec3f D_80A8B3D8 = { 0.0f, 24.0f, 16.0f }; +static Vec3f D_80A8B3E4 = { 0.0f, -3.0f, 3.0f }; +static Vec3f D_80A8B3F0 = { 0.0f, 0.5f, 0.0f }; +static Vec3f D_80A8B3FC = { 3000.0f, -800.0f, 0.0f }; + +void func_80A85620(EnTruUnkStruct* arg0, Vec3f* arg1, f32 arg2, f32 arg3, f32 arg4) { + s16 i; + + for (i = 0; i < 30; i++, arg0++) { + if (arg0->unk_00 == 0) { + arg0->unk_02 = Rand_ZeroFloat(20.0f) + arg4; + arg0->unk_01 = arg0->unk_02; + arg0->unk_00 = 1; + arg0->unk_04 = *arg1; + arg0->unk_1C = gZeroVec3f; + arg0->unk_10 = D_80A8B250; + arg0->unk_28 = arg2; + arg0->unk_2C = arg3; + break; + } + } +} + +void func_80A85788(EnTruUnkStruct* arg0, GlobalContext* globalCtx) { + s32 i; + s32 flag = false; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + for (i = 0; i < 30; i++, arg0++) { + if (arg0->unk_00 == 1) { + f32 alpha; + + if (!flag) { + gSPDisplayList(POLY_XLU_DISP++, D_80A89000); + flag = true; + } + + do { + alpha = (f32)arg0->unk_02 / arg0->unk_01; + alpha *= 255.0f; + } while (0); + + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, 128); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)alpha); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, -arg0->unk_02 * 5, 32, 64, 1, 0, 0, 32, 32)); + + Matrix_InsertTranslation(arg0->unk_04.x, arg0->unk_04.y, arg0->unk_04.z, MTXMODE_NEW); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + Matrix_Scale(arg0->unk_28, arg0->unk_28, 1.0f, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, 14.0f, 0.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, D_80A890A8); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80A85AA4(EnTruUnkStruct* arg0, Vec3f* arg1, f32 arg2, f32 arg3, f32 arg4) { + s16 i; + + for (i = 0; i < 30; i++, arg0++) { + if (arg0->unk_00 == 0) { + arg0->unk_02 = arg4; + arg0->unk_01 = arg0->unk_02; + arg0->unk_00 = 2; + arg0->unk_04 = *arg1; + arg0->unk_1C = gZeroVec3f; + arg0->unk_10 = gZeroVec3f; + arg0->unk_28 = arg2; + arg0->unk_2C = arg3; + break; + } + } +} + +void func_80A85BCC(EnTruUnkStruct* arg0, GlobalContext* globalCtx) { + s32 i; + s32 flag = false; + + OPEN_DISPS(globalCtx->state.gfxCtx); + if (globalCtx) {} + + func_8012C2DC(globalCtx->state.gfxCtx); + + for (i = 0; i < 30; i++, arg0++) { + if (arg0->unk_00 == 2) { + f32 alpha; + + if (!flag) { + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 200, 0); + flag = true; + } + + do { + alpha = (f32)arg0->unk_02 / arg0->unk_01; + alpha *= 255.0f; + } while (0); + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 200, (u8)alpha); + + Matrix_InsertTranslation(arg0->unk_04.x, arg0->unk_04.y, arg0->unk_04.z, MTXMODE_NEW); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + Matrix_Scale(arg0->unk_28, arg0->unk_28, 1.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, D_80A8A108); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80A85E2C(EnTruUnkStruct* arg0, Vec3f* arg1, Vec3f* arg2, Vec3f* arg3, f32 arg4, f32 arg5, f32 arg6, u8 arg7) { + s32 i; + + for (i = 0; i < 30; i++, arg0++) { + if (arg0->unk_00 == 0) { + arg0->unk_02 = Rand_ZeroFloat(4.0f) + arg6; + arg0->unk_01 = arg0->unk_02; + arg0->unk_00 = arg7; + arg0->unk_04 = *arg1; + arg0->unk_1C = *arg3; + arg0->unk_10 = *arg2; + arg0->unk_28 = arg4; + arg0->unk_2C = arg5; + break; + } + } +} + +#ifdef NON_MATCHING +// s8/s6 flipped, same deal as above functions but the same fixes don't work +void func_80A85F84(EnTruUnkStruct* arg0, GlobalContext* globalCtx) { + u8 flag = false; + s32 i; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + for (i = 0; i < 30; i++, arg0++) { + f32 alpha; + s32 idx; + + if ((arg0->unk_00 == 3) || (arg0->unk_00 == 4) || (arg0->unk_00 == 5)) { + if (!flag) { + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, sizeof(Gfx) * 0); + gSPDisplayList(POLY_XLU_DISP++, object_tru_DL_01A820); + flag = true; + } + + Matrix_StatePush(); + + do { + alpha = (f32)arg0->unk_02 / arg0->unk_01; + alpha *= D_80A8B274[arg0->unk_00 - 3]; + } while (0); + + gDPSetCombineLERP(POLY_XLU_DISP++, PRIMITIVE, ENVIRONMENT, TEXEL0, ENVIRONMENT, PRIMITIVE, 0, TEXEL0, 0, + COMBINED, 0, SHADE, 0, 0, 0, 0, COMBINED); + gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_ZB_CLD_SURF2); + gSPSetGeometryMode(POLY_XLU_DISP++, G_FOG | G_LIGHTING); + gDPPipeSync(POLY_XLU_DISP++); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, D_80A8B25C[arg0->unk_00 - 3].r, D_80A8B25C[arg0->unk_00 - 3].g, + D_80A8B25C[arg0->unk_00 - 3].b, (u8)alpha); + gDPSetEnvColor(POLY_XLU_DISP++, D_80A8B25C[arg0->unk_00 - 3].r, D_80A8B25C[arg0->unk_00 - 3].g, + D_80A8B25C[arg0->unk_00 - 3].b, 0); + + Matrix_InsertTranslation(arg0->unk_04.x, arg0->unk_04.y, arg0->unk_04.z, MTXMODE_NEW); + Matrix_Scale(arg0->unk_28, arg0->unk_28, 1.0f, MTXMODE_APPLY); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + idx = ((f32)arg0->unk_02 / arg0->unk_01) * 8.0f; + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(D_80A8B280[idx])); + gSPDisplayList(POLY_XLU_DISP++, object_tru_DL_01A830); + + Matrix_StatePop(); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} +#else +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A85F84.s") #endif -extern ColliderSphereInit D_80A8B2A0; -extern CollisionCheckInfoInit2 D_80A8B2CC; +s32 func_80A86384(EnTruUnkStruct* arg0, Vec3f* arg1) { + s32 i; -extern UNK_TYPE D_060020C8; -extern UNK_TYPE D_0601A830; -extern UNK_TYPE D_0601AA60; + for (i = 0; i < 30; i++, arg0++) { + if (arg0->unk_02 != 0) { + if (arg0->unk_00 == 2) { + arg0->unk_04 = *arg1; + } else { + arg0->unk_04.x += arg0->unk_1C.x; + arg0->unk_04.y += arg0->unk_1C.y; + arg0->unk_04.z += arg0->unk_1C.z; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A85620.s") + arg0->unk_1C.x += arg0->unk_10.x; + arg0->unk_1C.y += arg0->unk_10.y; + arg0->unk_1C.z += arg0->unk_10.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A85788.s") + arg0->unk_02--; + arg0->unk_28 += arg0->unk_2C; + } else { + arg0->unk_00 = 0; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A85AA4.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A85BCC.s") +s32 func_80A86460(EnTru* this) { + s32 i; + Vec3f spB0; + Vec3f spA4; + Vec3f sp98; + Vec3f sp8C; + f32 temp_f6; + s16 phi_s1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A85E2C.s") + Math_Vec3f_Copy(&spB0, &gZeroVec3f); + Math_Vec3f_Copy(&sp8C, &gZeroVec3f); + Math_Vec3f_Copy(&spA4, &gZeroVec3f); + Math_Vec3f_Copy(&sp98, &gZeroVec3f); + phi_s1 = (Rand_ZeroOne() * 360.0f) * 182.0f; + spB0.z = 20.0f; + Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, this->actor.world.rot.y, &spB0, &sp8C); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A85F84.s") + for (i = 0; i < 8; i++, phi_s1 += 0x1FFE) { + Math_Vec3f_Copy(&spB0, &gZeroVec3f); + spB0.y = 1.0f; + spB0.z = Rand_ZeroOne() + 3.0f; + Lib_Vec3f_TranslateAndRotateY(&gZeroVec3f, phi_s1, &spB0, &sp98); + Math_Vec3f_Copy(&spB0, &gZeroVec3f); + spB0.z = (Rand_ZeroOne() * 4.0f) + 12.0f; + Lib_Vec3f_TranslateAndRotateY(&sp8C, phi_s1, &spB0, &spA4); + func_80A85E2C(this->unk_394, &spA4, &gZeroVec3f, &sp98, 0.4f, 0.06f, 12.0f, 4); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86384.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86460.s") +s32 func_80A86674(EnTru* this) { + s32 pad; + Vec3f sp40; + Vec3f sp34; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86674.s") + Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, this->actor.world.rot.y, &D_80A8B3D8, &sp40); + Lib_Vec3f_TranslateAndRotateY(&gZeroVec3f, this->actor.world.rot.y, &D_80A8B3E4, &sp34); + if (this->unk_390 == 1) { + func_80A85E2C(this->unk_394, &sp40, &D_80A8B3F0, &sp34, 0.2f, 0.1f, 12.0f, 3); + } else if (this->unk_390 == 2) { + func_80A85E2C(this->unk_394, &sp40, &D_80A8B3F0, &sp34, 0.2f, 0.1f, 12.0f, 5); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86770.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A868F8.s") +s32 func_80A86770(EnTru* this) { + s32 pad; + Vec3f sp98; + Vec3f sp8C; + s32 i; + s16 phi_s0 = Rand_ZeroOne() * 360.0f * 182.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86924.s") + for (i = 0; i < 4; i++, phi_s0 += 0x3FFC) { + Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, phi_s0, &gZeroVec3f, &sp98); + sp98.y = this->actor.floorHeight + 1.0f; + sp8C.x = Rand_ZeroOne() - 0.5f; + sp8C.z = Rand_ZeroOne() - 0.5f; + sp8C.y = Rand_ZeroOne() * 0.2f; + func_80A85E2C(this->unk_394, &sp98, &sp8C, &gZeroVec3f, 1.0f, 0.04f, 28.0f, 4); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A8697C.s") + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A869DC.s") +void func_80A868F8(EnTru* this) { + this->skelAnime.playSpeed = this->unk_358; + SkelAnime_Update(&this->skelAnime); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86B0C.s") +s32 func_80A86924(EnTru* this, s32 arg1) { + s32 ret = false; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86BAC.s") + if (arg1 != this->unk_37C) { + this->unk_37C = arg1; + ret = func_8013BC6C(&this->skelAnime, D_80A8B2D8, arg1); + this->unk_358 = this->skelAnime.playSpeed; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A86DB8.s") + return ret; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A871E0.s") +void func_80A8697C(EnTru* this, GlobalContext* globalCtx) { + this->collider.dim.worldSphere.radius = this->collider.dim.modelSphere.radius * this->collider.dim.scale; + if (this->actor.draw != NULL) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A872AC.s") +s32 func_80A869DC(EnTru* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + Vec3f sp38; + Vec3f sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A873B8.s") + Math_ApproachS(&this->unk_368, this->actor.yawTowardsPlayer - this->actor.shape.rot.y, 4, 0x2AA8); + this->unk_368 = CLAMP(this->unk_368, -0x1FFE, 0x1FFE); + Math_Vec3f_Copy(&sp38, &player->actor.world.pos); + sp38.y = player->bodyPartsPos[7].y + 3.0f; + Math_Vec3f_Copy(&sp2C, &this->actor.focus.pos); + sp2C.y -= 30.0f; + Math_ApproachS(&this->unk_366, Math_Vec3f_Pitch(&sp2C, &sp38), 4, 0x2AA8); + this->unk_366 = CLAMP(this->unk_366, -0x1C70, 0x1C70); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A87400.s") + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A875AC.s") +s32 func_80A86B0C(EnTru* this, GlobalContext* globalCtx) { + if (this->unk_34E & 8) { + this->unk_34E &= ~0x10; + this->unk_34E |= 0x20; + func_80A869DC(this, globalCtx); + } else if (this->unk_34E & 0x20) { + this->unk_34E &= ~0x20; + this->unk_366 = 0; + this->unk_368 = 0; + this->unk_36A = 20; + } else if (DECR(this->unk_36A) == 0) { + this->unk_34E |= 0x10; + this->unk_36A = 20; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A8777C.s") + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A87880.s") +s32 func_80A86BAC(EnTru* this, GlobalContext* globalCtx) { + if (this->unk_34E & 0x400) { + Matrix_StatePush(); + func_8012C28C(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A87B48.s") + OPEN_DISPS(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A87DC0.s") + switch (this->unk_390) { + case 1: + gDPSetEnvColor(POLY_OPA_DISP++, 200, 0, 0, 0); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A87FD0.s") + case 2: + gDPSetEnvColor(POLY_OPA_DISP++, 0, 0, 200, 0); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A881E0.s") + default: + gDPSetEnvColor(POLY_OPA_DISP++, 255, 255, 255, 0); + break; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/EnTru_Init.s") + Matrix_InsertXRotation_s(-0x4000, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/EnTru_Destroy.s") + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_tru_DL_0020C8); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/EnTru_Update.s") + Matrix_StatePop(); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A885B8.s") + CLOSE_DISPS(globalCtx->state.gfxCtx); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A88698.s") + if (this->unk_34E & 0x800) { + Matrix_StatePush(); + func_8012C2DC(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/func_80A886D4.s") + OPEN_DISPS(globalCtx->state.gfxCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Tru/EnTru_Draw.s") + gDPPipeSync(POLY_XLU_DISP++); + + Matrix_InsertXRotation_s(-0x4000, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_tru_DL_001F90); + + Matrix_StatePop(); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + + return false; +} + +s32 func_80A86DB8(EnTru* this) { + if (this->unk_34E & 0x80) { + this->unk_36E = 2; + return false; + } + + switch (this->unk_37C) { + case 0: + case 1: + if (DECR(this->unk_36C) == 0) { + s16 rand = Rand_S16Offset(40, 20); + if (this->unk_36E == 2) { + this->unk_36C = 8; + } else { + this->unk_36C = rand; + } + + if (this->unk_36E == 2) { + this->unk_36E = 1; + } else { + this->unk_36E = 2; + } + } + return false; + + case 2: + if (Animation_OnFrame(&this->skelAnime, 10.0f)) { + this->unk_36E = 1; + } else if ((this->skelAnime.curFrame >= 11.0f) && (this->skelAnime.curFrame <= 32.0f)) { + this->unk_36E = 0; + } else { + this->unk_36E = 2; + } + return false; + + case 3: + if (Animation_OnFrame(&this->skelAnime, 31.0f)) { + this->unk_36E = 1; + } else if (this->skelAnime.curFrame <= 32.0f) { + this->unk_36E = 2; + } else { + this->unk_36E = 0; + } + return false; + + case 9: + if (Animation_OnFrame(&this->skelAnime, 57.0f)) { + this->unk_36C = 0; + this->unk_36E = 0; + } + + if (this->skelAnime.curFrame < 57.0f) { + if (DECR(this->unk_36C) == 0) { + this = this; + this->unk_36C = Rand_S16Offset(8, 8); + this->unk_36E = 2; + } else { + this->unk_36E = 1; + } + } else if (DECR(this->unk_36C) == 0) { + this->unk_36E++; + if (this->unk_36E >= 4) { + this->unk_36C = Rand_S16Offset(20, 10); + this->unk_36E = 0; + } + } + return false; + + case 10: + this->unk_36E = 0; + return false; + + case 11: + if (Animation_OnFrame(&this->skelAnime, 19.0f) || Animation_OnFrame(&this->skelAnime, 45.0f)) { + this->unk_36E = 1; + } else if ((this->skelAnime.curFrame >= 19.0f) && (this->skelAnime.curFrame <= 45.0f)) { + this->unk_36E = 2; + } else { + this->unk_36E = 3; + } + return false; + + case 13: + if (Animation_OnFrame(&this->skelAnime, 19.0f)) { + this->unk_36E = 1; + } else if (this->skelAnime.curFrame >= 19.0f) { + this->unk_36E = 2; + } else { + this->unk_36E = 0; + } + return false; + + default: + if (DECR(this->unk_36C) == 0) { + if ((this->unk_36E != 2) || !(this->unk_34E & 0x80)) { + this->unk_36E++; + } + + if (this->unk_36E >= 4) { + this->unk_36C = Rand_S16Offset(30, 30); + this->unk_36E = 0; + } + } + return false; + } + + return false; +} + +UNK_TYPE* func_80A871E0(EnTru* this, GlobalContext* globalCtx) { + if (this->unk_34E & 0x2000) { + if (this->unk_38C == 35) { + this->unk_390 = 1; + } else { + this->unk_390 = 2; + } + return D_80A88984; + } + + if (this->unk_34E & 0x4000) { + return D_80A889A4; + } + + if (this->unk_34E & 0x80) { + return D_80A88924; + } + + if (!(this->unk_34E & 0x40) && !(gSaveContext.weekEventReg[16] & 0x10)) { + return D_80A88918; + } + + if ((this->unk_34E & 0x1000) && !(gSaveContext.weekEventReg[16] & 0x10)) { + return D_80A88910; + } + + return D_80A8892C; +} + +s32 func_80A872AC(EnTru* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + s32 ret = false; + + if (this->unk_34E & 7) { + if (func_800B84D0(&this->actor, globalCtx)) { + if (player->transformation == PLAYER_FORM_HUMAN) { + this->unk_34E &= ~0x80; + } + this->unk_34E &= ~(0x4000 | 0x2000); + + if ((player->unk_A87 == 35) || (player->unk_A87 == 36)) { + this->unk_34E |= 0x2000; + this->unk_38C = player->unk_A87; + } else if (player->unk_A87 != 0) { + this->unk_34E |= 0x4000; + } + + this->unk_378 = func_80A875AC; + this->unk_390 = 0; + this->unk_364 = 0; + this->unk_354 = func_80A871E0(this, globalCtx); + func_8013AED4(&this->unk_34E, 0, 7); + this->actionFunc = func_80A881E0; + ret = true; + } + } + + return ret; +} + +s32 func_80A873B8(EnTru* this) { + s16 yDiff = this->actor.yawTowardsPlayer - this->actor.world.rot.y; + s32 ret; + + if ((u16)ABS_ALT(yDiff) < 0x1600) { + ret = true; + } else { + ret = false; + } + return ret; +} + +s32 func_80A87400(EnTru* this, GlobalContext* globalCtx) { + Vec3s* sp4C; + Vec3f sp40; + Vec3f sp34; + s16 phi_a1; + s32 ret = false; + + this->actor.velocity.y = Math_SinS(this->unk_360) * this->unk_35C; + this->unk_360 = CLAMP(this->unk_360 + 2000, 0, 0x4000); + + Math_ApproachF(&this->unk_35C, 30.0f, 0.08f, 1000.0f); + Math_ApproachF(&this->actor.speedXZ, 30.0f, 0.2f, 1000.0f); + + if (this->path != NULL) { + sp4C = (Vec3s*)Lib_SegmentedToVirtual(this->path->points); + if (func_8013BD40(&this->actor, this->path, this->unk_384)) { + if (this->unk_384 > this->unk_384 + 1) { + this->unk_384 = this->path->count - 2; + ret = true; + } + this->unk_384++; + } + Math_Vec3s_ToVec3f(&sp34, &sp4C[this->unk_384]); + Math_Vec3f_Copy(&sp40, &this->actor.world.pos); + phi_a1 = Math_Vec3f_Yaw(&sp40, &sp34); + } else { + phi_a1 = this->actor.world.rot.y; + } + + Math_ApproachS(&this->actor.world.rot.y, phi_a1, 4, 3640); + this->actor.shape.rot.y = this->actor.world.rot.y; + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + if ((s32)(this->actor.floorHeight + 80.0f) >= (s32)this->actor.world.pos.y) { + func_80A86770(this); + } + + return ret; +} + +s32 func_80A875AC(Actor* thisx, GlobalContext* globalCtx) { + EnTru* this = THIS; + s32 ret = false; + + switch (this->unk_364) { + case 0: + if ((this->unk_34E & 0x40) || (gSaveContext.weekEventReg[16] & 0x10)) { + this->unk_374 = this->actor.cutscene; + this->unk_364++; + } else { + this->unk_364++; + this->unk_364++; + break; + } + + case 1: + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->unk_374); + } else if (ActorCutscene_GetCanPlayNext(this->unk_374)) { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_374, &this->actor); + this->unk_364++; + } else { + ActorCutscene_SetIntentToPlay(this->unk_374); + } + break; + + case 2: + if ((this->unk_37C != 5) && (this->unk_37C != 6)) { + func_80A86924(this, 3); + this->unk_364++; + } else { + func_80A86924(this, 4); + ret = true; + } + break; + + case 3: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->unk_364++; + func_80A86924(this, 4); + ret = true; + } + break; + } + + if (ret == true) { + if (this->unk_390 != 0) { + this->unk_34E |= 8; + this->unk_378 = func_80A87880; + } else { + this->unk_378 = func_80A8777C; + } + this->unk_364 = 0; + } + + return ret; +} + +s32 func_80A8777C(Actor* thisx, GlobalContext* globalCtx) { + s32 temp_v0; + s32 ret = 0; + + temp_v0 = func_80152498(&globalCtx->msgCtx); + + switch (temp_v0) { + default: + if (temp_v0 != 0x10) { + break; + } + if (0) { + + case 4: + case 5: + if (!func_80147624(globalCtx)) { + break; + } + } + + temp_v0 = func_80123810(globalCtx); + if ((temp_v0 == 35) || (temp_v0 == 36)) { + ((EnTru*)thisx)->unk_34E |= 8; + if (temp_v0 == 35) { + ((EnTru*)thisx)->unk_390 = 1; + } else { + ((EnTru*)thisx)->unk_390 = 2; + } + ((EnTru*)thisx)->unk_378 = func_80A87880; + ((EnTru*)thisx)->unk_364 = 0; + ret = 1; + } else if (temp_v0 < 0) { + ret = 3; + } else if (temp_v0 != 0) { + ret = 2; + } + break; + } + + return ret; +} + +s32 func_80A87880(Actor* thisx, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + EnTru* this = THIS; + s32 ret = false; + + switch (this->unk_364) { + case 0: + ActorCutscene_Stop(this->unk_374); + this->unk_374 = ActorCutscene_GetAdditionalCutscene(this->unk_374); + this->unk_364++; + + case 1: + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->unk_374); + } else if (ActorCutscene_GetCanPlayNext(this->unk_374)) { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_374, &this->actor); + this->unk_364++; + } else { + ActorCutscene_SetIntentToPlay(this->unk_374); + } + break; + + case 2: + this->unk_34E |= 0x10; + this->unk_34E &= ~0x8; + this->actor.shape.rot.y = this->actor.yawTowardsPlayer; + this->actor.world.rot.y = this->actor.yawTowardsPlayer; + func_80A86924(this, 7); + this->unk_364++; + break; + + case 3: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->unk_364++; + func_80A86924(this, 9); + this->actor.world.rot.y += 0x4000; + } else if (Animation_OnFrame(&this->skelAnime, 12.0f) && !(this->unk_34E & 0x800)) { + this->unk_34E |= 0x400; + this->unk_34E |= 0x800; + func_80123AA4(player, 3); + } + break; + + case 4: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->unk_364++; + func_80A86924(this, 10); + ret = true; + } else if (Animation_OnFrame(&this->skelAnime, 18.0f) || Animation_OnFrame(&this->skelAnime, 32.0f) || + Animation_OnFrame(&this->skelAnime, 52.0f)) { + if (Animation_OnFrame(&this->skelAnime, 52.0f)) { + this->unk_34E &= ~0x400; + func_80123D50(globalCtx, player, 18, 21); + } + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KOUME_DRINK); + } else if (Animation_OnFrame(&this->skelAnime, 90.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KOUME_REGAIN); + } + + if ((this->skelAnime.curFrame > 90.0f) && (this->skelAnime.curFrame < 95.0f)) { + func_80A86674(this); + } + break; + } + + if (ret == true) { + this->unk_378 = func_80A87B48; + this->unk_364 = 0; + } + + return ret; +} + +s32 func_80A87B48(Actor* thisx, GlobalContext* globalCtx) { + EnTru* this = THIS; + Player* player = GET_PLAYER(globalCtx); + Vec3f sp4C; + Vec3f sp40; + s16 sp3E; + s32 pad2; + s32 ret = false; + + switch (this->unk_364) { + case 0: + func_80A86924(this, 11); + this->unk_364++; + break; + + case 1: + if (Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + sp3E = BINANG_ROT180(func_800DFCDC(GET_ACTIVE_CAM(globalCtx))); + Math_Vec3f_Copy(&sp4C, &gZeroVec3f); + sp4C.z = 40.0f; + Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, sp3E, &sp4C, &sp40); + func_80A85620(this->unk_394, &sp40, 2.0f, 0.08f, 60.0f); + func_8016A268(globalCtx, 1, 160, 160, 160, 0); + this->unk_370 = 20; + this->unk_372 = 10; + this->unk_364++; + } else if (Animation_OnFrame(&this->skelAnime, 22.0f)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KOUME_MAGIC); + func_80A85AA4(this->unk_394, &this->unk_1F8, 1.0f, 0.1f, 40.0f); + } + break; + + case 2: + if (DECR(this->unk_370) != 0) { + MREG(68) = 255.0f - ((fabsf(10.0f - this->unk_370) / 10) * 255.0f); + if (this->unk_370 == 9) { + this->actor.shape.shadowDraw = NULL; + this->unk_34E |= (0x200 | 0x8); + this->unk_34E &= ~0x800; + if (player->unk_A87 != 0) { + player->unk_A87 = 0; + } + func_80A86924(this, 12); + } + } else { + MREG(64) = 0; + ret = true; + } + break; + } + + if (ret == true) { + this->unk_378 = func_80A87DC0; + this->unk_364 = 0; + } + + return ret; +} + +s32 func_80A87DC0(Actor* thisx, GlobalContext* globalCtx) { + EnTru* this = THIS; + s32 ret = false; + + switch (this->unk_364) { + case 0: + ActorCutscene_Stop(this->unk_374); + this->unk_374 = ActorCutscene_GetAdditionalCutscene(this->unk_374); + this->unk_364++; + + case 1: + if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->unk_374); + } else if (ActorCutscene_GetCanPlayNext(this->unk_374)) { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_374, &this->actor); + this->unk_364++; + } else { + ActorCutscene_SetIntentToPlay(this->unk_374); + } + break; + + case 2: + func_801A75E8(NA_SE_EN_KOUME_MAGIC); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KOUME_AWAY); + Audio_PlayActorSound2(&this->actor, NA_SE_EN_KOUME_LAUGH); + func_80A86924(this, 13); + this->skelAnime.baseTransl.y = 0; + this->skelAnime.moveFlags = 2; + this->unk_34E &= ~0x8; + this->unk_34E |= 0x10; + this->unk_364++; + break; + + case 3: + if (!Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + AnimationContext_SetMoveActor(globalCtx, &this->actor, &this->skelAnime, 1.0f); + break; + } else { + func_80A86924(this, 14); + this->actor.shape.rot.y = this->actor.world.rot.y; + this->unk_362 = 20; + this->unk_364++; + } + + case 4: + if (func_80A87400(this, globalCtx) || (DECR(this->unk_362) == 0)) { + ret = true; + gSaveContext.weekEventReg[12] |= 8; + } + break; + } + + if (ret == true) { + this->actor.flags &= ~1; + this->actor.draw = NULL; + this->unk_378 = NULL; + this->unk_34E = 0; + this->unk_364 = 0; + } + return ret; +} + +void func_80A87FD0(EnTru* this, GlobalContext* globalCtx) { + if (this->actor.draw != NULL) { + if ((this->unk_34E & 0x80) || (gSaveContext.weekEventReg[16] & 0x10)) { + if (func_80A873B8(this)) { + func_8013AED4(&this->unk_34E, 3, 7); + } else { + func_8013AED4(&this->unk_34E, 0, 7); + } + } else if (this->unk_34E & 0x40) { + if (func_80A873B8(this)) { + func_8013AED4(&this->unk_34E, 3, 7); + } else { + func_8013AED4(&this->unk_34E, 0, 7); + } + + if ((this->unk_37C == 2) && Animation_OnFrame(&this->skelAnime, this->skelAnime.endFrame)) { + this->unk_362 = Rand_S16Offset(40, 20); + func_80A86924(this, 1); + func_80A86460(this); + } else if (this->unk_37C != 2) { + if (DECR(this->unk_362) == 0) { + func_80A86924(this, 2); + } + } + } else if (!(gSaveContext.weekEventReg[16] & 0x10) && (fabsf(this->actor.playerHeightRel) < 10.0f) && + (this->actor.xzDistToPlayer < 140.0f)) { + func_8013AED4(&this->unk_34E, 4, 7); + this->unk_34E |= 0x1040; + this->unk_362 = Rand_S16Offset(40, 20); + } else if (func_80A873B8(this)) { + func_8013AED4(&this->unk_34E, 3, 7); + } else { + func_8013AED4(&this->unk_34E, 0, 7); + } + } +} + +void func_80A881E0(EnTru* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (func_8010BF58(&this->actor, globalCtx, this->unk_354, this->unk_378, &this->unk_1E8)) { + if (player->transformation != PLAYER_FORM_HUMAN) { + this->unk_34E |= 0x80; + } + + if (ActorCutscene_GetCurrentIndex() != -1) { + ActorCutscene_Stop(ActorCutscene_GetCurrentIndex()); + } + + if (!(this->unk_34E & 0x40) && !(gSaveContext.weekEventReg[16] & 0x10)) { + func_80A86924(this, 0); + } else if (this->unk_34E & 0x80) { + func_80A86924(this, 0); + func_80A86460(this); + } else if (gSaveContext.weekEventReg[16] & 0x10) { + func_80A86924(this, 6); + } + + func_8013AED4(&this->unk_34E, 0, 7); + this->unk_34E &= ~(0x1000 | 0x8); + this->unk_34E |= 0x10; + this->actor.shape.rot.y = this->actor.world.rot.y; + this->actor.flags &= ~0x100; + this->unk_1E8 = 0; + this->actionFunc = func_80A87FD0; + } +} + +void EnTru_Init(Actor* thisx, GlobalContext* globalCtx) { + EnTru* this = THIS; + + if ((gSaveContext.entranceIndex != 0xC200) || (gSaveContext.weekEventReg[12] & 8)) { + Actor_MarkForDeath(&this->actor); + return; + } + + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 24.0f); + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_tru_Skel_01AA60, NULL, this->jointTable, this->morphTable, + 27); + Collider_InitAndSetSphere(globalCtx, &this->collider, &this->actor, &sSphereInit); + CollisionCheck_SetInfo2(&this->actor.colChkInfo, DamageTable_Get(0x16), &sColChkInfoInit); + this->unk_37C = -1; + func_80A86924(this, 0); + this->path = func_8013BEDC(globalCtx, this->actor.params & 0xFF, 255, &this->unk_384); + if (this->path != NULL) { + this->unk_384 = 1; + } + + this->actor.targetMode = 0; + Actor_SetScale(&this->actor, 0.008f); + this->unk_34E = 0; + + if (gSaveContext.weekEventReg[16] & 0x10) { + func_80A86924(this, 5); + } else { + this->unk_388 = 0; + } + + this->actionFunc = func_80A87FD0; + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); +} + +void EnTru_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnTru* this = THIS; + + Collider_DestroySphere(globalCtx, &this->collider); +} + +void EnTru_Update(Actor* thisx, GlobalContext* globalCtx) { + EnTru* this = THIS; + f32 radius; + + func_80A872AC(this, globalCtx); + + this->actionFunc(this, globalCtx); + + func_80A868F8(this); + func_80A86B0C(this, globalCtx); + func_80A86DB8(this); + + radius = this->collider.dim.worldSphere.radius + 30; + this->unk_388 = !(this->unk_34E & 0x80) ? 0 : 0; + + func_8013C964(&this->actor, globalCtx, radius, 20.0f, this->unk_388, this->unk_34E & 7); + func_80A8697C(this, globalCtx); + func_80A86384(this->unk_394, &this->unk_1F8); +} + +s32 EnTru_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot, Actor* thisx) { + s32 pad; + EnTru* this = THIS; + + if (limbIndex == 21) { + Matrix_GetStateTranslation(&this->actor.focus.pos); + Math_Vec3f_ToVec3s(&this->collider.dim.worldSphere.center, &this->actor.focus.pos); + this->actor.focus.pos.x = (this->actor.focus.pos.x / 10.0f) * 10.0f; + this->actor.focus.pos.y = ((this->actor.focus.pos.y + 10.0f) / 10.0f) * 10.0f; + this->actor.focus.pos.z = (this->actor.focus.pos.z / 10.0f) * 10.0f; + Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.world.rot); + Matrix_MultiplyVector3fByState(&D_80A8B3FC, &this->unk_1F8); + } + + if (!(this->unk_34E & 0x200) && (limbIndex == 14)) { + *dList = NULL; + } + + return false; +} + +void EnTru_PostLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + EnTru* this = THIS; + + if (limbIndex == 19) { + func_80A86BAC(this, globalCtx); + } +} + +void func_80A886D4(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) { + EnTru* this = THIS; + s32 pad[3]; + s32 sp2C; + s32 phi_v1; + + if (this->unk_34E & 0x10) { + phi_v1 = false; + } else { + phi_v1 = true; + } + + if (this->unk_34E & 0x20) { + sp2C = true; + } else { + sp2C = false; + } + + if (!phi_v1) { + sp2C = false; + } + + if (limbIndex == 21) { + func_8013AD9C(this->unk_366, this->unk_368 + this->actor.shape.rot.y, &this->unk_1EC, &this->unk_204, phi_v1, + sp2C); + Matrix_StatePop(); + Matrix_InsertTranslation(this->unk_1EC.x, this->unk_1EC.y, this->unk_1EC.z, MTXMODE_NEW); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + if (sp2C) { + s16 oldZ = this->unk_204.z; + + this->unk_204.z = this->unk_204.x; + this->unk_204.x = oldZ; + } + Matrix_RotateY(this->unk_204.y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->unk_204.x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->unk_204.z, MTXMODE_APPLY); + Matrix_StatePush(); + } +} + +void EnTru_Draw(Actor* thisx, GlobalContext* globalCtx) { + static TexturePtr D_80A8B408[] = { + &object_tru_Tex_018FA0, + &object_tru_Tex_0197A0, + &object_tru_Tex_019FA0, + &object_tru_Tex_0197A0, + }; + s32 pad; + EnTru* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, Lib_SegmentedToVirtual(D_80A8B408[this->unk_36E])); + gSPSegment(POLY_OPA_DISP++, 0x09, Lib_SegmentedToVirtual(D_80A8B408[this->unk_36E])); + + func_801343C0(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, + EnTru_OverrideLimbDraw, EnTru_PostLimbDraw, func_80A886D4, &this->actor); + func_80A85788(this->unk_394, globalCtx); + func_80A85BCC(this->unk_394, globalCtx); + func_80A85F84(this->unk_394, globalCtx); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Tru/z_en_tru.h b/src/overlays/actors/ovl_En_Tru/z_en_tru.h index 7c21a43a3..4127fcdff 100644 --- a/src/overlays/actors/ovl_En_Tru/z_en_tru.h +++ b/src/overlays/actors/ovl_En_Tru/z_en_tru.h @@ -6,12 +6,55 @@ struct EnTru; typedef void (*EnTruActionFunc)(struct EnTru*, GlobalContext*); +typedef s32 (*EnTruUnkFunc)(Actor*, GlobalContext*); + +typedef struct { + /* 0x00 */ u8 unk_00; + /* 0x01 */ u8 unk_01; + /* 0x02 */ u8 unk_02; + /* 0x04 */ Vec3f unk_04; + /* 0x10 */ Vec3f unk_10; + /* 0x1C */ Vec3f unk_1C; + /* 0x28 */ f32 unk_28; + /* 0x2C */ f32 unk_2C; +} EnTruUnkStruct; // size = 0x30 typedef struct EnTru { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x44]; + /* 0x0144 */ SkelAnime skelAnime; /* 0x0188 */ EnTruActionFunc actionFunc; - /* 0x018C */ char unk_18C[0x7A8]; + /* 0x018C */ ColliderSphere collider; + /* 0x01E4 */ Path* path; + /* 0x01E8 */ s32 unk_1E8; + /* 0x01EC */ Vec3f unk_1EC; + /* 0x01F8 */ Vec3f unk_1F8; + /* 0x0204 */ Vec3s unk_204; + /* 0x020A */ Vec3s jointTable[27]; + /* 0x02AC */ Vec3s morphTable[27]; + /* 0x034E */ u16 unk_34E; + /* 0x0350 */ UNK_TYPE1 unk350[0x4]; + /* 0x0354 */ s32* unk_354; + /* 0x0358 */ f32 unk_358; + /* 0x035C */ f32 unk_35C; + /* 0x0360 */ s16 unk_360; + /* 0x0362 */ s16 unk_362; + /* 0x0364 */ s16 unk_364; + /* 0x0366 */ s16 unk_366; + /* 0x0368 */ s16 unk_368; + /* 0x036A */ s16 unk_36A; + /* 0x036C */ s16 unk_36C; + /* 0x036E */ s16 unk_36E; + /* 0x0370 */ s16 unk_370; + /* 0x0372 */ s16 unk_372; + /* 0x0374 */ s16 unk_374; + /* 0x0378 */ EnTruUnkFunc unk_378; + /* 0x037C */ s32 unk_37C; + /* 0x0380 */ UNK_TYPE1 unk380[0x4]; + /* 0x0384 */ s32 unk_384; + /* 0x0388 */ s32 unk_388; + /* 0x038C */ s32 unk_38C; + /* 0x0390 */ s32 unk_390; + /* 0x0394 */ EnTruUnkStruct unk_394[30]; } EnTru; // size = 0x934 extern const ActorInit En_Tru_InitVars; diff --git a/src/overlays/actors/ovl_En_Tru_Mt/z_en_tru_mt.h b/src/overlays/actors/ovl_En_Tru_Mt/z_en_tru_mt.h index ed083ec50..793958ed7 100644 --- a/src/overlays/actors/ovl_En_Tru_Mt/z_en_tru_mt.h +++ b/src/overlays/actors/ovl_En_Tru_Mt/z_en_tru_mt.h @@ -10,7 +10,7 @@ typedef void (*EnTruMtActionFunc)(struct EnTruMt*, GlobalContext*); typedef struct EnTruMt { /* 0x0000 */ Actor actor; /* 0x0144 */ EnTruMtActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x260]; + /* 0x0148 */ char unk_148[0x260]; } EnTruMt; // size = 0x3A8 extern const ActorInit En_Tru_Mt_InitVars; diff --git a/src/overlays/actors/ovl_En_Viewer/z_en_viewer.h b/src/overlays/actors/ovl_En_Viewer/z_en_viewer.h index 6b145b0c5..566c21f3c 100644 --- a/src/overlays/actors/ovl_En_Viewer/z_en_viewer.h +++ b/src/overlays/actors/ovl_En_Viewer/z_en_viewer.h @@ -10,7 +10,7 @@ typedef void (*EnViewerActionFunc)(struct EnViewer*, GlobalContext*); typedef struct EnViewer { /* 0x0000 */ Actor actor; /* 0x0144 */ EnViewerActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x10]; + /* 0x0148 */ char unk_148[0x10]; } EnViewer; // size = 0x158 extern const ActorInit En_Viewer_InitVars; diff --git a/src/overlays/actors/ovl_En_Warp_Uzu/z_en_warp_uzu.c b/src/overlays/actors/ovl_En_Warp_Uzu/z_en_warp_uzu.c index 8dd30eec2..2031127f7 100644 --- a/src/overlays/actors/ovl_En_Warp_Uzu/z_en_warp_uzu.c +++ b/src/overlays/actors/ovl_En_Warp_Uzu/z_en_warp_uzu.c @@ -81,7 +81,7 @@ void func_80A66208(EnWarpUzu* this, GlobalContext* globalCtx) { Vec3f sp24; this->actor.textId = 0; - Matrix_RotateY(this->actor.shape.rot.y, 0); + Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_NEW); Matrix_MultiplyVector3fByState(&D_80A664FC, &sp24); Math_Vec3f_Sum(&this->actor.world.pos, &sp24, &this->actor.focus.pos); Math_Vec3s_Copy(&this->actor.focus.rot, &this->actor.shape.rot); diff --git a/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.c b/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.c index 236881f25..05d86f3cd 100644 --- a/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.c +++ b/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.c @@ -5,6 +5,8 @@ */ #include "z_en_water_effect.h" +#include "objects/object_water_effect/object_water_effect.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x00000035 @@ -15,7 +17,11 @@ void EnWaterEffect_Destroy(Actor* thisx, GlobalContext* globalCtx); void EnWaterEffect_Update(Actor* thisx, GlobalContext* globalCtx); void EnWaterEffect_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80A59C04(Actor* thisx, GlobalContext* globalCtx2); +void func_80A5A184(Actor* thisx, GlobalContext* globalCtx2); +void func_80A5A534(Actor* thisx, GlobalContext* globalCtx); +void func_80A5A6B8(Actor* thisx, GlobalContext* globalCtx2); + const ActorInit En_Water_Effect_InitVars = { ACTOR_EN_WATER_EFFECT, ACTORCAT_BOSS, @@ -28,30 +34,672 @@ const ActorInit En_Water_Effect_InitVars = { (ActorFunc)EnWaterEffect_Draw, }; -#endif +static Vec3f D_80A5AFB0 = { 0.0f, 0.0f, 0.0f }; +static Vec3f D_80A5AFBC = { 0.0f, -1.0f, 0.0f }; -extern UNK_TYPE D_06000DE0; -extern UNK_TYPE D_060042B0; -extern UNK_TYPE D_060043E8; +void func_80A587A0(EnWaterEffect* this, Vec3f* arg1, u8 arg2) { + s16 i; + EnWaterEffectStruct* ptr = &this->unk_144[0]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/func_80A587A0.s") + for (i = 0; i < ARRAY_COUNT(this->unk_144) / 2; i++, ptr++) { + if (!ptr->unk_00) { + ptr->unk_00 = true; + ptr->unk_04 = *arg1; + ptr->unk_10 = D_80A5AFB0; + ptr->unk_1C = D_80A5AFB0; + ptr->unk_2C.x = 0.1f; + ptr->unk_2C.y = 0.0f; + ptr->unk_2C.z = Rand_ZeroFloat(M_PI * 2); + ptr->unk_01 = Rand_ZeroFloat(100.0f); + ptr->unk_2A = arg2; + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/func_80A58908.s") +void func_80A58908(EnWaterEffect* this, Vec3f* arg1, Vec3f* arg2, u8 arg3) { + Vec3f sp2C = D_80A5AFBC; + EnWaterEffectStruct* ptr = &this->unk_144[0]; + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/EnWaterEffect_Init.s") + for (i = 0; i < ARRAY_COUNT(this->unk_144) / 2; i++, ptr++) { + if (ptr->unk_00 == 0) { + ptr->unk_00 = 2; + ptr->unk_04 = *arg1; + ptr->unk_10 = *arg2; + ptr->unk_1C = sp2C; + ptr->unk_2C.y = Rand_ZeroFloat(0.02f) + 0.02f; + ptr->unk_2C.x = ptr->unk_2C.y; + ptr->unk_2C.z = Rand_ZeroFloat(M_PI * 2); + ptr->unk_01 = Rand_ZeroFloat(100.0f); + ptr->unk_2A = arg3; + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/EnWaterEffect_Destroy.s") +void EnWaterEffect_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnWaterEffect* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/EnWaterEffect_Update.s") + this->actor.flags &= ~1; + this->unk_DC4 = Rand_ZeroFloat(100.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/EnWaterEffect_Draw.s") + if (this->actor.params == ENWATEREFFECT_1) { + this->actor.update = func_80A59C04; + this->actor.draw = func_80A5A184; + this->unk_DC6 = Rand_ZeroFloat(100.0f) + 60.0f; + } else if ((this->actor.params == ENWATEREFFECT_777) || (this->actor.params == ENWATEREFFECT_778) || + (this->actor.params == ENWATEREFFECT_779) || (this->actor.params == ENWATEREFFECT_780)) { + this->actor.update = func_80A5A534; + this->actor.draw = func_80A5A6B8; + this->actor.shape.rot.y = Rand_ZeroFloat(0x10000); + Actor_SetScale(&this->actor, this->actor.shape.rot.z * 0.0002f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/func_80A599E8.s") + if (this->actor.params == ENWATEREFFECT_777) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_WATER_EFFECT, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, this->actor.shape.rot.z, 0x30A); + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_WATER_EFFECT, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, this->actor.shape.rot.z, 0x30B); + } else if (this->actor.params == ENWATEREFFECT_778) { + this->unk_DC4 = -3; + } else if (this->actor.params == ENWATEREFFECT_779) { + this->unk_DC4 = -6; + } else if (this->actor.params == ENWATEREFFECT_780) { + this->unk_DC4 = 23; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/func_80A59C04.s") + this->unk_E08[1] = 0.2f; + this->unk_E18[1] = -0.017f; + this->unk_E08[2] = 0.2f; + this->unk_E18[2] = -0.018f; + this->unk_E08[3] = 0.2f; + this->unk_E18[3] = -0.019f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/func_80A5A184.s") + this->unk_DC8[1].y = 1.0f; + this->unk_DC8[2].y = 1.0f; + this->unk_DC8[3].y = 1.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/func_80A5A534.s") + this->unk_E2C = 255.0f; + this->unk_E34 = 255.0f; + this->unk_E30 = 200.0f; + this->unk_E38 = 191.25f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Water_Effect/func_80A5A6B8.s") +void EnWaterEffect_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +void EnWaterEffect_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnWaterEffect* this = THIS; + Player* player = GET_PLAYER(globalCtx); + EnWaterEffectStruct* ptr = &this->unk_144[0]; + s16 i; + s16 j; + s32 phi_v0; + Vec3f spA4; + Vec3f sp98; + u8 phi_v1; + Vec3f sp88; + + if (!Flags_GetSwitch(globalCtx, this->actor.params)) { + this->unk_DC4++; + if ((this->unk_DC4 % 32) == 0) { + if (Rand_ZeroOne() < 0.5f) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 10.0f, 40.0f, 4); + sp88.x = randPlusMinusPoint5Scaled(50.0f) + this->actor.world.pos.x; + sp88.y = this->actor.world.pos.y; + sp88.z = randPlusMinusPoint5Scaled(50.0f) + this->actor.world.pos.z; + if ((this->actor.world.pos.y + this->actor.depthInWater) <= this->actor.floorHeight) { + phi_v1 = 0; + } else { + phi_v1 = 1; + this->actor.floorHeight = this->actor.world.pos.y + this->actor.depthInWater; + } + func_80A587A0(this, &sp88, phi_v1); + } + } + } + + for (i = 0; i < ARRAY_COUNT(this->unk_144) / 2; i++, ptr++) { + if (ptr->unk_00 != 0) { + ptr->unk_01++; + + ptr->unk_04.x += ptr->unk_10.x; + ptr->unk_04.y += ptr->unk_10.y; + ptr->unk_04.z += ptr->unk_10.z; + ptr->unk_10.y += ptr->unk_1C.y; + + Math_ApproachF(&ptr->unk_38, (ptr->unk_01 & 6) ? 80.0f : 200.0f, 1.0f, 80); + + if (ptr->unk_00 == 1) { + ptr->unk_2C.z += 0.15f; + Math_ApproachF(&ptr->unk_2C.x, 0.03f, 0.5f, 0.005f); + Math_ApproachF(&ptr->unk_2C.y, 0.5f, 0.5f, 0.02f); + + if (ptr->unk_2C.y > 0.15f) { + ptr->unk_1C.y = -1.0f; + if (ptr->unk_10.y < -20.0f) { + ptr->unk_10.y = -20.0f; + } + } + + if ((fabsf(ptr->unk_04.x - player->actor.world.pos.x) < 15.0f) && + (fabsf(ptr->unk_04.z - player->actor.world.pos.z) < 15.0f) && + (player->actor.world.pos.y < ptr->unk_04.y) && + ((ptr->unk_04.y - player->actor.world.pos.y) < 40.0f)) { + phi_v0 = true; + } else { + phi_v0 = false; + } + + if ((ptr->unk_04.y <= this->actor.floorHeight) || phi_v0) { + + if (phi_v0) { + ptr->unk_00 = 0; + Audio_PlaySoundAtPosition(globalCtx, &ptr->unk_04, 30, NA_SE_EV_BOMB_DROP_WATER); + } else { + ptr->unk_04.y = this->actor.floorHeight; + if (ptr->unk_2A == 0) { + Audio_PlaySoundAtPosition(globalCtx, &ptr->unk_04, 30, NA_SE_EV_WATERDROP_GRD); + ptr->unk_00 = 3; + ptr->unk_2C.x = 0.1f; + ptr->unk_2C.y = 0.6f; + ptr->unk_10 = D_80A5AFB0; + ptr->unk_1C = D_80A5AFB0; + ptr->unk_3C = 200; + ptr->unk_28 = 9; + Math_Vec3f_Copy(&sp98, &ptr->unk_04); + sp98.y += 3.0f; + EffectSsGSplash_Spawn(globalCtx, &sp98, NULL, NULL, 1, 100); + } else { + ptr->unk_00 = 0; + Audio_PlaySoundAtPosition(globalCtx, &ptr->unk_04, 30, NA_SE_EV_WATERDROP); + EffectSsGRipple_Spawn(globalCtx, &ptr->unk_04, 70, 500, 0); + EffectSsGRipple_Spawn(globalCtx, &ptr->unk_04, 70, 500, 10); + Math_Vec3f_Copy(&sp98, &ptr->unk_04); + sp98.y += 10.0f; + EffectSsGSplash_Spawn(globalCtx, &sp98, NULL, NULL, 1, 300); + } + } + + for (j = 0; j < 12; j++) { + Matrix_InsertYRotation_f((2.0f * (j * M_PI)) / 5.5f, MTXMODE_NEW); + Matrix_GetStateTranslationAndScaledZ(Rand_ZeroFloat(1.5f) + 1.5f, &spA4); + spA4.y = Rand_ZeroFloat(4.0f) + 2.0f; + func_80A58908(this, &ptr->unk_04, &spA4, ptr->unk_2A); + } + } + } else if (ptr->unk_00 == 2) { + ptr->unk_2C.z += 0.15f; + if (ptr->unk_10.y < -8.0f) { + ptr->unk_10.y = -8.0f; + } + + if (ptr->unk_10.y < 0.0f) { + if (ptr->unk_04.y <= this->actor.floorHeight) { + ptr->unk_04.y = this->actor.floorHeight; + if (ptr->unk_2A == 0) { + ptr->unk_00 = 3; + ptr->unk_2C.x = 0.05f; + ptr->unk_2C.y = 0.2f; + ptr->unk_10 = D_80A5AFB0; + ptr->unk_1C = D_80A5AFB0; + ptr->unk_3C = 150; + ptr->unk_28 = Rand_ZeroFloat(5.0f) + 7.0f; + } else { + EffectSsGRipple_Spawn(globalCtx, &ptr->unk_04, 0, 200, 0); + ptr->unk_00 = 0; + } + } + } + } else if (ptr->unk_00 == 3) { + Math_ApproachF(&ptr->unk_2C.x, ptr->unk_2C.y, 0.1f, 0.6f); + ptr->unk_3C -= ptr->unk_28; + if (ptr->unk_3C <= 0) { + ptr->unk_3C = 0; + ptr->unk_00 = 0; + } + } + } + } +} + +void EnWaterEffect_Draw(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + EnWaterEffect* this = THIS; + s32 pad; + EnWaterEffectStruct* backupPtr = &this->unk_144[0]; + EnWaterEffectStruct* ptr = backupPtr; + u8 phi_s4 = false; + s16 i; + + OPEN_DISPS(gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + + for (i = 0; i < ARRAY_COUNT(this->unk_144) / 2; i++, ptr++) { + if ((ptr->unk_00 == 1) || (ptr->unk_00 == 2)) { + if (!phi_s4) { + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0); + + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gameplay_keep_Tex_08DBE0)); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_004260); + gDPSetEnvColor(POLY_XLU_DISP++, 250, 250, 255, 0); + phi_s4++; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (u8)ptr->unk_38, (u8)(((void)0, ptr->unk_38) + 55.0f), 225, 150); + + Matrix_InsertTranslation(ptr->unk_04.x, ptr->unk_04.y, ptr->unk_04.z, MTXMODE_NEW); + + if (ptr->unk_00 == 1) { + Matrix_RotateY(func_800DFC68(GET_ACTIVE_CAM(globalCtx)), MTXMODE_APPLY); + } else { + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + } + + Matrix_Scale(ptr->unk_2C.x, ptr->unk_2C.y, 1.0f, MTXMODE_APPLY); + Matrix_InsertZRotation_f(ptr->unk_2C.z, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_0042B0); + } + } + + phi_s4 = false; + ptr = backupPtr; + + for (i = 0; i < ARRAY_COUNT(this->unk_144) / 2; i++, ptr++) { + if (ptr->unk_00 == 3) { + if (!phi_s4) { + func_8012C448(gfxCtx); + + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gameplay_keep_Tex_08DBE0)); + gDPSetEnvColor(POLY_XLU_DISP++, 250, 250, 255, 0); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_004260); + phi_s4++; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (u8)ptr->unk_38, (u8)(((void)0, ptr->unk_38) + 55.0f), 225, + ptr->unk_3C); + + Matrix_InsertTranslation(ptr->unk_04.x, ptr->unk_04.y, ptr->unk_04.z, MTXMODE_NEW); + Matrix_Scale(ptr->unk_2C.x, 1.0f, ptr->unk_2C.x, MTXMODE_APPLY); + Matrix_InsertYRotation_f(ptr->unk_2C.z, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_0042F8); + } + } + + CLOSE_DISPS(gfxCtx); +} + +void func_80A599E8(EnWaterEffect* this, Vec3f* arg1, u8 arg2) { + s16 i; + EnWaterEffectStruct* ptr = &this->unk_144[0]; + + for (i = 0; i < ARRAY_COUNT(this->unk_144); i++, ptr++) { + if (ptr->unk_00 == 0) { + ptr->unk_00 = 4; + ptr->unk_04 = *arg1; + + ptr->unk_1C = D_80A5AFB0; + ptr->unk_10 = D_80A5AFB0; + + if ((arg2 == 0) || (arg2 == 2)) { + ptr->unk_1C.y = -1.0f; + } + + if (arg2 >= 2) { + if (arg2 == 2) { + ptr->unk_10.x = randPlusMinusPoint5Scaled(10.0f); + ptr->unk_10.y = Rand_ZeroFloat(3.0f) + 5.0f; + ptr->unk_10.z = randPlusMinusPoint5Scaled(10.0f); + } + ptr->unk_2C.z = 0.0017f; + ptr->unk_2C.x = 0.003f; + ptr->unk_2C.y = 0.0018f; + } else { + ptr->unk_2C.z = 0.003f; + ptr->unk_2C.x = 0.003f; + ptr->unk_2C.y = 0.003f; + } + ptr->unk_38 = 255.0f; + ptr->unk_28 = Rand_ZeroFloat(0x10000); + ptr->unk_3C = 255; + ptr->unk_01 = Rand_ZeroFloat(200.0f); + ptr->unk_2A = arg2; + break; + } + } +} + +void func_80A59C04(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnWaterEffect* this = THIS; + s16 i; + s16 j; + f32 temp_f0_2; + Player* player = GET_PLAYER(globalCtx); + Vec3f sp90; + Actor* rotaryRoom = globalCtx->actorCtx.actorList[ACTORCAT_BG].first; + CollisionPoly* sp88; + EnWaterEffectStruct* ptr = &this->unk_144[0]; + u8 phi_s5; + Vec3f sp74; + + while (rotaryRoom != NULL) { + if (rotaryRoom->id == ACTOR_BG_IKANA_ROTARYROOM) { + break; + } + rotaryRoom = rotaryRoom->next; + } + + if (this->unk_DC6 != 0) { + this->unk_DC6--; + } + + if ((rotaryRoom != NULL) && Flags_GetSwitch(globalCtx, (rotaryRoom->params >> 1) & 0x7F)) { + this->unk_DC6 = Rand_ZeroFloat(150.0f) + 100.0f; + } else if (!func_801690CC(globalCtx)) { + this->unk_DC4++; + if (this->unk_DC6 == 0) { + this->unk_DC6 = Rand_ZeroFloat(150.0f) + 100.0f; + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 10.0f, 40.0f, 4); + sp74.x = randPlusMinusPoint5Scaled(50.0f) + this->actor.world.pos.x; + sp74.y = this->actor.world.pos.y; + sp74.z = randPlusMinusPoint5Scaled(50.0f) + this->actor.world.pos.z; + func_80A599E8(this, &sp74, 0); + } + } + + for (i = 0; i < ARRAY_COUNT(this->unk_144); i++, ptr++) { + phi_s5 = false; + + if (ptr->unk_00 != 0) { + ptr->unk_01++; + + ptr->unk_04.x += ptr->unk_10.x; + ptr->unk_04.y += ptr->unk_10.y; + ptr->unk_04.z += ptr->unk_10.z; + ptr->unk_10.y = ptr->unk_10.y + ptr->unk_1C.y; + + if (ptr->unk_00 == 4) { + if (ptr->unk_2A > 0) { + if (ptr->unk_2A == 1) { + Math_ApproachF(&ptr->unk_2C.x, 0.001f, 0.5f, 0.0002f); + } + + if (ptr->unk_2A & 1) { + Math_ApproachZeroF(&ptr->unk_38, 1.0f, 30.0f); + if (ptr->unk_2A == 1) { + ptr->unk_3C -= 20; + } else { + ptr->unk_3C -= 10; + } + if (ptr->unk_3C <= 0) { + ptr->unk_00 = 0; + } + Math_ApproachZeroF(&ptr->unk_10.x, 1.0f, 1.0f); + Math_ApproachZeroF(&ptr->unk_10.z, 1.0f, 1.0f); + } + } + + if ((ptr->unk_2A % 2) == 0) { + if (ptr->unk_2A == 0) { + func_80A599E8(this, &ptr->unk_04, 1); + } else if ((ptr->unk_01 & 1) == 0) { + func_80A599E8(this, &ptr->unk_04, 3); + } + + if (ptr->unk_10.y < -20.0f) { + ptr->unk_10.y = -20.0f; + } + + ptr->unk_28 += 0x800; + if ((fabsf(ptr->unk_04.x - player->actor.world.pos.x) < 20.0f) && + (fabsf(ptr->unk_04.z - player->actor.world.pos.z) < 20.0f) && + (fabsf(ptr->unk_04.y - (player->actor.world.pos.y + 25.0f)) < 30.0f)) { + phi_s5 = true; + if ((player->transformation != PLAYER_FORM_GORON) && !player->isBurning) { + func_800B8D50(globalCtx, &this->actor, 2.0f, Rand_ZeroFloat(0x10000), 0.0f, 0x10); + for (j = 0; j < ARRAY_COUNT(player->flameTimers); j++) { + player->flameTimers[j] = Rand_S16Offset(0, 200); + } + player->isBurning = true; + func_800B8E58(&player->actor, player->ageProperties->unk_92 + NA_SE_VO_LI_DEMO_DAMAGE); + } + } + + Math_Vec3f_Copy(&sp90, &ptr->unk_04); + sp90.y += 30.0f; + + temp_f0_2 = BgCheck_EntityRaycastFloor1(&globalCtx->colCtx, &sp88, &sp90); + if (fabsf(temp_f0_2 - this->actor.floorHeight) > 200.0f) { + phi_s5 = true; + } + + if ((ptr->unk_04.y <= temp_f0_2) || (phi_s5 != 0)) { + if (phi_s5 == 0) { + ptr->unk_04.y = temp_f0_2; + } + ptr->unk_10.y = 0.0f; + ptr->unk_1C.y = 0.0f; + if (ptr->unk_2A == 0) { + for (j = 0; j < 5; j++) { + func_80A599E8(this, &ptr->unk_04, 2); + } + Audio_PlaySoundAtPosition(globalCtx, &ptr->unk_04, 30, NA_SE_EV_PLANT_BROKEN); + } + ptr->unk_2A++; + } + } + } + } + } +} + +void func_80A5A184(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnWaterEffect* this = THIS; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + EnWaterEffectStruct* ptr = &this->unk_144[0]; + u8 flag = false; + s16 i; + + OPEN_DISPS(gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + + for (i = 0; i < ARRAY_COUNT(this->unk_144); i++, ptr++) { + if (ptr->unk_00 == 4) { + if (!flag) { + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_004340); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 10, 0, 0); + POLY_OPA_DISP = Gfx_SetFog(POLY_OPA_DISP, 255, 0, 0, 255, 500, 3600); + flag++; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0x80, 0x80, (u8)ptr->unk_38, 0, 0, (u8)ptr->unk_3C); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, 0, (ptr->unk_01 * -20) & 0x1FF, + 0x20, 0x80)); + + Matrix_InsertTranslation(ptr->unk_04.x, ptr->unk_04.y, ptr->unk_04.z, MTXMODE_NEW); + + if (ptr->unk_2A >= 2) { + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + } else { + Matrix_RotateY(func_800DFC68(GET_ACTIVE_CAM(globalCtx)), MTXMODE_APPLY); + } + + Matrix_Scale(ptr->unk_2C.x, ptr->unk_2C.y, 1.0f, MTXMODE_APPLY); + + if ((i & 1) != 0) { + Matrix_InsertYRotation_f(M_PI, MTXMODE_APPLY); + } + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_0043E8); + + if ((ptr->unk_2A & 1) == 0) { + Matrix_InsertTranslation(ptr->unk_04.x, ptr->unk_04.y + 5.0f, ptr->unk_04.z, MTXMODE_NEW); + Matrix_InsertXRotation_s(ptr->unk_28, MTXMODE_APPLY); + Matrix_Scale(ptr->unk_2C.z, ptr->unk_2C.z, ptr->unk_2C.z, MTXMODE_APPLY); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_06AB30); + } + } + } + + POLY_OPA_DISP = func_801660B8(globalCtx, POLY_OPA_DISP); + + CLOSE_DISPS(gfxCtx); +} + +void func_80A5A534(Actor* thisx, GlobalContext* globalCtx) { + EnWaterEffect* this = THIS; + s32 i; + + if (this->unk_E38 < 1.0f) { + Actor_MarkForDeath(&this->actor); + } + + this->unk_DC4++; + + if (this->unk_DC4 >= 0) { + for (i = 1; i < 4; i++) { + this->unk_DC8[i].z += this->unk_E08[i]; + this->unk_E08[i] += this->unk_E18[i]; + if (this->unk_DC8[i].z <= 0.0f) { + this->unk_DC8[i].z = 0.0f; + this->unk_E08[i] = 0.0f; + } + } + + Math_ApproachF(&this->unk_DC8[1].y, 20.0f, 1.0f, 0.025f); + Math_ApproachF(&this->unk_DC8[2].y, 20.0f, 1.0f, 0.075f); + Math_ApproachF(&this->unk_DC8[3].y, 20.0f, 1.0f, 0.1f); + + if (this->unk_DC4 >= 24) { + Math_ApproachF(&this->unk_DC8[4].y, 2.0f, 0.1f, 0.2f); + Math_ApproachZeroF(&this->unk_E2C, 1.0f, 26.0f); + Math_ApproachZeroF(&this->unk_E30, 1.0f, 26.0f); + Math_ApproachZeroF(&this->unk_E34, 1.0f, 24.0f); + if (this->unk_DC4 >= 50) { + Math_ApproachZeroF(&this->unk_E38, 1.0f, 3.75f); + } + } + } +} + +void func_80A5A6B8(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnWaterEffect* this = THIS; + EnWaterEffectStruct* ptr = &this->unk_144[0]; + u8 phi_s4 = false; + s16 i; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, MTXMODE_NEW); + Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + func_8012C2DC(globalCtx->state.gfxCtx); + + gDPSetEnvColor(POLY_XLU_DISP++, 165, 235, 255, 128); + + Matrix_StatePush(); + Matrix_StatePush(); + Matrix_StatePush(); + + if ((this->actor.params == ENWATEREFFECT_777) || (this->actor.params == ENWATEREFFECT_778)) { + if (this->unk_E2C > 1.0f) { + func_8012C2DC(globalCtx->state.gfxCtx); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_water_effect_Matanimheader_000DE0)); + Matrix_Scale(this->unk_DC8[1].y, this->unk_DC8[1].z, this->unk_DC8[1].y, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)this->unk_E2C); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_000420); + } + + Matrix_StatePop(); + + if (this->unk_E30 > 1.0f) { + func_8012C2DC(globalCtx->state.gfxCtx); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_water_effect_Matanimheader_000E0C)); + Matrix_Scale(this->unk_DC8[2].y, this->unk_DC8[2].z, this->unk_DC8[2].y, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)this->unk_E30); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_000730); + } + Matrix_StatePop(); + } else { + Matrix_StatePop(); + Matrix_StatePop(); + } + + if ((this->unk_E34 > 1.0f) && (this->actor.params != ENWATEREFFECT_780)) { + func_8012C2DC(globalCtx->state.gfxCtx); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_water_effect_Matanimheader_000E40)); + Matrix_Scale(this->unk_DC8[3].y, this->unk_DC8[3].z, this->unk_DC8[3].y, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)this->unk_E34); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_000A48); + } + + Matrix_StatePop(); + + if ((this->actor.params == ENWATEREFFECT_777) || (this->actor.params == ENWATEREFFECT_780)) { + func_8012C2DC(globalCtx->state.gfxCtx); + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_water_effect_Matanimheader_000E58)); + Matrix_Scale(this->unk_DC8[4].y, this->unk_DC8[4].z, this->unk_DC8[4].y, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)this->unk_E38); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_000CD8); + } + + if (this->actor.params == ENWATEREFFECT_777) { + func_8012C2DC(globalCtx->state.gfxCtx); + + for (i = 0; i < ARRAY_COUNT(this->unk_144) / 2; i++, ptr++) { + if (ptr->unk_00 == 3) { + if (!phi_s4) { + func_8012C448(globalCtx->state.gfxCtx); + + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gameplay_keep_Tex_08DBE0)); + gDPSetEnvColor(POLY_XLU_DISP++, 250, 250, 255, 0); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_004260); + phi_s4++; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, (u8)ptr->unk_38, (u8)(((void)0, ptr->unk_38) + 55.0f), 225, + ptr->unk_3C); + + Matrix_InsertTranslation(ptr->unk_04.x, ptr->unk_04.y, ptr->unk_04.z, MTXMODE_NEW); + Matrix_Scale(ptr->unk_2C.x, 1.0f, ptr->unk_2C.x, MTXMODE_APPLY); + Matrix_InsertYRotation_f(ptr->unk_2C.z, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_water_effect_DL_0042F8); + } + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.h b/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.h index f7805ddca..774b858cd 100644 --- a/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.h +++ b/src/overlays/actors/ovl_En_Water_Effect/z_en_water_effect.h @@ -5,9 +5,41 @@ struct EnWaterEffect; +typedef struct { + /* 0x00 */ u8 unk_00; + /* 0x01 */ u8 unk_01; + /* 0x04 */ Vec3f unk_04; + /* 0x10 */ Vec3f unk_10; + /* 0x1C */ Vec3f unk_1C; + /* 0x28 */ s16 unk_28; + /* 0x2A */ u8 unk_2A; + /* 0x2C */ Vec3f unk_2C; + /* 0x38 */ f32 unk_38; + /* 0x3C */ s16 unk_3C; +} EnWaterEffectStruct; // size = 0x40 + +enum { + /* 0x 1 */ ENWATEREFFECT_1 = 1, + /* 0x309 */ ENWATEREFFECT_777 = 777, + /* 0x30A */ ENWATEREFFECT_778, + /* 0x30B */ ENWATEREFFECT_779, + /* 0x30C */ ENWATEREFFECT_780, +}; + typedef struct EnWaterEffect { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0xCF8]; + /* 0x144 */ EnWaterEffectStruct unk_144[50]; + /* 0xDC4 */ s16 unk_DC4; + /* 0xDC6 */ s16 unk_DC6; + /* 0xDC8 */ Vec3f unk_DC8[5]; + /* 0xE04 */ UNK_TYPE1 unk_E04[4]; + /* 0xE04 */ f32 unk_E08[4]; + /* 0xE18 */ f32 unk_E18[4]; + /* 0xE28 */ UNK_TYPE1 unk_E28[4]; + /* 0xE2C */ f32 unk_E2C; + /* 0xE30 */ f32 unk_E30; + /* 0xE34 */ f32 unk_E34; + /* 0xE38 */ f32 unk_E38; } EnWaterEffect; // size = 0xE3C extern const ActorInit En_Water_Effect_InitVars; diff --git a/src/overlays/actors/ovl_En_Wf/z_en_wf.c b/src/overlays/actors/ovl_En_Wf/z_en_wf.c index 0ff4d527b..931d283e4 100644 --- a/src/overlays/actors/ovl_En_Wf/z_en_wf.c +++ b/src/overlays/actors/ovl_En_Wf/z_en_wf.c @@ -1,7 +1,7 @@ /* * File: z_en_wf.c * Overlay: ovl_En_Wf - * Description: Wolfos + * Description: Wolfos and White Wolfos */ #include "z_en_wf.h" @@ -508,7 +508,7 @@ void func_80990C6C(EnWf* this, GlobalContext* globalCtx, s32 arg2) { sp88.x = randPlusMinusPoint5Scaled(50.0f) + this->actor.world.pos.x; sp88.y = Rand_ZeroFloat(5.0f) + this->actor.world.pos.y; sp88.z = randPlusMinusPoint5Scaled(50.0f) + this->actor.world.pos.z; - func_800B0F18(globalCtx, &sp88, &D_801D15B0, &D_809942DC, phi_s1, phi_s1, phi_s6, 5, + func_800B0F18(globalCtx, &sp88, &gZeroVec3f, &D_809942DC, phi_s1, phi_s1, phi_s6, 5, Rand_ZeroFloat(5.0f) + 14.0f); } } diff --git a/src/overlays/actors/ovl_En_Wiz/z_en_wiz.h b/src/overlays/actors/ovl_En_Wiz/z_en_wiz.h index 822ceadd9..1388260cf 100644 --- a/src/overlays/actors/ovl_En_Wiz/z_en_wiz.h +++ b/src/overlays/actors/ovl_En_Wiz/z_en_wiz.h @@ -11,7 +11,13 @@ typedef struct EnWiz { /* 0x0000 */ Actor actor; /* 0x0144 */ char unk_144[0x268]; /* 0x03AC */ EnWizActionFunc actionFunc; - /* 0x03B0 */ char unk_3B0[0x9D0]; + /* 0x03B0 */ char unk_3B0[0xA]; + /* 0x03BA */ s16 unk_3BA; + /* 0x03BC */ char unk_3BC[0x8C]; + /* 0x0448 */ s32 unk_448; + /* 0x044C */ char unk_44C[0x2FE]; + /* 0x074A */ s16 unk_74A; + /* 0x074C */ char unk_74C[0x634]; } EnWiz; // size = 0xD80 extern const ActorInit En_Wiz_InitVars; diff --git a/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.c b/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.c index 480bdaeaa..4853331bb 100644 --- a/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.c +++ b/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.c @@ -5,6 +5,8 @@ */ #include "z_en_wiz_fire.h" +#include "overlays/actors/ovl_En_Wiz/z_en_wiz.h" +#include "objects/object_wiz/object_wiz.h" #define FLAGS 0x08000015 @@ -21,8 +23,13 @@ void func_80A49F38(EnWizFire* this, GlobalContext* globalCtx); void func_80A49FD8(EnWizFire* this, GlobalContext* globalCtx); void func_80A4A11C(EnWizFire* this, GlobalContext* globalCtx); void func_80A4A608(EnWizFire* this, GlobalContext* globalCtx); +void func_80A4BAB4(Actor* thisx, GlobalContext* globalCtx); +void func_80A4BC74(EnWizFire* this, Vec3f* arg1, Vec3f* arg2); +void func_80A4BDDC(EnWizFire* this, GlobalContext* globalCtx); +void func_80A4BF78(EnWizFire* this, GlobalContext* globalCtx); + +static s32 D_80A4C1C0 = 0; -#if 0 const ActorInit En_Wiz_Fire_InitVars = { ACTOR_EN_WIZ_FIRE, ACTORCAT_ENEMY, @@ -35,51 +42,838 @@ const ActorInit En_Wiz_Fire_InitVars = { (ActorFunc)EnWizFire_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A4C1E4 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_ENEMY, AC_ON | AC_TYPE_PLAYER, OC1_NONE, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0xF7CFFFFF, 0x09, 0x10 }, { 0x01001202, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_ENEMY, + AC_ON | AC_TYPE_PLAYER, + OC1_NONE, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0xF7CFFFFF, 0x09, 0x10 }, + { 0x01001202, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 0, 0, 0, { 0, 0, 0 } }, }; -#endif +void EnWizFire_Init(Actor* thisx, GlobalContext* globalCtx) { + EnWizFire* this = THIS; -extern ColliderCylinderInit D_80A4C1E4; + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + this->unk_162 = this->actor.params; + this->actor.targetMode = 3; + this->unk_172 = 10; + this->unk_1FC = 255.0f; + this->actor.flags &= ~1; -extern UNK_TYPE D_06000FD8; -extern UNK_TYPE D_06002630; -extern UNK_TYPE D_06002B40; -extern UNK_TYPE D_06003120; -extern UNK_TYPE D_06005190; + if (!func_8012405C(globalCtx)) { + this->collider.info.toucher.dmgFlags = 0x20000000; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/EnWizFire_Init.s") + switch (this->unk_162) { + case 4: + this->unk_166 = 1; + this->collider.info.toucher.damage = 8; + this->collider.info.toucher.effect = 2; + this->collider.info.bumper.dmgFlags = (0x1000000 | 0x800 | 0x200 | 0x2); + this->unk_162 = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/EnWizFire_Destroy.s") + case 0: + if (this->unk_162 == 4) { + this->unk_162 = 0; + this->collider.info.toucher.damage = 8; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A4984C.s") + case 1: + case 3: + this->actionFunc = func_80A4984C; + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A49A44.s") + case 2: + this->actor.draw = func_80A4BAB4; + this->unk_170 = Rand_S16Offset(0, 10000); + this->unk_160 = 1; + this->collider.info.toucher.damage = 2; + this->actionFunc = func_80A49F38; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A49F38.s") +void EnWizFire_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnWizFire* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A49FD8.s") + if (this->unk_162 == 0) { + globalCtx->envCtx.unk_8C.fogColor[2] = 0; + globalCtx->envCtx.unk_8C.fogColor[1] = globalCtx->envCtx.unk_8C.fogColor[2]; + globalCtx->envCtx.unk_8C.fogColor[0] = globalCtx->envCtx.unk_8C.fogColor[2]; + globalCtx->envCtx.unk_8C.diffuseColor2[2] = globalCtx->envCtx.unk_8C.fogColor[2]; + globalCtx->envCtx.unk_8C.diffuseColor2[1] = globalCtx->envCtx.unk_8C.fogColor[2]; + globalCtx->envCtx.unk_8C.diffuseColor2[0] = globalCtx->envCtx.unk_8C.fogColor[2]; + globalCtx->envCtx.unk_8C.diffuseColor1[2] = globalCtx->envCtx.unk_8C.fogColor[2]; + globalCtx->envCtx.unk_8C.diffuseColor1[1] = globalCtx->envCtx.unk_8C.fogColor[2]; + globalCtx->envCtx.unk_8C.diffuseColor1[0] = globalCtx->envCtx.unk_8C.fogColor[2]; + globalCtx->envCtx.unk_8C.ambientColor[2] = globalCtx->envCtx.unk_8C.fogColor[2]; + globalCtx->envCtx.unk_8C.ambientColor[1] = globalCtx->envCtx.unk_8C.fogColor[2]; + globalCtx->envCtx.unk_8C.ambientColor[0] = globalCtx->envCtx.unk_8C.fogColor[2]; + globalCtx->envCtx.unk_8C.fogNear = globalCtx->envCtx.unk_8C.fogColor[2]; + } + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A4A11C.s") +void func_80A4984C(EnWizFire* this, GlobalContext* globalCtx) { + Vec3f sp44 = { 0.0f, 0.0f, 0.0f }; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A4A608.s") + for (i = 0; i < ARRAY_COUNT(this->unk_178); i++) { + this->unk_178[i] = this->actor.world.pos; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/EnWizFire_Update.s") + this->unk_16E = 0; + Matrix_StatePush(); + Matrix_RotateY(this->actor.world.rot.y, MTXMODE_NEW); + Matrix_InsertXRotation_s(this->actor.world.rot.x, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A4B0C8.s") + if (this->unk_162 != 0) { + sp44.z = randPlusMinusPoint5Scaled(2.0f) + 8.0f; + } else { + sp44.z = 12.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A4B33C.s") + Matrix_MultiplyVector3fByState(&sp44, &this->actor.velocity); + Matrix_StatePop(); + this->actor.world.rot.x = this->actor.world.rot.y = this->actor.world.rot.z = 0; + this->unk_168 = 50; + if (this->unk_162 != 0) { + this->actor.velocity.y = 10.0f; + this->actor.gravity = -1.0f; + this->unk_150 = 0.01f; + } else { + this->unk_150 = 0.02f; + this->unk_168 = 100; + } + this->unk_160 = 0; + this->actionFunc = func_80A49A44; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/EnWizFire_Draw.s") +void func_80A49A44(EnWizFire* this, GlobalContext* globalCtx) { + Vec3f sp54 = { 0.0f, 0.0f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A4BAB4.s") + this->actor.world.rot.z += 5000; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A4BC74.s") + if (this->unk_162 != 0) { + this->unk_150 = 0.01f; + } else { + this->unk_150 = 0.02f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A4BDDC.s") + if ((this->unk_168 == 0) && (this->unk_14C < 0.001f)) { + Math_Vec3f_Copy(&this->actor.velocity, &gZeroVec3f); + this->unk_160 = 3; + this->unk_16A = 0; + this->actionFunc = func_80A4A608; + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Wiz_Fire/func_80A4BF78.s") + if (this->unk_168 == 0) { + this->unk_150 = 0.0f; + } + + Math_ApproachF(&this->unk_14C, this->unk_150, 0.2f, 0.01f); + + if (this->unk_172 == 0) { + if ((this->actor.bgCheckFlags & 8) && (this->unk_162 == 0) && (this->unk_168 != 0) && + (this->actor.bgCheckFlags & 8)) { + D_80A4C1C0 = 0; + this->unk_168 = 0; + this->unk_150 = 0.0f; + } + } + + if ((this->actor.bgCheckFlags & 1) && (this->unk_16A == 0)) { + s32 i; + s16 phi_s0; + s32 temp; + + if (this->unk_162 == 1) { + this->unk_16A = 10; + + Matrix_StatePush(); + Matrix_RotateY((s16)randPlusMinusPoint5Scaled(0x100) + this->actor.world.rot.y, MTXMODE_NEW); + sp54.z = randPlusMinusPoint5Scaled(2.0f) + 8.0f; + Matrix_MultiplyVector3fByState(&sp54, &this->actor.velocity); + Matrix_StatePop(); + + this->actor.velocity.y = 6.0f; + this->actor.gravity = -0.7f; + + if (this->unk_164 == 0) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_WIZ_FIRE, this->actor.world.pos.x, + this->actor.world.pos.y - 10.0f, this->actor.world.pos.z, 0, 0, 0, 2); + this->unk_164 = 1; + } + + this->unk_168 = 0; + this->unk_14C = 0.0f; + Math_Vec3f_Copy(&this->actor.velocity, &gZeroVec3f); + this->unk_160 = 3; + this->unk_16A = 0; + this->actionFunc = func_80A4A608; + return; + } + + if ((this->unk_162 == 0) && (this->unk_168 != 0)) { + if (this->actor.floorBgId == BGCHECK_SCENE) { + this->unk_16A = 100; + if (this->unk_166 == 0) { + phi_s0 = 0; + + for (i = 0; i < 5; i++) { + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_WIZ_FIRE, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, phi_s0, 0, 1); + phi_s0 += BINANG_ADD((s32)randPlusMinusPoint5Scaled(0x1000), 0x3333); + } + + Audio_PlayActorSound2(&this->actor, NA_SE_IT_BOMB_EXPLOSION); + this->unk_16A = Rand_S16Offset(70, 30); + if (this->unk_16A != 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_WIZ_EXP - SFX_FLAG); + } + } else if (this->unk_16A != 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + } + Math_Vec3f_Copy(&this->actor.velocity, &gZeroVec3f); + this->unk_168 = 0; + this->unk_160 = 2; + this->unk_14C = 0.0f; + this->actionFunc = func_80A4A11C; + } + return; + } + } + + if ((this->unk_162 != 3) && (this->unk_168 != 0)) { + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + if (this->collider.info.acHitInfo->toucher.dmgFlags == 0x1000) { + this->unk_168 = 0; + this->unk_148 = 1; + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 50, NA_SE_EV_ICE_MELT); + } + } + + if (func_8012405C(globalCtx) && (this->collider.base.atFlags & AT_BOUNCED)) { + Audio_PlayActorSound2(&this->actor, NA_SE_IT_SHIELD_REFLECT_MG); + this->collider.base.atFlags &= ~(AT_TYPE_ENEMY | AT_BOUNCED | AT_HIT); + this->collider.base.atFlags |= AT_TYPE_PLAYER; + this->collider.info.toucher.dmgFlags = 0x20; + this->collider.info.toucher.damage = 2; + this->unk_168 = 100; + this->unk_162 = 3; + this->actor.velocity.x *= -1.0f; + this->actor.velocity.y *= -0.5f; + this->actor.velocity.z *= -1.0f; + + if ((this->actor.parent != NULL) && (this->actor.parent->id == ACTOR_EN_WIZ) && + (this->actor.parent->update != NULL)) { + ((EnWiz*)this->actor.parent)->unk_3BA = 0; + } + } + } +} + +void func_80A49F38(EnWizFire* this, GlobalContext* globalCtx) { + this->unk_150 = 0.02f; + this->unk_168 = Rand_S16Offset(50, 50); + this->unk_154 = randPlusMinusPoint5Scaled(1.0f) * 0.007f; + this->unk_158 = randPlusMinusPoint5Scaled(1.0f) * 0.005f; + this->unk_15C = randPlusMinusPoint5Scaled(1.0f) * 0.007f; + this->actionFunc = func_80A49FD8; +} + +void func_80A49FD8(EnWizFire* this, GlobalContext* globalCtx) { + if (this->unk_168 > 10) { + Math_ApproachF(&this->unk_14C, this->unk_150, 0.3f, 0.01f); + } else { + Math_ApproachF(&this->unk_14C, 2.0f * this->unk_150, 0.2f, 0.002f); + Math_ApproachZeroF(&this->unk_1FC, 1.0f, 35.0f); + if ((this->unk_168 == 0) && (this->unk_1FC < 2.0f)) { + Actor_MarkForDeath(&this->actor); + } + return; + } + + if (this->collider.base.acFlags & AC_HIT) { + if (this->unk_168 != 0) { + this->collider.base.acFlags &= ~AC_HIT; + if (this->unk_168 > 10) { + this->unk_168 -= 10; + } + + if (this->collider.info.acHitInfo->toucher.dmgFlags == 0x1000) { + this->unk_168 = 0; + this->unk_148 = 1; + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 50, NA_SE_EV_ICE_MELT); + } + } + } + + if (this->unk_168 != 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_BURN_OUT - SFX_FLAG); + } +} + +void func_80A4A11C(EnWizFire* this, GlobalContext* globalCtx) { + s32 pad; + + if ((this->actor.parent != NULL) && (this->actor.parent->id == ACTOR_EN_WIZ) && + (this->actor.parent->update != NULL) && (this->actor.parent->colChkInfo.health == 0)) { + this->unk_16A = 0; + this->unk_174 = 1; + } + + this->unk_16E++; + + if (this->unk_16E > 10) { + this->unk_16E = 10; + } + + if (this->unk_16A != 0) { + Math_ApproachF(&this->unk_200, 60.0f, 0.5f, 10.0f); + if (this->unk_166 == 1) { + Vec3f sp40 = { 0.0f, 0.0f, 0.0f }; + Vec3f sp34; + + sp40.x = randPlusMinusPoint5Scaled(3.0f) / 10.0f; + sp40.y = 0.23f; + sp40.z = randPlusMinusPoint5Scaled(3.0f) / 10.0f; + + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); + sp34.x += randPlusMinusPoint5Scaled(150.0f); + sp34.z += randPlusMinusPoint5Scaled(150.0f); + + Math_ApproachF(&this->unk_1F0, 0.022f, 0.3f, 0.01f); + this->collider.dim.radius = this->unk_1F0 * 4300.0f; + this->collider.dim.height = 30; + this->collider.dim.yShift = 15; + func_80A4BC74(this, &sp34, &sp40); + Audio_PlayActorSound2(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + return; + } + + Math_ApproachF(&this->unk_1F0, 0.02f, 0.3f, 0.002f); + Math_ApproachF(&this->unk_1F8, 0.02f, 0.3f, 0.002f); + Math_ApproachF(&this->unk_1F4, 0.02f, 0.3f, 0.2f); + this->collider.dim.radius = this->unk_1F0 * 4000.0f; + this->collider.dim.height = this->unk_1F4 * 1850.0f; + this->collider.dim.yShift = -15; + + if (this->collider.dim.height < 2) { + this->collider.dim.height = 2; + } + + if (this->collider.base.acFlags & AC_HIT) { + this->collider.base.acFlags &= ~AC_HIT; + if ((D_80A4C1C0 == 0) && (this->collider.info.acHitInfo->toucher.dmgFlags == 0x1000)) { + D_80A4C1C0 = 1; + this->unk_148 = 1; + this->unk_16A = 0; + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 50, NA_SE_EV_ICE_MELT); + } + } + this->actor.world.pos.y = this->actor.floorHeight + 10.0f; + Actor_SetHeight(&this->actor, 0.0f); + return; + } + + Math_ApproachZeroF(&this->unk_200, 0.2f, 3.0f); + + if (this->unk_166 == 1) { + Math_ApproachZeroF(&this->unk_1F0, 0.046f, 0.001f); + Audio_PlayActorSound2(&this->actor, NA_SE_EV_ICE_FREEZE - SFX_FLAG); + + if (this->unk_164 == 0) { + if ((this->actor.parent != NULL) && (this->actor.parent->id == ACTOR_EN_WIZ) && (this->unk_1F0 < 0.05f)) { + EnWiz* wiz = (EnWiz*)this->actor.parent; + + this->collider.dim.yShift = -15; + this->unk_164 = 1; + wiz->unk_3BA = 0; + } + } + + if ((this->unk_164 != 0) && (this->unk_1F0 < 0.05f)) { + Math_ApproachZeroF(&this->unk_1FC, 1.0f, 5.0f); + } + + if ((this->unk_1F0 < 0.001f) && (this->unk_204 < 0.001f)) { + D_80A4C1C0 = 0; + Actor_MarkForDeath(&this->actor); + } + return; + } + + Math_ApproachZeroF(&this->unk_1F4, 0.1f, 0.01f); + + if (this->unk_1F4 < 0.01f) { + Math_ApproachZeroF(&this->unk_1FC, 1.0f, 10.0f); + if ((this->unk_1FC < 10.0f) && (this->unk_204 < 0.001f)) { + D_80A4C1C0 = 0; + if ((this->actor.parent != NULL) && (this->unk_162 == 0) && (this->actor.parent->id == ACTOR_EN_WIZ) && + (this->actor.parent->update != NULL)) { + EnWiz* wiz = (EnWiz*)this->actor.parent; + + wiz->unk_3BA = 0; + } + Actor_MarkForDeath(&this->actor); + } + } +} + +void func_80A4A608(EnWizFire* this, GlobalContext* globalCtx) { + if (this->unk_16A == 0) { + this->unk_16A = 2; + this->unk_16E++; + if (this->unk_16E >= 6) { + if ((this->actor.parent != NULL) && (this->unk_162 == 0) && (this->actor.parent->id == ACTOR_EN_WIZ)) { + EnWiz* wiz = (EnWiz*)this->actor.parent; + + D_80A4C1C0 = 0; + if (wiz->actor.update != NULL) { + wiz->unk_3BA = 0; + } + } + Actor_MarkForDeath(&this->actor); + } + } +} + +void EnWizFire_Update(Actor* thisx, GlobalContext* globalCtx2) { + static Color_RGB8 D_80A4C234[] = { + { 100, 40, 40 }, { 180, 0x78, 80 }, { 155, 80, 80 }, { 125, 20, 0 }, + { 0, 0, 0 }, { 200, 250, 250 }, { 100, 250, 250 }, { 225, 255, 235 }, + }; + static Color_RGBA8 D_80A4C24C = { 250, 250, 250, 255 }; + static Color_RGBA8 D_80A4C250 = { 180, 180, 180, 255 }; + GlobalContext* globalCtx = globalCtx2; + EnWizFire* this = THIS; + Player* player = GET_PLAYER(globalCtx); + s32 j; + s16 temp_s0; + s16 idx; + + Actor_SetScale(&this->actor, this->unk_14C); + func_80A4BDDC(this, globalCtx); + this->unk_204 = this->unk_200 / 60.0f; + + if (this->unk_162 == 0) { + Actor* wiz = this->actor.parent; + + if ((wiz != NULL) && (wiz->id == ACTOR_EN_WIZ) && (wiz->update != NULL) && (((EnWiz*)wiz)->unk_74A != 2)) { + f32 phi_f0; + + idx = this->unk_166 * 4; + + phi_f0 = 970.0f; + if (this->unk_166 == 0) { + phi_f0 = 968.0f; + } + + globalCtx->envCtx.unk_8C.fogNear = (phi_f0 - (s16)globalCtx->envCtx.unk_C4.fogNear) * this->unk_204; + + globalCtx->envCtx.unk_8C.ambientColor[0] = + ((f32)D_80A4C234[idx].r - globalCtx->envCtx.unk_C4.ambientColor[0]) * this->unk_204; + globalCtx->envCtx.unk_8C.ambientColor[1] = + ((f32)D_80A4C234[idx].g - globalCtx->envCtx.unk_C4.ambientColor[1]) * this->unk_204; + globalCtx->envCtx.unk_8C.ambientColor[2] = + ((f32)D_80A4C234[idx].b - globalCtx->envCtx.unk_C4.ambientColor[2]) * this->unk_204; + + idx++; + globalCtx->envCtx.unk_8C.diffuseColor1[0] = + ((f32)D_80A4C234[idx].r - globalCtx->envCtx.unk_C4.diffuseColor1[0]) * this->unk_204; + globalCtx->envCtx.unk_8C.diffuseColor1[1] = + ((f32)D_80A4C234[idx].g - globalCtx->envCtx.unk_C4.diffuseColor1[1]) * this->unk_204; + globalCtx->envCtx.unk_8C.diffuseColor1[2] = + ((f32)D_80A4C234[idx].b - globalCtx->envCtx.unk_C4.diffuseColor1[2]) * this->unk_204; + + idx++; + globalCtx->envCtx.unk_8C.diffuseColor2[0] = + ((f32)D_80A4C234[idx].r - globalCtx->envCtx.unk_C4.diffuseColor[0]) * this->unk_204; + globalCtx->envCtx.unk_8C.diffuseColor2[1] = + ((f32)D_80A4C234[idx].g - globalCtx->envCtx.unk_C4.diffuseColor[1]) * this->unk_204; + globalCtx->envCtx.unk_8C.diffuseColor2[2] = + ((f32)D_80A4C234[idx].b - globalCtx->envCtx.unk_C4.diffuseColor[2]) * this->unk_204; + + idx++; + globalCtx->envCtx.unk_8C.fogColor[0] = + ((f32)D_80A4C234[idx].r - globalCtx->envCtx.unk_C4.fogColor[0]) * this->unk_204; + globalCtx->envCtx.unk_8C.fogColor[1] = + ((f32)D_80A4C234[idx].g - globalCtx->envCtx.unk_C4.fogColor[1]) * this->unk_204; + globalCtx->envCtx.unk_8C.fogColor[2] = + ((f32)D_80A4C234[idx].b - globalCtx->envCtx.unk_C4.fogColor[2]) * this->unk_204; + } + } + + this->unk_170++; + + this->actionFunc(this, globalCtx); + + this->actor.shape.yOffset = 10.0f; + Actor_ApplyMovement(&this->actor); + + this->unk_178[0] = this->actor.world.pos; + + for (j = 8; j >= 0; j--) { + this->unk_178[j + 1] = this->unk_178[j]; + } + + this->actor.velocity.y += this->actor.gravity; + + if (this->unk_172 != 0) { + this->unk_172--; + } + + if (this->unk_168 != 0) { + this->unk_168--; + } + + if (this->unk_16C != 0) { + this->unk_16C--; + } + + if (this->unk_16A != 0) { + this->unk_16A--; + } + + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 20.0f, 5.0f, 10, 0x1D); + + if (((this->unk_148 != 0) || (D_80A4C1C0 != 0)) && (this->unk_16C == 0)) { + Vec3f sp70; + Vec3f sp64; + Vec3f sp58; + f32 sp54; + s32 i; + + sp70.x = 0.0f; + sp70.y = 1.0f; + sp70.z = 0.0f; + sp64.x = 0.0f; + sp64.y = 1.0f; + sp64.z = 0.0f; + + sp54 = Rand_S16Offset(20, 10); + if (this->unk_162 == 0) { + sp54 = Rand_S16Offset(40, 20); + } + + this->unk_16C = Rand_S16Offset(2, 2); + + for (i = 0; i < 2; i++) { + temp_s0 = Rand_S16Offset(20, 20); + sp58.x = ((f32)((Rand_ZeroOne() < 0.5f) ? -1 : 1) * temp_s0) + this->actor.world.pos.x; + sp58.y = (Rand_ZeroOne() * 20.0f) + this->actor.floorHeight; + temp_s0 = Rand_S16Offset(20, 20); + sp58.z = ((f32)((Rand_ZeroOne() < .5f) ? -1 : 1) * temp_s0) + this->actor.world.pos.z; + func_800B0DE0(globalCtx, &sp58, &sp64, &sp70, &D_80A4C24C, &D_80A4C250, Rand_S16Offset(350, 100), sp54); + } + } + + if (this->unk_160 < 2) { + this->collider.dim.radius = (this->unk_14C * 15.0f) + 25.0f; + this->collider.dim.height = (this->unk_14C * 15.0f) + 25.0f; + this->collider.dim.yShift = (this->unk_14C * -0.75f) - 5.0f; + } + + if (this->unk_162 == 2) { + this->collider.dim.radius = 10; + this->collider.dim.height = this->unk_14C * 5000.0f; + this->collider.dim.yShift = 0; + } + + if (this->collider.base.atFlags & AT_HIT) { + this->collider.base.atFlags &= ~AT_HIT; + if (this->unk_162 == 0) { + Audio_PlayActorSound2(&this->actor, NA_SE_EN_WIZ_LAUGH2); + if (player->invincibilityTimer > 0) { + player->invincibilityTimer += 40; + if (this->unk_166 != 0) { + player->invincibilityTimer += 50; + this->unk_174 = 1; + } + } + } + } + + if ((player->stateFlags2 & 0x4000) && (player->unk_AE8 < 90)) { + player->unk_AE8 = 90; + } + + if ((this->unk_148 == 0) && (D_80A4C1C0 == 0) && ((this->unk_162 != 0) || (this->unk_1FC > 200.0f))) { + Collider_UpdateCylinder(&this->actor, &this->collider); + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + if (player->invincibilityTimer == 0) { + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + } +} + +void func_80A4B0C8(EnWizFire* this, GlobalContext* globalCtx) { + s32 pad; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if ((this->unk_162 == 0) && (this->unk_160 == 2)) { + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.floorHeight, this->actor.world.pos.z, + MTXMODE_NEW); + Matrix_Scale(this->unk_1F0, this->unk_1F0, this->unk_1F0, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPPipeSync(POLY_XLU_DISP++); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (s8)this->unk_1FC); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 40, 30, 80); + gSPDisplayList(POLY_XLU_DISP++, object_wiz_DL_005190); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 215, 215, 215, (s8)this->unk_1FC); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, 128); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, -globalCtx->state.frames & 0x7F, + -globalCtx->state.frames & 0x7F, 0x20, 0x40, 1, globalCtx->state.frames & 0xFF, + globalCtx->state.frames & 0xFF, 0x10, 0x10)); + + Matrix_RotateY(0, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_wiz_DL_005750); + } + + func_80A4BF78(this, globalCtx); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80A4B33C(EnWizFire* this, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if ((this->unk_162 == 0) && (this->unk_160 == 2)) { + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + Matrix_StatePush(); + Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.floorHeight, this->actor.world.pos.z, + MTXMODE_NEW); + Matrix_Scale(this->unk_1F0, this->unk_1F0, this->unk_1F0, MTXMODE_APPLY); + + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, -globalCtx->state.frames % 128, 0, 0x20, 0x20, 1, + (globalCtx->state.frames * 2) % 128, 0, 0x20, 0x20)); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPPipeSync(POLY_XLU_DISP++); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 100, 40, 0, (s8)this->unk_1FC); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 245, 255, 128); + gSPDisplayList(POLY_XLU_DISP++, object_wiz_DL_003120); + + Matrix_StatePop(); + Matrix_StatePush(); + Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.floorHeight, this->actor.world.pos.z, + MTXMODE_NEW); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, globalCtx->state.frames % 128, + (-globalCtx->state.frames * 6) % 256, 0x20, 0x40, 1, + (globalCtx->state.frames * 2) % 128, (-globalCtx->state.frames * 6) % 256, 0x20, + 0x40)); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 80, 0, 0, (s8)this->unk_1FC); + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 0, 0, 0, 100); + + Matrix_Scale(this->unk_1F8, this->unk_1F8, this->unk_1F8, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_wiz_DL_003640); + + Matrix_StatePop(); + Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.floorHeight, this->actor.world.pos.z, 0); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, (-globalCtx->state.frames * 3) % 128, 0, 0x20, 0x20, 1, + 0, (-globalCtx->state.frames * 10) % 256, 0x20, 0x40)); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 100, 50, 0, 255); + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 200, 235, 240, 128); + + Matrix_Scale(this->unk_1F4, this->unk_1F4, this->unk_1F4, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_wiz_DL_003FC0); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void EnWizFire_Draw(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + EnWizFire* this = THIS; + s32 i; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + Matrix_StatePush(); + + for (i = 9; i >= this->unk_16E; i--) { + f32 temp_f20 = this->actor.scale.x - (i * -0.0019f); + + if (temp_f20 > 0.0f) { + if (this->unk_166 == 0) { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255 - (i * 25), 0, 255 - (i * 25)); + gDPSetEnvColor(POLY_XLU_DISP++, 255 - (i * 25), 0, 0, 0); + } else { + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255 - (i * 7), 255 - (i * 3), 255 - (i * 3), 255 - (i * 25)); + gDPSetEnvColor(POLY_XLU_DISP++, 220, 255, 235, 0); + } + + Matrix_InsertTranslation(this->unk_178[i].x, this->unk_178[i].y + this->actor.shape.yOffset, + this->unk_178[i].z, MTXMODE_NEW); + Matrix_Scale(temp_f20, temp_f20, temp_f20, MTXMODE_APPLY); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + Matrix_InsertZRotation_s(this->actor.world.rot.z, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_wiz_DL_002B40); + } + } + + Matrix_StatePop(); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + + if (this->unk_166 == 0) { + func_80A4B33C(this, globalCtx); + } else { + func_80A4B0C8(this, globalCtx); + } +} + +void func_80A4BAB4(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnWizFire* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_InsertTranslation(this->actor.world.pos.x, this->actor.floorHeight + 20.0f, this->actor.world.pos.z, + MTXMODE_NEW); + Matrix_Scale(this->unk_14C + this->unk_154, this->unk_14C + this->unk_158, this->unk_14C + this->unk_15C, + MTXMODE_APPLY); + + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x20, 1, this->unk_170 & 0x7F, + (-this->unk_170 * 10) & 0x7F, 0x20, 0x20)); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0x80, 100, 50, 0, (s8)this->unk_1FC); + gDPSetEnvColor(POLY_XLU_DISP++, 200, 235, 245, 255); + + Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_wiz_DL_002630); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80A4BC74(EnWizFire* this, Vec3f* arg1, Vec3f* arg2) { + s16 i; + EnWizFireStruct* ptr = this->unk_254; + + for (i = 0; i < ARRAY_COUNT(this->unk_254); i++, ptr++) { + if (ptr->unk_00 == 0) { + ptr->unk_00 = 1; + Math_Vec3f_Copy(&ptr->unk_1C, &gZeroVec3f); + ptr->unk_01 = Rand_ZeroFloat(100.0f); + ptr->unk_10 = *arg1; + ptr->unk_28 = *arg2; + ptr->unk_0C = (Rand_ZeroFloat(5.0f) + 20.0f) * 0.001f; + ptr->unk_08 = 0; + ptr->unk_06 = 0; + break; + } + } +} + +void func_80A4BDDC(EnWizFire* this, GlobalContext* globalCtx) { + s32 i; + EnWizFireStruct* ptr = &this->unk_254[0]; + + for (i = 0; i < ARRAY_COUNT(this->unk_254); i++, ptr++) { + if (ptr->unk_00 != 0) { + ptr->unk_01++; + + ptr->unk_10.x += ptr->unk_1C.x; + ptr->unk_10.y += ptr->unk_1C.y; + ptr->unk_10.z += ptr->unk_1C.z; + + ptr->unk_1C.x += ptr->unk_28.x; + ptr->unk_1C.y += ptr->unk_28.y; + ptr->unk_1C.z += ptr->unk_28.z; + + if (ptr->unk_08 == 0) { + ptr->unk_06 += 10; + if (ptr->unk_06 >= 100) { + ptr->unk_08 = 1; + } + } else { + ptr->unk_06 -= 8; + if (ptr->unk_06 <= 0) { + ptr->unk_06 = 0; + ptr->unk_00 = 0; + } + } + } + } +} + +void func_80A4BF78(EnWizFire* this, GlobalContext* globalCtx) { + s16 i; + u8 flag; + EnWizFireStruct* ptr = &this->unk_254[0]; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + + OPEN_DISPS(gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + func_8012C2DC(globalCtx->state.gfxCtx); + + flag = false; + for (i = 0; i < ARRAY_COUNT(this->unk_254); i++, ptr++) { + if (ptr->unk_00 != 0) { + if (!flag) { + gSPDisplayList(POLY_XLU_DISP++, object_wiz_DL_000E70); + flag++; + } + + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 195, 225, 235, ptr->unk_06); + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, (ptr->unk_01 * 3) & 0x7F, + (ptr->unk_01 * 0xF) & 0xFF, 0x20, 0x40, 1, 0, 0, 0x20, 0x20)); + + Matrix_InsertTranslation(ptr->unk_10.x, ptr->unk_10.y, ptr->unk_10.z, MTXMODE_NEW); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); + Matrix_Scale(ptr->unk_0C, ptr->unk_0C, 1.0f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetRenderMode(POLY_XLU_DISP++, G_RM_PASS, G_RM_AA_ZB_XLU_SURF2); + gSPClearGeometryMode(POLY_XLU_DISP++, G_CULL_BACK | G_FOG); + gSPDisplayList(POLY_XLU_DISP++, object_wiz_DL_000FD8); + } + } + + CLOSE_DISPS(gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.h b/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.h index 0ff444fce..df396da97 100644 --- a/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.h +++ b/src/overlays/actors/ovl_En_Wiz_Fire/z_en_wiz_fire.h @@ -7,10 +7,48 @@ struct EnWizFire; typedef void (*EnWizFireActionFunc)(struct EnWizFire*, GlobalContext*); +typedef struct { + /* 0x00 */ u8 unk_00; + /* 0x01 */ u8 unk_01; + /* 0x02 */ UNK_TYPE1 unk02[0x4]; + /* 0x06 */ s16 unk_06; + /* 0x08 */ s16 unk_08; + /* 0x0A */ UNK_TYPE1 unk0A[0x2]; + /* 0x0C */ f32 unk_0C; + /* 0x10 */ Vec3f unk_10; + /* 0x1C */ Vec3f unk_1C; + /* 0x28 */ Vec3f unk_28; +} EnWizFireStruct; // size = 0x34 + typedef struct EnWizFire { /* 0x0000 */ Actor actor; /* 0x0144 */ EnWizFireActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x29AC]; + /* 0x0148 */ u8 unk_148; + /* 0x014C */ f32 unk_14C; + /* 0x0150 */ f32 unk_150; + /* 0x0154 */ f32 unk_154; + /* 0x0158 */ f32 unk_158; + /* 0x015C */ f32 unk_15C; + /* 0x0160 */ s16 unk_160; + /* 0x0162 */ s16 unk_162; + /* 0x0164 */ u8 unk_164; + /* 0x0166 */ s16 unk_166; + /* 0x0168 */ s16 unk_168; + /* 0x016A */ s16 unk_16A; + /* 0x016C */ s16 unk_16C; + /* 0x016E */ s16 unk_16E; + /* 0x0170 */ s16 unk_170; + /* 0x0172 */ s16 unk_172; + /* 0x0174 */ s8 unk_174; + /* 0x0178 */ Vec3f unk_178[10]; + /* 0x01F0 */ f32 unk_1F0; + /* 0x01F4 */ f32 unk_1F4; + /* 0x01F8 */ f32 unk_1F8; + /* 0x01FC */ f32 unk_1FC; + /* 0x0200 */ f32 unk_200; + /* 0x0204 */ f32 unk_204; + /* 0x0208 */ ColliderCylinder collider; + /* 0x0254 */ EnWizFireStruct unk_254[200]; } EnWizFire; // size = 0x2AF4 extern const ActorInit En_Wiz_Fire_InitVars; diff --git a/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c b/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c index d961ffc1b..d2b5e0378 100644 --- a/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c +++ b/src/overlays/actors/ovl_En_Zl4/z_en_zl4.c @@ -1,7 +1,7 @@ /* * File: z_en_zl4.c * Overlay: ovl_En_Zl4 - * Description: + * Description: Glitched early version of Skull Kid stuck in a T-pose */ #include "z_en_zl4.h" diff --git a/src/overlays/actors/ovl_En_Zo/z_en_zo.h b/src/overlays/actors/ovl_En_Zo/z_en_zo.h index b876205f5..a823a1ec0 100644 --- a/src/overlays/actors/ovl_En_Zo/z_en_zo.h +++ b/src/overlays/actors/ovl_En_Zo/z_en_zo.h @@ -10,7 +10,7 @@ typedef void (*EnZoActionFunc)(struct EnZo*, GlobalContext*); typedef struct EnZo { /* 0x0000 */ Actor actor; /* 0x0144 */ EnZoActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x2DC]; + /* 0x0148 */ char unk_148[0x2DC]; } EnZo; // size = 0x424 extern const ActorInit En_Zo_InitVars; diff --git a/src/overlays/actors/ovl_En_Zog/z_en_zog.c b/src/overlays/actors/ovl_En_Zog/z_en_zog.c index a4c63543c..a8a10008b 100644 --- a/src/overlays/actors/ovl_En_Zog/z_en_zog.c +++ b/src/overlays/actors/ovl_En_Zog/z_en_zog.c @@ -5,6 +5,7 @@ */ #include "z_en_zog.h" +#include "objects/object_zog/object_zog.h" #define FLAGS 0x00000009 @@ -30,7 +31,8 @@ void func_80B94E34(EnZog* this, GlobalContext* globalCtx); void func_80B95128(EnZog* this, GlobalContext* globalCtx); void func_80B95240(EnZog* this, GlobalContext* globalCtx); -#if 0 +static u8 D_80B95E10; + const ActorInit En_Zog_InitVars = { ACTOR_EN_ZOG, ACTORCAT_NPC, @@ -43,78 +45,1041 @@ const ActorInit En_Zog_InitVars = { (ActorFunc)EnZog_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B95880 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_ENEMY, OC1_ON | OC1_TYPE_PLAYER, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0xF7CFFFFF, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_ENEMY, + OC1_ON | OC1_TYPE_PLAYER, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0xF7CFFFFF, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 30, 40, 0, { 0, 0, 0 } }, }; -#endif +static TexturePtr D_80B958AC[] = { &object_zog_Tex_024750, &object_zog_Tex_024F50, &object_zog_Tex_025750 }; -extern ColliderCylinderInit D_80B95880; +static TexturePtr D_80B958B8[] = { &object_zog_Tex_025F50, &object_zog_Tex_026750 }; -extern UNK_TYPE D_0600FC0C; -extern UNK_TYPE D_060280A8; +static AnimationHeader* D_80B958C0[] = { + &object_zog_Anim_00FC0C, &object_zog_Anim_0106B0, &object_zog_Anim_0166F4, &object_zog_Anim_017170, + &object_zog_Anim_014B10, &object_zog_Anim_018600, &object_zog_Anim_01A06C, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B93310.s") +static AnimationHeader* D_80B958DC[] = { &object_zog_Anim_00CA94, &object_zog_Anim_00F110 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B93468.s") +static AnimationHeader* D_80B958E4[] = { &object_zog_Anim_01579C, &object_zog_Anim_015B80, &object_zog_Anim_00ECBC }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/EnZog_Init.s") +static AnimationHeader* D_80B958F0[] = { &object_zog_Anim_008EB8, &object_zog_Anim_0099A4 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/EnZog_Destroy.s") +static AnimationHeader* D_80B958F8[] = { &object_zog_Anim_00931C, &object_zog_Anim_009EC4, &object_zog_Anim_00B01C }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B939C0.s") +static AnimationHeader* D_80B95904[] = { + &object_zog_Anim_00BF38, &object_zog_Anim_01A990, &object_zog_Anim_01AD58, + &object_zog_Anim_01B72C, &object_zog_Anim_01BC88, +}; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B93A48.s") +static AnimationHeader* D_80B95918 = &object_zog_Anim_001000; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B93B44.s") +static AnimationHeader* D_80B9591C = &object_zog_Anim_001970; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B93BA8.s") +static AnimationHeader* D_80B95920 = &object_zog_Anim_002344; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B93BE0.s") +static AnimationHeader* D_80B95924 = &object_zog_Anim_002894; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B93D2C.s") +static AnimationHeader* D_80B95928 = &object_zog_Anim_0030E0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B93DE8.s") +static AnimationHeader* D_80B9592C = &object_zog_Anim_0037F8; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B93EA0.s") +static AnimationHeader* D_80B95930 = &object_zog_Anim_0041D0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B943A0.s") +static AnimationHeader* D_80B95934 = &object_zog_Anim_004BDC; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B943C0.s") +static AnimationHeader* D_80B95938 = &object_zog_Anim_0055B4; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B943EC.s") +static s16 D_80B9593C[] = { 0, 1, 2, 3 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B94470.s") +static s16 D_80B95944[] = { 4, 5 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B9451C.s") +static s16 D_80B95948[] = { 5, 6, 7, 0 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B9461C.s") +static s16 D_80B95950[] = { 7, 8, 9, 10, 7, 11, 12, 13, 14, 15, 12, 13, 14, 15, 12, 16, 17, 0 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B946B4.s") +static s16* D_80B95974[] = { D_80B9593C, D_80B95944, D_80B95948, D_80B95950 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B946FC.s") +static s16 D_80B95984[] = { 4, 2, 3, 17 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B948A8.s") +static Vec3f D_80B9598C = { 0.0f, -0.05f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B94A00.s") +static Vec3f D_80B95998 = { 0.0f, -0.025f, 0.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B94C5C.s") +static Color_RGBA8 D_80B959A4 = { 220, 220, 255, 255 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B94D0C.s") +static Color_RGBA8 D_80B959A8 = { 80, 80, 220, 255 }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B94E34.s") +static Vec3f D_80B959AC = { 0.0f, 0.0f, 15.0f }; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B95128.s") +void func_80B93310(Actor* thisx, Lights* mapper, GlobalContext* globalCtx) { + Vec3f sp34; + EnZog* this = THIS; + f32 sp2C; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B95240.s") + if (this->unk_322 > 0) { + if (this->unk_30A & 8) { + this->actor.shape.shadowAlpha = this->unk_322; + } else { + this->actor.shape.shadowAlpha = 255; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/EnZog_Update.s") + Math_Vec3f_Copy(&sp34, &this->actor.world.pos); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B954C4.s") + sp2C = sqrtf(SQ(this->actor.focus.pos.x - this->unk_2F0.x) + SQ(this->actor.focus.pos.z - this->unk_2F0.z)); + if (sp2C < 12.0f) { + sp2C = 12.0f; + } else if (sp2C > 60.0f) { + sp2C = 60.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/func_80B95598.s") + Math_Vec3f_Copy(&this->actor.world.pos, &this->unk_2F0); + func_800B4AEC(globalCtx, &this->actor, 50.0f); + if (sp34.y < this->actor.floorHeight) { + this->actor.world.pos.y = this->actor.floorHeight; + } else { + this->actor.world.pos.y = sp34.y; + } + this->actor.scale.z *= sp2C * (1 / 12.0f); + func_800B3FC0(&this->actor, mapper, globalCtx); + this->actor.scale.z = this->actor.scale.x; + Math_Vec3f_Copy(&this->actor.world.pos, &sp34); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Zog/EnZog_Draw.s") +void func_80B93468(EnZog* this, GlobalContext* globalCtx) { + Vec3s* points; + + this->unk_2E8 = &globalCtx->setupPathList[ENZOG_GET_FC00(&this->actor)]; + if (this->unk_2E8 != NULL) { + points = &((Vec3s*)Lib_SegmentedToVirtual(this->unk_2E8->points))[this->unk_2EC]; + points++; + + this->actor.world.pos.x = points[-1].x; + this->actor.world.pos.z = points[-1].z; + this->actor.world.rot.y = Math_Atan2S(points->x - this->actor.world.pos.x, points->z - this->actor.world.pos.z); + this->actor.speedXZ = 0.0f; + } +} + +void EnZog_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnZog* this = THIS; + s32 i; + s16 cs; + + if (!D_80B95E10) { + for (i = 0; i < ARRAY_COUNT(D_80B958AC); i++) { + D_80B958AC[i] = Lib_SegmentedToVirtual(D_80B958AC[i]); + } + + for (i = 0; i < ARRAY_COUNT(D_80B958B8); i++) { + D_80B958B8[i] = Lib_SegmentedToVirtual(D_80B958B8[i]); + } + + D_80B95E10 = true; + } + + ActorShape_Init(&this->actor.shape, 0.0f, func_80B93310, 24.0f); + Actor_SetScale(&this->actor, 0.01f); + this->actionFunc = func_80B95128; + this->actor.textId = 0x1004; + SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_zog_Skel_029170, &object_zog_Anim_00FC0C, this->jointTable, + this->morphTable, 23); + Animation_PlayOnce(&this->skelAnime, &object_zog_Anim_00FC0C); + Collider_InitAndSetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + + if ((ENZOG_GET_F(&this->actor) != ENZOG_F_2) && (INV_CONTENT(ITEM_MASK_ZORA) == ITEM_MASK_ZORA) && + ((globalCtx->csCtx.unk_12 != 2) || (gSaveContext.sceneSetupIndex != 0) || + (globalCtx->sceneNum != SCENE_30GYOSON))) { + Actor_MarkForDeath(&this->actor); + return; + } + + this->actor.minVelocityY = -4.0f; + this->actor.gravity = -1.0f; + this->actor.uncullZoneScale = 3000.0f; + this->actor.shape.yOffset = 1000.0f; + this->unk_308 = 0; + this->unk_30A = 0; + this->unk_31C = 2; + this->unk_31E = 0; + this->unk_31A = -1; + this->unk_322 = 100; + + Math_Vec3f_Copy(&this->unk_2F0, &this->actor.world.pos); + + if (ENZOG_GET_F(&this->actor) == ENZOG_F_2) { + this->actionFunc = func_80B95240; + this->unk_322 = 255; + this->unk_31C = 0; + this->unk_31E = 0; + this->actor.shape.yOffset = 0.0f; + } + + this->unk_2EC = 0; + if (ENZOG_GET_FC00(&this->actor) != ENZOG_FC00_63) { + func_80B93468(this, globalCtx); + } else { + this->unk_2E8 = NULL; + } + + this->unk_2FC = 0; + this->unk_302 = 0; + this->unk_2EC++; + this->unk_304 = 0; + this->unk_2FE = this->unk_2FC; + this->unk_300 = this->unk_302; + cs = this->actor.cutscene; + + for (i = 0; i < ARRAY_COUNT(this->unk_30C); i++) { + this->unk_30C[i] = cs; + if (cs != -1) { + this->actor.cutscene = cs; + cs = ActorCutscene_GetAdditionalCutscene(this->actor.cutscene); + } + } + + this->actor.flags |= 0x10000; + this->actor.home.rot.z = 0; + if (ENZOG_GET_F(&this->actor) != ENZOG_F_2) { + for (i = 0; i < 5; i++) { + Actor_SpawnAsChild(&globalCtx->actorCtx, &this->actor, globalCtx, ACTOR_EN_TANRON4, this->actor.world.pos.x, + this->actor.world.pos.y + 500.0f, this->actor.world.pos.z, 0, 0, 0, 100); + } + } + + if ((ENZOG_GET_F(&this->actor) != ENZOG_F_2) && (gSaveContext.weekEventReg[88] & 0x10)) { + this->unk_302 = this->unk_300 = 0; + this->unk_2FC = this->unk_2FE = 3; + this->actor.flags |= 0x2000000; + this->actor.flags &= ~0x10000; + this->unk_31C = 2; + this->unk_31E = 0; + + Animation_PlayLoop(&this->skelAnime, D_80B958DC[0]); + this->actor.textId = 0x1009; + if (gSaveContext.weekEventReg[91] & 2) { + this->actor.textId = 0x103C; + this->actionFunc = func_80B9451C; + } else { + this->actionFunc = func_80B948A8; + } + this->actor.shape.rot.y = 0x4000; + this->actor.world.rot.y = 0x4000; + this->actor.world.pos.x = -376.0f; + this->actor.world.pos.y = 80.0f; + this->actor.world.pos.z = 4793.0f; + this->actor.shape.yOffset = 0.0f; + } +} + +void EnZog_Destroy(Actor* thisx, GlobalContext* globalCtx) { + EnZog* this = THIS; + + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void func_80B939C0(EnZog* this, s16 arg1, u8 arg2) { + Animation_Change(&this->skelAnime, D_80B958C0[arg1], 1.0f, 0.0f, Animation_GetLastFrame(D_80B958C0[arg1]), arg2, + -5.0f); + this->unk_304 = arg1; +} + +void func_80B93A48(EnZog* this, GlobalContext* globalCtx) { + s16* table; + + if (SkelAnime_Update(&this->skelAnime)) { + if (this->unk_302 != this->unk_300) { + this->unk_302++; + } else if (this->unk_302 == 0) { + if (this->unk_2FC != this->unk_2FE) { + this->unk_2FC = this->unk_2FE; + } + } + + if (this->unk_302 >= D_80B95984[this->unk_2FC]) { + this->unk_302 = 0; + this->unk_300 = 0; + if (this->unk_2FC != this->unk_2FE) { + this->unk_2FC = this->unk_2FE; + } + } + + table = D_80B95974[this->unk_2FC]; + + this->unk_304 = table[this->unk_302]; + Animation_PlayOnce(&this->skelAnime, D_80B958C0[this->unk_304]); + SkelAnime_Update(&this->skelAnime); + } +} + +void func_80B93B44(EnZog* this) { + if (!(this->unk_30A & 4)) { + if (this->unk_31A != -1) { + ActorCutscene_Stop(this->unk_30C[this->unk_31A]); + } + } + this->unk_31A = -1; + this->unk_30A &= ~4; +} + +void func_80B93BA8(EnZog* this, s16 arg1) { + func_80B93B44(this); + this->unk_31A = arg1; + this->unk_30A |= 4; +} + +s32 func_80B93BE0(EnZog* this, GlobalContext* globalCtx) { + Path* path = this->unk_2E8; + s16 temp_v0; + Vec3s* points; + + if (this->unk_2E8 == 0) { + return false; + } + + points = &((Vec3s*)Lib_SegmentedToVirtual(path->points))[this->unk_2EC]; + + if (this->unk_30A & 1) { + this->actor.world.pos.x = points->x; + this->actor.world.pos.z = points->z; + return true; + } + + points++; + temp_v0 = Math_Atan2S(points->x - this->actor.world.pos.x, points->z - this->actor.world.pos.z); + + if (ABS_ALT(temp_v0 - this->actor.world.rot.y) > 0x4000) { + this->unk_2EC++; + func_80B93468(this, globalCtx); + if ((this->unk_2EC + 1) >= this->unk_2E8->count) { + this->unk_30A |= 1; + return true; + } + } else { + this->actor.world.rot.y = temp_v0; + } + + return false; +} + +void func_80B93D2C(EnZog* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp28 = this->actor.world.pos; + + sp28.y += this->actor.depthInWater; + this->actor.world.pos.y += (this->actor.depthInWater - 10.0f) + (2.0f * Math_SinS(this->unk_308)); + this->unk_308 += 0x200; + if ((globalCtx->gameplayFrames % 16) == 0) { + EffectSsGRipple_Spawn(globalCtx, &sp28, 150, 500, 0); + } +} + +void func_80B93DE8(Vec3f* arg0, GlobalContext* globalCtx, s32 arg2) { + Vec3f sp2C; + + sp2C.x = randPlusMinusPoint5Scaled(30.0f) + arg0->x; + sp2C.y = arg0->y + 3.0f; + sp2C.z = randPlusMinusPoint5Scaled(30.0f) + arg0->z; + EffectSsKiraKira_SpawnDispersed(globalCtx, &sp2C, &D_80B9598C, &D_80B95998, &D_80B959A4, &D_80B959A8, 1000, arg2); +} + +s32 func_80B93EA0(EnZog* this, GlobalContext* globalCtx) { + s16 sp3E; + + if (SkelAnime_Update(&this->skelAnime)) { + switch (this->unk_306) { + case 2: + case 3: + Animation_PlayLoop(&this->skelAnime, *D_80B958F0); + this->unk_31C = 0; + this->unk_31E = 1; + break; + + case 4: + Animation_PlayLoop(&this->skelAnime, *D_80B958F8); + this->unk_31C = 2; + this->unk_31E = 1; + break; + + case 5: + switch (this->unk_304) { + case 16: + Animation_PlayOnce(&this->skelAnime, *D_80B95904); + this->unk_304 = 17; + this->unk_31C = 2; + this->unk_31E = 0; + break; + + case 17: + Animation_Change(&this->skelAnime, *D_80B958DC, 0.0f, 0.0f, 0.0f, 0, 0.0f); + break; + } + break; + + case 6: + Animation_PlayLoop(&this->skelAnime, *D_80B958E4); + this->unk_31C = 1; + this->unk_31E = 1; + break; + + case 12: + Animation_PlayLoop(&this->skelAnime, D_80B95930); + break; + + case 13: + Animation_PlayLoop(&this->skelAnime, D_80B95938); + break; + + case 14: + Animation_PlayLoop(&this->skelAnime, D_80B95928); + break; + + case 15: + Animation_PlayLoop(&this->skelAnime, D_80B9591C); + break; + } + SkelAnime_Update(&this->skelAnime); + } + + if (func_800EE29C(globalCtx, 0x1D7)) { + sp3E = globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x1D7)]->unk0; + func_800EDF24(&this->actor, globalCtx, func_800EE200(globalCtx, 0x1D7)); + + switch (this->unk_306) { + case 2: + if (globalCtx->csCtx.frames == 60) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_JUMP_SAND); + } + break; + + case 8: + if (this->unk_322 > 4) { + this->unk_322 -= 4; + } else { + this->unk_322 = 0; + } + + if (this->unk_322 > 0) { + func_80B93DE8(&this->unk_2F0, globalCtx, 20); + func_80B93DE8(&this->actor.world.pos, globalCtx, 20); + func_80B93DE8(&this->actor.focus.pos, globalCtx, 20); + } + break; + + case 9: + case 10: + if (this->unk_322 < 150) { + this->unk_322 += 15; + } else { + this->unk_322 = 150; + } + break; + + default: + this->unk_30A &= ~8; + break; + } + + if (this->unk_306 != sp3E) { + this->unk_306 = sp3E; + + switch (this->unk_306) { + case 1: + func_80B939C0(this, 7, 0); + this->unk_31C = 2; + this->unk_31E = 0; + break; + + case 2: + func_80B939C0(this, 11, 2); + this->unk_31C = 1; + this->unk_31E = 0; + break; + + case 3: + func_80B939C0(this, 15, 2); + this->unk_31C = 0; + this->unk_31E = 1; + break; + + case 4: + func_80B939C0(this, 13, 2); + this->unk_31C = 2; + this->unk_31E = 1; + break; + + case 5: + func_80B939C0(this, 16, 2); + this->unk_31C = 2; + this->unk_31E = 1; + break; + + case 6: + func_80B939C0(this, 8, 2); + this->unk_31C = 1; + this->unk_31E = 0; + break; + + case 8: + this->unk_322 = 0xFA; + this->unk_30A |= 8; + break; + + case 9: + this->unk_322 = 0; + this->unk_30A |= 8; + func_80B939C0(this, 18, 0); + this->unk_31C = 0; + this->unk_31E = 0; + this->unk_30A &= ~2; + break; + + case 10: + func_80B939C0(this, 14, 0); + this->unk_31C = 0; + this->unk_30A |= 2; + this->unk_31E = 1; + break; + + case 11: + Animation_PlayLoop(&this->skelAnime, D_80B95920); + break; + + case 12: + Animation_PlayOnce(&this->skelAnime, D_80B9592C); + break; + + case 13: + Animation_PlayOnce(&this->skelAnime, D_80B95934); + break; + + case 14: + this->unk_30A |= 2; + Animation_PlayOnce(&this->skelAnime, D_80B95924); + break; + + case 15: + Animation_PlayOnce(&this->skelAnime, D_80B95918); + break; + } + } + return true; + } + + return false; +} + +void func_80B943A0(EnZog* this, GlobalContext* globalCtx) { + func_80B93EA0(this, globalCtx); +} + +void func_80B943C0(EnZog* this, GlobalContext* globalCtx) { + if (!(this->unk_30A & 4)) { + this->actionFunc = func_80B943A0; + this->unk_306 = -1; + } +} + +void func_80B943EC(EnZog* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + if (this->unk_30A & 0x10) { + if (!(player->stateFlags2 & 0x8000000)) { + this->unk_30A &= ~0x10; + } + } else if ((player->stateFlags2 & 0x8000000) && (this->actor.xzDistToPlayer < 120.0f)) { + this->unk_30A |= 0x10; + Audio_PlayActorSound2(&this->actor, NA_SE_SY_TRE_BOX_APPEAR); + } +} + +void func_80B94470(EnZog* this, GlobalContext* globalCtx) { + if (func_80152498(&globalCtx->msgCtx) == 5) { + if (func_80147624(globalCtx) && (globalCtx->msgCtx.unk11F04 == 0x103C)) { + func_801477B4(globalCtx); + this->actionFunc = func_80B9451C; + this->unk_300 = this->unk_302 = 0; + this->unk_31C = 2; + this->unk_31E = 0; + } + } + func_80B93A48(this, globalCtx); +} + +void func_80B9451C(EnZog* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + this->unk_300 = 2; + this->actionFunc = func_80B94470; + } else if ((globalCtx->msgCtx.unk1202A == 3) && (this->actor.xzDistToPlayer < 120.0f)) { + if ((globalCtx->msgCtx.unk1202E == 7) && (gSaveContext.playerForm == PLAYER_FORM_HUMAN)) { + func_80B93BA8(this, 2); + this->actionFunc = func_80B943C0; + this->actor.shape.shadowDraw = NULL; + } + } else if (this->actor.xzDistToPlayer < 120.0f) { + func_800B8614(&this->actor, globalCtx, 150.0f); + } + func_80B943EC(this, globalCtx); +} + +void func_80B9461C(EnZog* this, GlobalContext* globalCtx) { + if (!func_80B93EA0(this, globalCtx)) { + this->actor.textId = 0x103C; + this->actionFunc = func_80B9451C; + this->actor.flags |= 0x2000000; + gSaveContext.weekEventReg[91] |= 2; + } + + if ((this->unk_304 == 11) && ((s32)this->skelAnime.curFrame >= 55)) { + this->unk_30A |= 2; + } +} + +void func_80B946B4(EnZog* this, GlobalContext* globalCtx) { + func_80B93A48(this, globalCtx); + if (!(this->unk_30A & 4)) { + this->actionFunc = func_80B9461C; + this->unk_306 = -1; + } +} + +void func_80B946FC(EnZog* this, GlobalContext* globalCtx) { + switch (func_80152498(&globalCtx->msgCtx)) { + case 4: + if (func_80147624(globalCtx)) { + switch (globalCtx->msgCtx.choiceIndex) { + case 0: + func_8019F208(); + globalCtx->msgCtx.unk11F10 = 0; + this->actionFunc = func_80B946B4; + func_80B93BA8(this, 1); + break; + + case 1: + func_8019F230(); + func_80151938(globalCtx, 0x1014); + break; + } + } + break; + + case 5: + if (func_80147624(globalCtx)) { + switch (globalCtx->msgCtx.unk11F04) { + case 0x1008: + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + break; + + case 0x1009: + this->unk_300 = 4; + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + break; + + case 0x1014: + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + break; + + case 0x1015: + func_801477B4(globalCtx); + this->actionFunc = func_80B948A8; + this->unk_300 = this->unk_302 = 0; + this->unk_31C = 2; + this->unk_31E = 0; + return; + } + } + break; + } + + func_80B93A48(this, globalCtx); +} + +void func_80B948A8(EnZog* this, GlobalContext* globalCtx) { + if (func_800B84D0(&this->actor, globalCtx)) { + this->unk_300 = 2; + this->actionFunc = func_80B946FC; + } else if ((globalCtx->msgCtx.unk1202A == 3) && (this->actor.xzDistToPlayer < 120.0f)) { + if ((globalCtx->msgCtx.unk1202E == 7) && (gSaveContext.playerForm == PLAYER_FORM_HUMAN)) { + func_80B93BA8(this, 2); + this->actionFunc = func_80B943C0; + this->actor.shape.shadowDraw = NULL; + } + return; + } else { + if ((this->unk_302 == 2) && (this->unk_2FC == 2)) { + this->unk_300 = 0; + this->unk_2FE = 3; + this->unk_302 = this->unk_300; + this->unk_2FC = this->unk_2FE; + func_80B93B44(this); + } + + if ((this->unk_302 == 0) && (this->actor.xzDistToPlayer < 120.0f)) { + func_800B8614(&this->actor, globalCtx, 150.0f); + } + } + func_80B93A48(this, globalCtx); + func_80B943EC(this, globalCtx); +} + +void func_80B94A00(EnZog* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp30; + + if (func_80B93BE0(this, globalCtx)) { + this->actionFunc = func_80B948A8; + this->actor.flags |= 0x2000000; + if (gSaveContext.weekEventReg[29] & 0x20) { + this->actor.textId = 0x1009; + } else { + this->actor.textId = 0x1008; + gSaveContext.weekEventReg[29] |= 0x20; + } + this->unk_300 = 2; + this->unk_31C = 2; + this->unk_31E = 0; + return; + } + + if ((this->skelAnime.curFrame >= 35.0f) || + ((this->skelAnime.curFrame >= 10.0f) && (this->skelAnime.curFrame <= 24.0f))) { + this->actor.speedXZ = 0.0f; + } else { + this->actor.speedXZ = 1.5f; + } + + if ((this->actor.depthInWater > 0.0f) && ((globalCtx->gameplayFrames % 8) == 0)) { + sp30 = this->actor.world.pos; + sp30.y += this->actor.depthInWater; + EffectSsGRipple_Spawn(globalCtx, &sp30, 150, 500, 0); + } + + if (this->actor.shape.yOffset > 0.0f) { + this->actor.shape.yOffset -= 20.0f; + } + + func_80B93A48(this, globalCtx); + + if ((this->unk_304 == 4) && + (Animation_OnFrame(&this->skelAnime, 136.0f) || Animation_OnFrame(&this->skelAnime, 155.0f))) { + Audio_PlayActorSound2(&this->actor, NA_SE_PL_WALK_WATER0); + } + + if ((this->unk_304 == 5) && + (Animation_OnFrame(&this->skelAnime, 12.0f) || Animation_OnFrame(&this->skelAnime, 37.0f))) { + if (this->actor.depthInWater > 0.0f) { + Audio_PlayActorSound2(&this->actor, NA_SE_PL_WALK_WATER0); + } else { + Audio_PlayActorSound2(&this->actor, NA_SE_PL_WALK_SAND); + } + } +} + +void func_80B94C5C(EnZog* this, GlobalContext* globalCtx) { + this->actor.speedXZ = 0.0f; + if (this->unk_304 != 0) { + if (this->actor.shape.yOffset > 0.0f) { + this->actor.shape.yOffset -= 20.0f; + } + this->actor.velocity.y = -1.0f; + this->actor.minVelocityY = -1.0f; + } + + if ((this->unk_2FC == 1) && (this->unk_302 == 0)) { + this->unk_2FE = 2; + this->unk_300 = 2; + } + + if (this->unk_304 == 5) { + this->actionFunc = func_80B94A00; + } + + func_80B93A48(this, globalCtx); +} + +void func_80B94D0C(EnZog* this, GlobalContext* globalCtx) { + func_80B93D2C(this, globalCtx); + this->actor.speedXZ = 0.0f; + if (this->unk_320 > 0) { + this->unk_320--; + this->unk_31C = 1; + this->unk_31E = 1; + } else { + this->unk_31C = 2; + this->unk_31E = 0; + } + + if ((func_80152498(&globalCtx->msgCtx) == 5) && func_80147624(globalCtx)) { + this->unk_320 = 5; + switch (globalCtx->msgCtx.unk11F04) { + case 0x1004: + case 0x1005: + case 0x1006: + func_80151938(globalCtx, globalCtx->msgCtx.unk11F04 + 1); + break; + + case 0x1007: + func_801477B4(globalCtx); + this->actionFunc = func_80B94E34; + this->unk_300 = 5; + this->unk_320 = 0; + this->unk_31C = 2; + this->unk_31E = 0; + func_80B93B44(this); + break; + } + } + func_80B93A48(this, globalCtx); +} + +void func_80B94E34(EnZog* this, GlobalContext* globalCtx) { + s32 pad; + Player* player = GET_PLAYER(globalCtx); + + func_80B93D2C(this, globalCtx); + func_80B93BE0(this, globalCtx); + if (this->actor.speedXZ < 0.1f) { + this->actor.speedXZ = 0.0f; + } else { + if (this->actor.speedXZ > 0.1f) { + WaterBox* sp44; + Vec3f sp38; + + Lib_Vec3f_TranslateAndRotateY(&this->actor.world.pos, this->actor.shape.rot.y, &D_80B959AC, &sp38); + sp38.x += randPlusMinusPoint5Scaled(30.0f); + sp38.y += 20.0f; + sp38.z += randPlusMinusPoint5Scaled(30.0f); + if (WaterBox_GetSurface1(globalCtx, &globalCtx->colCtx, sp38.x, sp38.z, &sp38.y, &sp44) && + (this->actor.world.pos.y < sp38.y)) { + EffectSsGSplash_Spawn(globalCtx, &sp38, NULL, NULL, 1, + Rand_ZeroFloat(this->actor.speedXZ * 40.0f) + (this->actor.speedXZ * 60.0f)); + } + + if ((player->actor.speedXZ > 3.0f) && (this->unk_324 == 0)) { + this->unk_324 = 25; + func_800B8E58(&player->actor, player->ageProperties->unk_92 + 0x6818); + } + } + this->actor.speedXZ *= 0.3f; + } + + if (ABS_ALT(this->actor.yawTowardsPlayer - this->actor.world.rot.y) > 0x5000) { + func_800B8A1C(&this->actor, globalCtx, 0, 60.0f, 40.0f); + } + + if (this->unk_324 > 0) { + this->unk_324--; + } + + if (func_800B84D0(&this->actor, globalCtx)) { + this->actionFunc = func_80B94D0C; + this->actor.speedXZ = 0.0f; + this->unk_300 = 2; + } else if (this->actor.bgCheckFlags & 1) { + this->actor.home.rot.z = 1; + this->actionFunc = func_80B94C5C; + this->actor.speedXZ = 0.0f; + this->unk_2FE = 1; + this->actor.velocity.y = 0.0f; + this->actor.minVelocityY = 0.0f; + this->actor.gravity = 0.0f; + this->unk_31C = 1; + this->unk_31E = 0; + func_80B93BA8(this, 0); + gSaveContext.weekEventReg[88] |= 0x10; + } else if ((this->actor.yawTowardsPlayer > 16000) && (this->actor.yawTowardsPlayer < 32000) && + (this->unk_302 == 0)) { + func_800B8614(&this->actor, globalCtx, 150.0f); + } + + this->actor.shape.rot.y = this->actor.world.rot.y; + func_80B93A48(this, globalCtx); +} + +void func_80B95128(EnZog* this, GlobalContext* globalCtx) { + func_80B93D2C(this, globalCtx); + func_80B93BE0(this, globalCtx); + + if (func_800B84D0(&this->actor, globalCtx)) { + this->actionFunc = func_80B94D0C; + this->unk_300 = 2; + this->actor.speedXZ = 0.0f; + + switch (CURRENT_DAY) { + case 1: + func_80B93BA8(this, 4); + break; + + case 2: + func_80B93BA8(this, 5); + break; + + default: + func_80B93BA8(this, 6); + break; + } + + this->actor.flags &= ~0x10000; + gSaveContext.weekEventReg[91] |= 1; + } else { + func_800B8614(&this->actor, globalCtx, 150.0f); + } + this->actor.shape.rot.y = this->actor.world.rot.y; + func_80B93A48(this, globalCtx); +} + +void func_80B95240(EnZog* this, GlobalContext* globalCtx) { + func_80B93EA0(this, globalCtx); +} + +void EnZog_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + EnZog* this = THIS; + + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 10.0f, 10.0f, 10.0f, 5); + if (func_800EE29C(globalCtx, 0x1D7) && (ENZOG_GET_F(&this->actor) != ENZOG_F_2)) { + this->actionFunc = func_80B9461C; + this->actor.shape.yOffset = 0.0f; + } + + this->actionFunc(this, globalCtx); + + if (((this->unk_304 == 6) && Animation_OnFrame(&this->skelAnime, 43.0f)) || + ((this->unk_304 == 17) && Animation_OnFrame(&this->skelAnime, 14.0f))) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_LAND_SAND); + } + + if (this->unk_30A & 1) { + this->collider.dim.pos.x = this->unk_2F0.x; + this->collider.dim.pos.y = this->actor.world.pos.y; + this->collider.dim.pos.z = this->unk_2F0.z; + } else { + Collider_UpdateCylinder(&this->actor, &this->collider); + } + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + + this->actor.focus.pos = this->actor.world.pos; + this->actor.focus.pos.y += 30.0f; + + if (this->unk_30A & 4) { + if (this->unk_31A == -1) { + this->unk_30A &= ~4; + } else if (this->unk_30C[this->unk_31A] == -1) { + this->unk_30A &= ~4; + } else if (ActorCutscene_GetCurrentIndex() == 0x7C) { + ActorCutscene_Stop(0x7C); + ActorCutscene_SetIntentToPlay(this->unk_30C[this->unk_31A]); + } else if (ActorCutscene_GetCanPlayNext(this->unk_30C[this->unk_31A])) { + ActorCutscene_StartAndSetUnkLinkFields(this->unk_30C[this->unk_31A], &this->actor); + this->unk_30A &= ~4; + } else { + ActorCutscene_SetIntentToPlay(this->unk_30C[this->unk_31A]); + } + } +} + +void func_80B954C4(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx) { + static Vec3f D_80B959B8 = { 0.0f, 0.0f, 0.0f }; + EnZog* this = THIS; + + D_80B959B8.y = 1000.0f; + if (limbIndex == 9) { + Matrix_MultiplyVector3fByState(&D_80B959B8, &this->actor.focus.pos); + } + D_80B959B8.y = 0.0f; + + if (limbIndex == 1) { + Matrix_MultiplyVector3fByState(&D_80B959B8, &this->unk_2F0); + } + + if ((this->unk_30A & 2) && (limbIndex == 17)) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + gSPDisplayList(POLY_OPA_DISP++, object_zog_DL_0280A8); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } +} + +void func_80B95598(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot, Actor* thisx, Gfx** gfx) { + static Vec3f D_80B959C4 = { 0.0f, 0.0f, 0.0f }; + EnZog* this = THIS; + + D_80B959C4.y = 1000.0f; + if (limbIndex == 9) { + Matrix_MultiplyVector3fByState(&D_80B959C4, &this->actor.focus.pos); + } + D_80B959C4.y = 0.0f; + + if (limbIndex == 1) { + Matrix_MultiplyVector3fByState(&D_80B959C4, &this->unk_2F0); + } + + if ((this->unk_30A & 2) && (limbIndex == 17)) { + gSPDisplayList((*gfx)++, object_zog_DL_0280A8); + } +} + +void EnZog_Draw(Actor* thisx, GlobalContext* globalCtx) { + EnZog* this = THIS; + Gfx* gfx; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (this->unk_30A & 8) { + if (this->unk_322 > 128) { + gfx = POLY_XLU_DISP++; + func_8012C2B4(gfx); + Scene_SetRenderModeXlu(globalCtx, 2, 2); + } else { + gfx = POLY_XLU_DISP++; + func_8012C304(gfx); + Scene_SetRenderModeXlu(globalCtx, 1, 2); + } + + gfx = POLY_XLU_DISP; + + gSPSegment(&gfx[0], 0x08, Lib_SegmentedToVirtual(D_80B958AC[this->unk_31C])); + gSPSegment(&gfx[1], 0x09, Lib_SegmentedToVirtual(D_80B958B8[this->unk_31E])); + gDPSetEnvColor(&gfx[2], 0, 0, 0, this->unk_322); + + POLY_XLU_DISP = &gfx[3]; + POLY_XLU_DISP = + SkelAnime_DrawFlex(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, NULL, func_80B95598, &this->actor, POLY_XLU_DISP); + } else { + func_8012C28C(globalCtx->state.gfxCtx); + Scene_SetRenderModeXlu(globalCtx, 0, 1); + + gfx = POLY_OPA_DISP; + + gSPSegment(&gfx[0], 0x08, Lib_SegmentedToVirtual(D_80B958AC[this->unk_31C])); + gSPSegment(&gfx[1], 0x09, Lib_SegmentedToVirtual(D_80B958B8[this->unk_31E])); + gDPSetEnvColor(&gfx[2], 0, 0, 0, 255); + + POLY_OPA_DISP = &gfx[3]; + SkelAnime_DrawFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, + this->skelAnime.dListCount, NULL, func_80B954C4, &this->actor); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_En_Zog/z_en_zog.h b/src/overlays/actors/ovl_En_Zog/z_en_zog.h index 48600b3f7..7dba946d5 100644 --- a/src/overlays/actors/ovl_En_Zog/z_en_zog.h +++ b/src/overlays/actors/ovl_En_Zog/z_en_zog.h @@ -7,10 +7,37 @@ struct EnZog; typedef void (*EnZogActionFunc)(struct EnZog*, GlobalContext*); +#define ENZOG_GET_F(thisx) ((thisx)->params & 0xF) +#define ENZOG_GET_FC00(thisx) (((thisx)->params & 0xFC00) >> 0xA) + +#define ENZOG_F_2 2 +#define ENZOG_FC00_63 63 + typedef struct EnZog { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x1E4]; - /* 0x0328 */ EnZogActionFunc actionFunc; + /* 0x000 */ Actor actor; + /* 0x144 */ ColliderCylinder collider; + /* 0x190 */ SkelAnime skelAnime; + /* 0x1D4 */ Vec3s jointTable[23]; + /* 0x25E */ Vec3s morphTable[23]; + /* 0x2E8 */ Path* unk_2E8; + /* 0x2EC */ s32 unk_2EC; + /* 0x2F0 */ Vec3f unk_2F0; + /* 0x2FC */ s16 unk_2FC; + /* 0x2FE */ s16 unk_2FE; + /* 0x300 */ s16 unk_300; + /* 0x302 */ s16 unk_302; + /* 0x304 */ s16 unk_304; + /* 0x306 */ s16 unk_306; + /* 0x308 */ s16 unk_308; + /* 0x30A */ u16 unk_30A; + /* 0x30C */ s16 unk_30C[7]; + /* 0x31A */ s16 unk_31A; + /* 0x31C */ s16 unk_31C; + /* 0x31E */ s16 unk_31E; + /* 0x320 */ s16 unk_320; + /* 0x322 */ s16 unk_322; + /* 0x324 */ s16 unk_324; + /* 0x328 */ EnZogActionFunc actionFunc; } EnZog; // size = 0x32C extern const ActorInit En_Zog_InitVars; diff --git a/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c b/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c index 551a5d7a0..c5c0c16ea 100644 --- a/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c +++ b/src/overlays/actors/ovl_Item_Etcetera/z_item_etcetera.c @@ -1,7 +1,7 @@ /* * File: z_item_etcetera.c * Overlay: ovl_Item_Etcetera - * Description: + * Description: Leftover OoT Collectible Items (bottle, key, Fire Arrow, etc.) */ #include "z_item_etcetera.h" diff --git a/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.c b/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.c index ccc7e487d..7d0068a52 100644 --- a/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.c +++ b/src/overlays/actors/ovl_Mir_Ray/z_mir_ray.c @@ -1,7 +1,7 @@ /* * File: z_mir_ray.c * Overlay: ovl_Mir_Ray - * Description: Mirror Shield Face & Light Ray + * Description: Reflectible light ray (unused, somewhat broken) */ #include "z_mir_ray.h" diff --git a/src/overlays/actors/ovl_Mir_Ray2/z_mir_ray2.c b/src/overlays/actors/ovl_Mir_Ray2/z_mir_ray2.c index 19a1e299b..d9eb30b4f 100644 --- a/src/overlays/actors/ovl_Mir_Ray2/z_mir_ray2.c +++ b/src/overlays/actors/ovl_Mir_Ray2/z_mir_ray2.c @@ -1,7 +1,7 @@ /* * File: z_mir_ray2.c * Overlay: ovl_Mir_Ray2 - * Description: + * Description: Reflectable light ray (static beam) */ #include "z_mir_ray2.h" diff --git a/src/overlays/actors/ovl_Mir_Ray3/z_mir_ray3.c b/src/overlays/actors/ovl_Mir_Ray3/z_mir_ray3.c index 0159996d8..d68880f2d 100644 --- a/src/overlays/actors/ovl_Mir_Ray3/z_mir_ray3.c +++ b/src/overlays/actors/ovl_Mir_Ray3/z_mir_ray3.c @@ -1,7 +1,7 @@ /* * File: z_mir_ray3.c * Overlay: ovl_Mir_Ray3 - * Description: + * Description: Mirror shield reflection and glow */ #include "z_mir_ray3.h" diff --git a/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.c b/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.c index 2b3a3189f..acef9d1ab 100644 --- a/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.c +++ b/src/overlays/actors/ovl_Obj_Aqua/z_obj_aqua.c @@ -5,6 +5,7 @@ */ #include "z_obj_aqua.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x00000010 @@ -66,8 +67,6 @@ Vec3f D_80ACC308 = { 1.0f / 1000.0f, 7.0f / 10000.0f, 1.0f / 1000.0f }; Vec3f D_80ACC314 = { 8.6f / 1000.0f, 8.0f / 10000.0f, 8.6f / 1000.0f }; Vec3f D_80ACC320 = { 1.0f / 100.0f, 2.6f / 1000.0f, 1.0f / 100.0f }; -extern Gfx D_0407D590[]; - void func_80ACB6A0(ObjAqua* this, GlobalContext* globalCtx) { s32 pad; Vec3f sp58; @@ -115,7 +114,7 @@ void func_80ACB940(ObjAqua* this, GlobalContext* globalCtx) { effectPos.x = this->actor.world.pos.x + (effectVel.x * 40.0f); effectPos.y = this->actor.world.pos.y; effectPos.z = this->actor.world.pos.z + (effectVel.z * 40.0f); - EffectSsIceSmoke_Spawn(globalCtx, &effectPos, &effectVel, &D_801D15B0, (s32)(Rand_ZeroOne() * 24.0f) + 70); + EffectSsIceSmoke_Spawn(globalCtx, &effectPos, &effectVel, &gZeroVec3f, (s32)(Rand_ZeroOne() * 24.0f) + 70); } void func_80ACBA10(ObjAqua* this) { @@ -285,13 +284,13 @@ void ObjAqua_Draw(Actor* thisx, GlobalContext* globalCtx) { if (actionFuncTemp) { s16 rotation = Math_SinS(this->unk_198) * 8000.0f; - Matrix_InsertZRotation_s(rotation, 1); - Matrix_Scale(1.3f, 1.0f, 1.0f, 1); - Matrix_InsertZRotation_s(rotation * -1, 1); - Matrix_Scale(10.0f / 13.0f, 1.0f, 1.0f, 1); + Matrix_InsertZRotation_s(rotation, MTXMODE_APPLY); + Matrix_Scale(1.3f, 1.0f, 1.0f, MTXMODE_APPLY); + Matrix_InsertZRotation_s(rotation * -1, MTXMODE_APPLY); + Matrix_Scale(10.0f / 13.0f, 1.0f, 1.0f, MTXMODE_APPLY); } - Matrix_RotateY(yaw, 1); + Matrix_RotateY(yaw, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, D_0407D590); + gSPDisplayList(POLY_XLU_DISP++, gGameplayKeepDrawFlameDL); CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.c b/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.c index 953f70e43..18ff5d8dc 100644 --- a/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.c +++ b/src/overlays/actors/ovl_Obj_Bean/z_obj_bean.c @@ -1,7 +1,7 @@ /* * File: z_obj_bean.c * Overlay: ovl_Obj_Bean - * Description: Floating Bean Plant / Dirt Patch + * Description: Floating Bean Plant / Soft Soil */ #include "z_obj_bean.h" diff --git a/src/overlays/actors/ovl_Obj_Bell/z_obj_bell.h b/src/overlays/actors/ovl_Obj_Bell/z_obj_bell.h index 2f2dd7b13..76265bcec 100644 --- a/src/overlays/actors/ovl_Obj_Bell/z_obj_bell.h +++ b/src/overlays/actors/ovl_Obj_Bell/z_obj_bell.h @@ -11,7 +11,7 @@ typedef struct ObjBell { /* 0x1B4 */ ColliderSphere collider2; /* 0x20C */ s16 unk_20C; // bell rotation angle? /* 0x20E */ s16 unk_20E; - /* 0x20E */ s16 unk_20F; + /* 0x210 */ s16 unk_210; /* 0x212 */ s16 unk_212; /* 0x214 */ s16 unk_214; /* 0x216 */ char unk_216[0x06]; diff --git a/src/overlays/actors/ovl_Obj_Bigicicle/z_obj_bigicicle.h b/src/overlays/actors/ovl_Obj_Bigicicle/z_obj_bigicicle.h index 79fb22868..5c3235ef2 100644 --- a/src/overlays/actors/ovl_Obj_Bigicicle/z_obj_bigicicle.h +++ b/src/overlays/actors/ovl_Obj_Bigicicle/z_obj_bigicicle.h @@ -10,7 +10,7 @@ typedef void (*ObjBigicicleActionFunc)(struct ObjBigicicle*, GlobalContext*); typedef struct ObjBigicicle { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjBigicicleActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x9C]; + /* 0x0148 */ char unk_148[0x9C]; } ObjBigicicle; // size = 0x1E4 extern const ActorInit Obj_Bigicicle_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Blockstop/z_obj_blockstop.c b/src/overlays/actors/ovl_Obj_Blockstop/z_obj_blockstop.c index 88ae42945..176f961be 100644 --- a/src/overlays/actors/ovl_Obj_Blockstop/z_obj_blockstop.c +++ b/src/overlays/actors/ovl_Obj_Blockstop/z_obj_blockstop.c @@ -1,7 +1,7 @@ /* * File: z_obj_blockstop.c * Overlay: ovl_Obj_Blockstop - * Description: + * Description: Push Block Trigger - Blockstop switch triggered by pushblock (Snowhead) */ #include "z_obj_blockstop.h" diff --git a/src/overlays/actors/ovl_Obj_Chan/z_obj_chan.h b/src/overlays/actors/ovl_Obj_Chan/z_obj_chan.h index a00ad595b..8b498f39e 100644 --- a/src/overlays/actors/ovl_Obj_Chan/z_obj_chan.h +++ b/src/overlays/actors/ovl_Obj_Chan/z_obj_chan.h @@ -10,7 +10,7 @@ typedef void (*ObjChanActionFunc)(struct ObjChan*, GlobalContext*); typedef struct ObjChan { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjChanActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x9C]; + /* 0x0148 */ char unk_148[0x9C]; } ObjChan; // size = 0x1E4 extern const ActorInit Obj_Chan_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Chikuwa/z_obj_chikuwa.c b/src/overlays/actors/ovl_Obj_Chikuwa/z_obj_chikuwa.c index 7c6580aaf..c1e74ce53 100644 --- a/src/overlays/actors/ovl_Obj_Chikuwa/z_obj_chikuwa.c +++ b/src/overlays/actors/ovl_Obj_Chikuwa/z_obj_chikuwa.c @@ -1,7 +1,7 @@ /* * File: z_obj_chikuwa.c * Overlay: ovl_Obj_Chikuwa - * Description: Falling Block Row + * Description: Falling row of blocks (unused) */ #include "z_obj_chikuwa.h" diff --git a/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.c b/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.c index c8eff2da6..4a82c7609 100644 --- a/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.c +++ b/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.c @@ -1,7 +1,7 @@ /* * File: z_obj_comb.c * Overlay: ovl_Obj_Comb - * Description: Honeycomb + * Description: Beehive */ #include "z_obj_comb.h" diff --git a/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h b/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h index 9ca91823e..303a3ed5e 100644 --- a/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h +++ b/src/overlays/actors/ovl_Obj_Comb/z_obj_comb.h @@ -10,7 +10,7 @@ typedef void (*ObjCombActionFunc)(struct ObjComb*, GlobalContext*); typedef struct ObjComb { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjCombActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x74]; + /* 0x0148 */ char unk_148[0x74]; } ObjComb; // size = 0x1BC extern const ActorInit Obj_Comb_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Danpeilift/z_obj_danpeilift.c b/src/overlays/actors/ovl_Obj_Danpeilift/z_obj_danpeilift.c index 9fa0026fe..91e4e24c7 100644 --- a/src/overlays/actors/ovl_Obj_Danpeilift/z_obj_danpeilift.c +++ b/src/overlays/actors/ovl_Obj_Danpeilift/z_obj_danpeilift.c @@ -1,7 +1,7 @@ /* * File: z_obj_danpeilift.c * Overlay: ovl_Obj_Danpeilift - * Description: Deku Shrine & Snowhead Temple Elevator + * Description: Deku Shrine & Snowhead Temple floating blocks */ #include "z_obj_danpeilift.h" diff --git a/src/overlays/actors/ovl_Obj_Demo/z_obj_demo.h b/src/overlays/actors/ovl_Obj_Demo/z_obj_demo.h index b2ffc1121..2631e91be 100644 --- a/src/overlays/actors/ovl_Obj_Demo/z_obj_demo.h +++ b/src/overlays/actors/ovl_Obj_Demo/z_obj_demo.h @@ -10,7 +10,7 @@ typedef void (*ObjDemoActionFunc)(struct ObjDemo*, GlobalContext*); typedef struct ObjDemo { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjDemoActionFunc actionFunc; - /* 0x0148 */ char unk_144[0xC]; + /* 0x0148 */ char unk_148[0xC]; } ObjDemo; // size = 0x154 extern const ActorInit Obj_Demo_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Dowsing/z_obj_dowsing.c b/src/overlays/actors/ovl_Obj_Dowsing/z_obj_dowsing.c index 98f66c014..60da4d5b5 100644 --- a/src/overlays/actors/ovl_Obj_Dowsing/z_obj_dowsing.c +++ b/src/overlays/actors/ovl_Obj_Dowsing/z_obj_dowsing.c @@ -14,7 +14,9 @@ void ObjDowsing_Init(Actor* thisx, GlobalContext* globalCtx); void ObjDowsing_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjDowsing_Update(Actor* thisx, GlobalContext* globalCtx); -#if 0 +s32 ObjDowsing_GetFlag(ObjDowsing* this, GlobalContext* globalCtx); +s32 ObjDowsing_CheckValidSpawn(ObjDowsing* this, GlobalContext* globalCtx); + const ActorInit Obj_Dowsing_InitVars = { ACTOR_OBJ_DOWSING, ACTORCAT_ITEMACTION, @@ -27,14 +29,42 @@ const ActorInit Obj_Dowsing_InitVars = { (ActorFunc)NULL, }; -#endif +s32 ObjDowsing_GetFlag(ObjDowsing* this, GlobalContext* globalCtx) { + s32 type = DOWSING_GET_TYPE(&this->actor); + s32 flag = DOWSING_GET_FLAG(&this->actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dowsing/func_80B23D50.s") + if (type == DOWSING_COLLECTIBLE) { + return Actor_GetCollectibleFlag(globalCtx, flag); + } else if (type == DOWSING_CHEST) { + return Actor_GetChestFlag(globalCtx, flag); + } else if (type == DOWSING_SWITCH) { + return Flags_GetSwitch(globalCtx, flag); + } else { + return 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dowsing/func_80B23DD0.s") +s32 ObjDowsing_CheckValidSpawn(ObjDowsing* this, GlobalContext* globalCtx) { + if (ObjDowsing_GetFlag(this, globalCtx)) { + Actor_MarkForDeath(&this->actor); + return true; + } + return false; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dowsing/ObjDowsing_Init.s") +void ObjDowsing_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjDowsing* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dowsing/ObjDowsing_Destroy.s") + ObjDowsing_CheckValidSpawn(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Dowsing/ObjDowsing_Update.s") +void ObjDowsing_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} + +void ObjDowsing_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjDowsing* this = THIS; + + if (!ObjDowsing_CheckValidSpawn(this, globalCtx)) { + func_800B8C50(thisx, globalCtx); + } +} diff --git a/src/overlays/actors/ovl_Obj_Dowsing/z_obj_dowsing.h b/src/overlays/actors/ovl_Obj_Dowsing/z_obj_dowsing.h index 5a2982cab..7b1125a28 100644 --- a/src/overlays/actors/ovl_Obj_Dowsing/z_obj_dowsing.h +++ b/src/overlays/actors/ovl_Obj_Dowsing/z_obj_dowsing.h @@ -3,8 +3,17 @@ #include "global.h" +#define DOWSING_GET_TYPE(thisx) ((thisx)->params >> 7) +#define DOWSING_GET_FLAG(thisx) ((thisx)->params & 0x7F) + struct ObjDowsing; +typedef enum { + /* 1 */ DOWSING_COLLECTIBLE = 1, + /* 2 */ DOWSING_CHEST, + /* 3 */ DOWSING_SWITCH +} DowsingType; + typedef struct ObjDowsing { /* 0x000 */ Actor actor; } ObjDowsing; // size = 0x144 diff --git a/src/overlays/actors/ovl_Obj_Entotu/z_obj_entotu.c b/src/overlays/actors/ovl_Obj_Entotu/z_obj_entotu.c index 4acf00181..0d4432ddd 100644 --- a/src/overlays/actors/ovl_Obj_Entotu/z_obj_entotu.c +++ b/src/overlays/actors/ovl_Obj_Entotu/z_obj_entotu.c @@ -1,7 +1,7 @@ /* * File: z_obj_entotu.c * Overlay: ovl_Obj_Entotu - * Description: Clock tower chimney Expelling Smoke + * Description: Clock Town Smoking Chimney */ #include "z_obj_entotu.h" diff --git a/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.c b/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.c index a4eb9ad9a..56f9b9f7a 100644 --- a/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.c +++ b/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.c @@ -5,6 +5,7 @@ */ #include "z_obj_etcetera.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x00000010 @@ -14,8 +15,8 @@ void ObjEtcetera_Init(Actor* thisx, GlobalContext* globalCtx); void ObjEtcetera_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjEtcetera_Update(Actor* thisx, GlobalContext* globalCtx); -void ObjEtcetera_PlaySmallFlutterAnimation(ObjEtcetera* this, GlobalContext* globalCtx); -void ObjEtcetera_DoIntenseOscillation(ObjEtcetera* this, GlobalContext* globalCtx); +void ObjEtcetera_PlayRustleAnimation(ObjEtcetera* this, GlobalContext* globalCtx); +void ObjEtcetera_DoBounceOscillation(ObjEtcetera* this, GlobalContext* globalCtx); void ObjEtcetera_Setup(ObjEtcetera* this, GlobalContext* globalCtx); void ObjEtcetera_DrawIdle(Actor* thisx, GlobalContext* globalCtx); void ObjEtcetera_DrawAnimated(Actor* thisx, GlobalContext* globalCtx); @@ -105,6 +106,11 @@ void ObjEtcetera_Destroy(Actor* thisx, GlobalContext* globalCtx) { Collider_DestroyCylinder(globalCtx, &this->collider); } +/** + * This function will make the flower oscillate on the X and Z axes in most situations + * where something interacts with it. When the player launches out of the flower, the + * oscillation is handled by ObjEtcetera_DoBounceOscillation instead. + */ void ObjEtcetera_DoNormalOscillation(ObjEtcetera* this, GlobalContext* globalCtx) { if (this->oscillationTimer > 0) { s32 requiredScopeTemp; @@ -119,10 +125,11 @@ void ObjEtcetera_DoNormalOscillation(ObjEtcetera* this, GlobalContext* globalCtx } } -void ObjEtcetera_StartSmallFlutterAnimation(ObjEtcetera* this) { - Animation_Change(&this->skelAnime, &D_040117A8, 1.0f, 0.0f, Animation_GetLastFrame(&D_040117A8), 2, 0.0f); +void ObjEtcetera_StartRustleAnimation(ObjEtcetera* this) { + Animation_Change(&this->skelAnime, &gDekuFlowerRustleAnim, 1.0f, 0.0f, + Animation_GetLastFrame(&gDekuFlowerRustleAnim), 2, 0.0f); this->dyna.actor.draw = ObjEtcetera_DrawAnimated; - this->actionFunc = ObjEtcetera_PlaySmallFlutterAnimation; + this->actionFunc = ObjEtcetera_PlayRustleAnimation; } void ObjEtcetera_Idle(ObjEtcetera* this, GlobalContext* globalCtx) { @@ -131,12 +138,13 @@ void ObjEtcetera_Idle(ObjEtcetera* this, GlobalContext* globalCtx) { if ((player->stateFlags3 & 0x200) && (this->dyna.actor.xzDistToPlayer < 20.0f)) { // Player is launching out of the Deku Flower - Animation_Change(&this->skelAnime, &D_0400EB7C, 1.0f, 0.0f, Animation_GetLastFrame(&D_0400EB7C), 2, 0.0f); + Animation_Change(&this->skelAnime, &gDekuFlowerBounceAnim, 1.0f, 0.0f, + Animation_GetLastFrame(&gDekuFlowerBounceAnim), 2, 0.0f); this->dyna.actor.draw = ObjEtcetera_DrawAnimated; - this->actionFunc = ObjEtcetera_DoIntenseOscillation; + this->actionFunc = ObjEtcetera_DoBounceOscillation; Actor_SetScale(&this->dyna.actor, 0.01f); this->dyna.actor.scale.y = 0.02f; - this->intenseOscillationScale = 0.003f; + this->bounceOscillationScale = 0.003f; this->oscillationTimer = 30; this->burrowFlag &= ~1; } else if ((player->stateFlags3 & 0x2000) && (this->dyna.actor.xzDistToPlayer < 30.0f) && @@ -151,7 +159,7 @@ void ObjEtcetera_Idle(ObjEtcetera* this, GlobalContext* globalCtx) { if (!(this->burrowFlag & 1)) { // Player is walking onto the Deku Flower, or falling on it from a height this->oscillationTimer = 10; - ObjEtcetera_StartSmallFlutterAnimation(this); + ObjEtcetera_StartRustleAnimation(this); } else if ((player->actor.speedXZ > 0.1f) || ((player->unk_ABC < 0.0f) && !(player->stateFlags3 & 0x100))) { // Player is walking on top of the Deku Flower, is at the very start of burrowing, or is at the very // start of launching @@ -162,19 +170,19 @@ void ObjEtcetera_Idle(ObjEtcetera* this, GlobalContext* globalCtx) { if (this->burrowFlag & 1) { // Player is walking off the Deku Flower this->oscillationTimer = 10; - ObjEtcetera_StartSmallFlutterAnimation(this); + ObjEtcetera_StartRustleAnimation(this); } this->burrowFlag &= ~1; } } if ((this->collider.base.acFlags & AC_HIT)) { this->oscillationTimer = 10; - ObjEtcetera_StartSmallFlutterAnimation(this); + ObjEtcetera_StartRustleAnimation(this); } ObjEtcetera_DoNormalOscillation(this, globalCtx); } -void ObjEtcetera_PlaySmallFlutterAnimation(ObjEtcetera* this, GlobalContext* globalCtx) { +void ObjEtcetera_PlayRustleAnimation(ObjEtcetera* this, GlobalContext* globalCtx) { if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) { this->burrowFlag |= 1; } else { @@ -187,7 +195,12 @@ void ObjEtcetera_PlaySmallFlutterAnimation(ObjEtcetera* this, GlobalContext* glo ObjEtcetera_DoNormalOscillation(this, globalCtx); } -void ObjEtcetera_DoIntenseOscillation(ObjEtcetera* this, GlobalContext* globalCtx) { +/** + * When the bounce animation plays (either because the player launched out of the flower, + * or because the flower spawned after killing a Mad Scrub), this function makes the + * flower oscillate stronger than it normally does, including an oscillation on the Y-axis. + */ +void ObjEtcetera_DoBounceOscillation(ObjEtcetera* this, GlobalContext* globalCtx) { // In order to match, we are seemingly required to access scale.x at one point // without using this. We can create a thisx or dyna pointer to achieve that, but // it's more likely they used dyna given that DynaPolyActor_IsInRidingMovingState takes a DynaPolyActor. @@ -208,12 +221,12 @@ void ObjEtcetera_DoIntenseOscillation(ObjEtcetera* this, GlobalContext* globalCt Actor_SetScale(&this->dyna.actor, 0.01f); this->dyna.actor.scale.y = 0.02f; this->oscillationTimer = 0; - this->intenseOscillationScale = 0.0f; + this->bounceOscillationScale = 0.0f; return; } - this->intenseOscillationScale *= 0.8f; - this->intenseOscillationScale -= (this->dyna.actor.scale.x - 0.01f) * 0.4f; - scaleTemp = dyna->actor.scale.x + this->intenseOscillationScale; + this->bounceOscillationScale *= 0.8f; + this->bounceOscillationScale -= (this->dyna.actor.scale.x - 0.01f) * 0.4f; + scaleTemp = dyna->actor.scale.x + this->bounceOscillationScale; Actor_SetScale(&this->dyna.actor, scaleTemp); this->dyna.actor.scale.y = 2.0f * scaleTemp; } @@ -221,7 +234,12 @@ void ObjEtcetera_DoIntenseOscillation(ObjEtcetera* this, GlobalContext* globalCt void ObjEtcetera_Setup(ObjEtcetera* this, GlobalContext* globalCtx) { CollisionHeader* colHeader = NULL; s32 type; - CollisionHeader* collisionHeaders[] = { &D_0400E710, &D_0400E710, &D_040118D8, &D_040118D8 }; + CollisionHeader* collisionHeaders[] = { + &gPinkDekuFlowerCol, + &gPinkDekuFlowerCol, + &gGoldDekuFlowerCol, + &gGoldDekuFlowerCol, + }; s32 pad; CollisionHeader* thisCollisionHeader; @@ -244,15 +262,15 @@ void ObjEtcetera_Setup(ObjEtcetera* this, GlobalContext* globalCtx) { switch (type) { case DEKU_FLOWER_TYPE_PINK: case DEKU_FLOWER_TYPE_PINK_SPAWNED_FROM_MAD_SCRUB: - SkelAnime_Init(globalCtx, &this->skelAnime, &D_04011518, &D_0400EB7C, this->jointTable, - this->morphTable, 11); - this->dList = &D_0400ED80; + SkelAnime_Init(globalCtx, &this->skelAnime, &gPinkDekuFlowerSkel, &gDekuFlowerBounceAnim, + this->jointTable, this->morphTable, DEKU_FLOWER_LIMB_MAX); + this->dList = gPinkDekuFlowerIdleDL; break; case DEKU_FLOWER_TYPE_GOLD: case DEKU_FLOWER_TYPE_GOLD_SPAWNED_FROM_MAD_SCRUB: - this->dList = &D_04011BD0; - SkelAnime_Init(globalCtx, &this->skelAnime, &D_040127E8, &D_0400EB7C, this->jointTable, - this->morphTable, 11); + this->dList = gGoldDekuFlowerIdleDL; + SkelAnime_Init(globalCtx, &this->skelAnime, &gGoldDekuFlowerSkel.sh, &gDekuFlowerBounceAnim, + this->jointTable, this->morphTable, DEKU_FLOWER_LIMB_MAX); this->collider.dim.height = 20; break; } @@ -270,13 +288,13 @@ void ObjEtcetera_Setup(ObjEtcetera* this, GlobalContext* globalCtx) { break; case DEKU_FLOWER_TYPE_PINK_SPAWNED_FROM_MAD_SCRUB: case DEKU_FLOWER_TYPE_GOLD_SPAWNED_FROM_MAD_SCRUB: - Animation_Change(&this->skelAnime, &D_0400EB7C, 1.0f, 0.0f, Animation_GetLastFrame(&D_0400EB7C), 2, - 0.0f); + Animation_Change(&this->skelAnime, &gDekuFlowerBounceAnim, 1.0f, 0.0f, + Animation_GetLastFrame(&gDekuFlowerBounceAnim), 2, 0.0f); this->dyna.actor.draw = ObjEtcetera_DrawAnimated; - this->actionFunc = ObjEtcetera_DoIntenseOscillation; + this->actionFunc = ObjEtcetera_DoBounceOscillation; Actor_SetScale(&this->dyna.actor, 0.0f); this->oscillationTimer = 30; - this->intenseOscillationScale = 0.0f; + this->bounceOscillationScale = 0.0f; this->dyna.actor.focus.pos.y = this->dyna.actor.home.pos.y + 10.0f; this->dyna.actor.targetMode = 3; break; @@ -299,6 +317,11 @@ void ObjEtcetera_Update(Actor* thisx, GlobalContext* globalCtx) { CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); } +/** + * When the flower isn't animating, this function is used to draw it. + * It draws the flower as a single, non-moving display list that encompasses the whole flower. + * When an animation is finished, functions are expected to set the actor's draw function to this. + */ void ObjEtcetera_DrawIdle(Actor* thisx, GlobalContext* globalCtx) { ObjEtcetera* this = THIS; @@ -311,6 +334,11 @@ void ObjEtcetera_DrawIdle(Actor* thisx, GlobalContext* globalCtx) { CLOSE_DISPS(globalCtx->state.gfxCtx); } +/** + * When the flower is animating, this function is used to draw it. + * It draws the flower as an animated bunch of limbs using the SkelAnime system. + * When a function wants to play an animation, it is expected to set the actor's draw function to this. + */ void ObjEtcetera_DrawAnimated(Actor* thisx, GlobalContext* globalCtx) { ObjEtcetera* this = THIS; diff --git a/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h b/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h index f5642ff28..a52f5ae2e 100644 --- a/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h +++ b/src/overlays/actors/ovl_Obj_Etcetera/z_obj_etcetera.h @@ -13,6 +13,26 @@ typedef enum { /* 4 */ DEKU_FLOWER_TYPE_MAX, } DekuFlowerType; +/** + * For the petal/leaf directions, "back" is negative and "front" is positive + * on the flower's local Z-axis. "Left" and "right" are relative to the front + * and back. + */ +typedef enum { + /* 0 */ DEKU_FLOWER_LIMB_NONE, + /* 1 */ DEKU_FLOWER_LIMB_BASE, + /* 2 */ DEKU_FLOWER_LIMB_CENTER, + /* 3 */ DEKU_FLOWER_LIMB_BACK_PETAL_OR_LEAF, + /* 4 */ DEKU_FLOWER_LIMB_FRONT_PETAL_OR_LEAF, + /* 5 */ DEKU_FLOWER_LIMB_FRONT_RIGHT_PETAL, + /* 6 */ DEKU_FLOWER_LIMB_BACK_RIGHT_PETAL, + /* 7 */ DEKU_FLOWER_LIMB_RIGHT_PETAL_OR_LEAF, + /* 8 */ DEKU_FLOWER_LIMB_FRONT_LEFT_PETAL, + /* 9 */ DEKU_FLOWER_LIMB_LEFT_PETAL_OR_LEAF, + /* 10 */ DEKU_FLOWER_LIMB_BACK_LEFT_PETAL, + /* 11 */ DEKU_FLOWER_LIMB_MAX, +} DekuFlowerLimbs; + struct ObjEtcetera; typedef void (*ObjEtceteraActionFunc)(struct ObjEtcetera*, GlobalContext*); @@ -21,9 +41,9 @@ typedef struct ObjEtcetera { /* 0x000 */ DynaPolyActor dyna; /* 0x15C */ SkelAnime skelAnime; /* 0x1A0 */ ColliderCylinder collider; - /* 0x1EC */ Vec3s jointTable[11]; - /* 0x22E */ Vec3s morphTable[11]; - /* 0x270 */ f32 intenseOscillationScale; + /* 0x1EC */ Vec3s jointTable[DEKU_FLOWER_LIMB_MAX]; + /* 0x22E */ Vec3s morphTable[DEKU_FLOWER_LIMB_MAX]; + /* 0x270 */ f32 bounceOscillationScale; /* 0x274 */ s16 oscillationTimer; /* 0x276 */ u16 burrowFlag; /* 0x278 */ s8 objIndex; diff --git a/src/overlays/actors/ovl_Obj_Flowerpot/z_obj_flowerpot.c b/src/overlays/actors/ovl_Obj_Flowerpot/z_obj_flowerpot.c index 8a6795094..793f7cbe0 100644 --- a/src/overlays/actors/ovl_Obj_Flowerpot/z_obj_flowerpot.c +++ b/src/overlays/actors/ovl_Obj_Flowerpot/z_obj_flowerpot.c @@ -5,6 +5,7 @@ */ #include "z_obj_flowerpot.h" +#include "objects/object_flowerpot/object_flowerpot.h" #define FLAGS 0x00000000 @@ -15,7 +16,21 @@ void ObjFlowerpot_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjFlowerpot_Update(Actor* thisx, GlobalContext* globalCtx); void ObjFlowerpot_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80A1C818(ObjFlowerpot* this); +void func_80A1C838(ObjFlowerpot* this, GlobalContext* globalCtx); +void func_80A1CBF8(ObjFlowerpot* this); +void func_80A1CC0C(ObjFlowerpot* this, GlobalContext* globalCtx); +void func_80A1CD10(ObjFlowerpot* this); +void func_80A1CEF4(ObjFlowerpot* this2, GlobalContext* globalCtx); + +static u32 D_80A1D830; +static MtxF D_80A1D838[8]; +static s16 D_80A1DA38; +static s16 D_80A1DA3A; +static s16 D_80A1DA3C; +static s16 D_80A1DA3E; +static s16 D_80A1DA40; + const ActorInit Obj_Flowerpot_InitVars = { ACTOR_OBJ_FLOWERPOT, ACTORCAT_PROP, @@ -28,86 +43,646 @@ const ActorInit Obj_Flowerpot_InitVars = { (ActorFunc)ObjFlowerpot_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[2] = { -static ColliderJntSphElementInit D_80A1D3A0[2] = { +static ColliderJntSphElementInit sJntSphElementsInit[2] = { { - { ELEMTYPE_UNK0, { 0x00400000, 0x00, 0x02 }, { 0x05CBFFBE, 0x00, 0x00 }, TOUCH_ON | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0x00400000, 0x00, 0x02 }, + { 0x05CBFFBE, 0x00, 0x00 }, + TOUCH_ON | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 100, 0 }, 12 }, 100 }, }, { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x0580C71C, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_NONE, }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x0580C71C, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_NONE, + }, { 1, { { 0, 300, 0 }, 12 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_80A1D3E8 = { - { COLTYPE_NONE, AT_ON | AT_TYPE_PLAYER, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_JNTSPH, }, - 2, D_80A1D3A0, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_NONE, + AT_ON | AT_TYPE_PLAYER, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_JNTSPH, + }, + 2, + sJntSphElementsInit, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80A1D414[] = { - ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_CONTINUE), - ICHAIN_F32_DIV1000(minVelocityY, -20000, ICHAIN_CONTINUE), - ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneForward, 1600, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_STOP), +static s16 D_80A1D3F8 = 0; + +static s16 D_80A1D3FC = 0; + +static s16 D_80A1D400 = 0; + +static u8 D_80A1D404 = true; + +static Vec3f D_80A1D408 = { 0.0f, 20.0f, 0.0f }; + +static InitChainEntry sInitChain[] = { + ICHAIN_F32_DIV1000(gravity, -2000, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(minVelocityY, -20000, ICHAIN_CONTINUE), + ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneForward, 1600, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneScale, 100, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 100, ICHAIN_STOP), }; -#endif +void func_80A1B3D0(void) { + s32 i; + s32 pad; + f32 spB4; + f32* ptr; + f32 spAC; + f32 spA8; + f32 tempf1; + f32 tempf2; + f32 tempf3; + f32 tempf4; + f32 tempf5; + f32 sp74[8]; + f32 temp_f20; + f32 temp_f22; + f32 temp_f24; + f32 temp_f26; + f32 temp_f28; + f32 temp_f0; + f32 temp_f30; -extern ColliderJntSphElementInit D_80A1D3A0[2]; -extern ColliderJntSphInit D_80A1D3E8; -extern InitChainEntry D_80A1D414[]; + D_80A1DA38 += 70; + D_80A1DA3A += 300; + D_80A1DA3C += 700; + D_80A1DA3E += 1300; + D_80A1DA40 += 8900; -extern UNK_TYPE D_060012E0; -extern UNK_TYPE D_060014F0; -extern UNK_TYPE D_060015B0; + temp_f28 = Math_SinS(D_80A1DA38); + spB4 = Math_SinS(D_80A1DA3A); + temp_f30 = Math_SinS(D_80A1DA3C); + spAC = Math_SinS(D_80A1DA3E); + spA8 = Math_SinS(D_80A1DA40); + temp_f26 = Math_CosS(D_80A1DA38); + temp_f20 = Math_CosS(D_80A1DA3A); + temp_f22 = Math_CosS(D_80A1DA3C); + temp_f24 = Math_CosS(D_80A1DA3E); + temp_f0 = Math_CosS(D_80A1DA40); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1B3D0.s") + sp74[0] = (temp_f28 - temp_f20) * temp_f30 * temp_f26 * temp_f28 * 0.0012f; + sp74[1] = (spB4 - temp_f22) * spAC * temp_f20 * temp_f28 * 0.0012f; + sp74[2] = (temp_f30 - temp_f24) * temp_f22 * temp_f28 * temp_f26 * 0.0012f; + sp74[3] = (spAC - temp_f20) * temp_f24 * spB4 * temp_f26 * 0.0012f; + sp74[4] = (temp_f28 - temp_f22) * temp_f28 * spB4 * spA8 * 0.0013f; + sp74[5] = (spB4 - temp_f24) * temp_f30 * spAC * spA8 * 0.0013f; + sp74[6] = (temp_f30 - temp_f26) * temp_f26 * temp_f20 * temp_f0 * 0.0013f; + sp74[7] = (spAC - temp_f20) * temp_f22 * temp_f24 * temp_f0 * 0.0013f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1B840.s") + for (i = 0; i < ARRAY_COUNT(D_80A1D838); i++) { + ptr = (f32*)&D_80A1D838[i].mf[0]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1B914.s") + tempf1 = sp74[(i + 0) & 7]; + tempf2 = sp74[(i + 1) & 7]; + tempf3 = sp74[(i + 2) & 7]; + tempf4 = sp74[(i + 3) & 7]; + tempf5 = sp74[(i + 4) & 7]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1B994.s") + ptr[0] = sp74[1] * 0.2f; + ptr[1] = tempf1; + ptr[2] = tempf2; + ptr[3] = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1B9CC.s") + ptr[4] = tempf3; + ptr[5] = sp74[0]; + ptr[6] = tempf3; + ptr[7] = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1BA04.s") + ptr[8] = tempf4; + ptr[9] = tempf5; + ptr[10] = sp74[3] * 0.2f; + ptr[11] = 0.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1BA44.s") + ptr[12] = 0.0f; + ptr[13] = 0.0f; + ptr[14] = 0.0f; + ptr[15] = 0.0f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1BD80.s") +void func_80A1B840(MtxF* matrix) { + MtxF* temp = Matrix_GetCurrentState(); + f32* tmp = (f32*)&temp->mf[0]; + f32* tmp2 = (f32*)&matrix->mf[0]; + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1C0FC.s") + for (i = 0; i < 16; i++) { + *tmp++ += *tmp2++; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1C328.s") +void func_80A1B914(ObjFlowerpot* this, GlobalContext* globalCtx) { + if (!(this->unk_1EA & 4)) { + s32 temp_v0 = func_800A8150(ENOBJFLOWERPOT_GET_3F(&this->actor)); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1C554.s") + if (temp_v0 >= 0) { + s32 params = ENOBJFLOWERPOT_GET_7F00(&this->actor); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1C5E8.s") + Item_DropCollectible(globalCtx, &this->actor.world.pos, temp_v0 | (params << 8)); + this->unk_1EA |= 4; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1C62C.s") +void func_80A1B994(ObjFlowerpot* this, GlobalContext* globalCtx) { + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_POT_BROKEN); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/ObjFlowerpot_Init.s") +void func_80A1B9CC(ObjFlowerpot* this, GlobalContext* globalCtx) { + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 20, NA_SE_EV_PLANT_BROKEN); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/ObjFlowerpot_Destroy.s") +void func_80A1BA04(ObjFlowerpot* this, Vec3f* arg1) { + Matrix_SetStateRotationAndTranslation(this->actor.world.pos.x, this->actor.world.pos.y, this->actor.world.pos.z, + &this->actor.shape.rot); + Matrix_MultiplyVector3fByState(&D_80A1D408, arg1); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1C818.s") +void func_80A1BA44(ObjFlowerpot* this, GlobalContext* globalCtx) { + s32 i; + Vec3f spD0; + Vec3f spC4; + Vec3f spB8; + f32 temp_f0; + f32 temp_f20; + s16 phi_s3; + s32 phi_s0; + s32 phi_s1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1C838.s") + spD0.x = this->actor.world.pos.x; + spD0.y = this->actor.world.pos.y; + spD0.z = this->actor.world.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1CBF8.s") + for (i = 0, phi_s3 = 0; i < 18; i++, phi_s3 += 0xE38) { + temp_f20 = (Rand_ZeroOne() * 8.0f) + 2.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1CC0C.s") + spC4.x = Math_SinS((s32)(Rand_ZeroOne() * 3640.0f) + phi_s3) * temp_f20; + spC4.y = Rand_ZeroOne() * 30.0f; + spC4.z = Math_CosS((s32)(Rand_ZeroOne() * 3640.0f) + phi_s3) * temp_f20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1CD10.s") + spB8.x = spC4.x * 0.27f; + spB8.y = (Rand_ZeroOne() * 6.0f) + 2.6f + ((30.0f - spC4.y) * 0.2f); + spB8.z = spC4.z * 0.27f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/func_80A1CEF4.s") + Math_Vec3f_Sum(&spC4, &spD0, &spC4); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/ObjFlowerpot_Update.s") + temp_f0 = Rand_ZeroOne(); + if (temp_f0 < 0.2f) { + phi_s0 = 32; + phi_s1 = 0; + } else if (temp_f0 < 0.6f) { + phi_s0 = 65; + phi_s1 = 1; + } else { + phi_s0 = 64; + phi_s1 = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Flowerpot/ObjFlowerpot_Draw.s") + EffectSsKakera_Spawn(globalCtx, &spC4, &spB8, &spC4, -600, phi_s0, 30, 0, 0, (Rand_ZeroOne() * 12.0f) + 16.6f, + phi_s1, 0, 35, -1, ACTOR_DEMO_GETITEM, object_flowerpot_DL_0015B0); + } + + spD0.y += 20.0f; + + func_800BBFB0(globalCtx, &spD0, 30.0f, 2, 20, 50, 1); + func_800BBFB0(globalCtx, &spD0, 30.0f, 2, 10, 80, 1); + func_800BBFB0(globalCtx, &spD0, 30.0f, 1, 10, 40, 1); +} + +void func_80A1BD80(ObjFlowerpot* this, GlobalContext* globalCtx) { + s32 i; + Vec3f spC8; + Vec3f spBC; + Vec3f spB0; + f32 temp_f20; + s16 phi_s1; + s32 phi_s0; + + spC8.x = this->actor.world.pos.x; + spC8.y = this->actor.world.pos.y; + spC8.z = this->actor.world.pos.z; + + for (i = 0, phi_s1 = 0; i < 14; i++, phi_s1 += 0x1249) { + temp_f20 = (Rand_ZeroOne() * 8.0f) + 2.0f; + + spBC.x = Math_SinS((s32)(Rand_ZeroOne() * 4681.0f) + phi_s1) * temp_f20; + spBC.y = Rand_ZeroOne() * 20.0f; + spBC.z = Math_CosS((s32)(Rand_ZeroOne() * 4681.0f) + phi_s1) * temp_f20; + + spB0.x = spBC.x * 0.17f; + spB0.y = (Rand_ZeroOne() * 5.0f) + 1.4f; + spB0.z = spBC.z * 0.17f; + + Math_Vec3f_Sum(&spBC, &spC8, &spBC); + + if (Rand_ZeroOne() < 0.2f) { + phi_s0 = 64; + } else { + phi_s0 = 32; + } + + EffectSsKakera_Spawn(globalCtx, &spBC, &spB0, &spBC, -240, phi_s0, 40, 0, 0, (Rand_ZeroOne() * 20.0f) + 10.6f, + 0, 0, 42, -1, ACTOR_DEMO_GETITEM, object_flowerpot_DL_0015B0); + } + + spBC.y = this->actor.world.pos.y + this->actor.depthInWater; + + for (phi_s1 = 0, i = 0; i < 4; i++, phi_s1 += 0x4000) { + spBC.x = (Math_SinS((s32)(Rand_ZeroOne() * 7200.0f) + phi_s1) * 15.0f) + this->actor.world.pos.x; + spBC.z = (Math_CosS((s32)(Rand_ZeroOne() * 7200.0f) + phi_s1) * 15.0f) + this->actor.world.pos.z; + EffectSsGSplash_Spawn(globalCtx, &spBC, NULL, NULL, 0, 200); + } + + spBC.x = this->actor.world.pos.x; + spBC.z = this->actor.world.pos.z; + EffectSsGSplash_Spawn(globalCtx, &spBC, NULL, NULL, 0, 350); + EffectSsGRipple_Spawn(globalCtx, &spBC, 150, 650, 0); +} + +void func_80A1C0FC(ObjFlowerpot* this, GlobalContext* globalCtx) { + Vec3f spC4; + Vec3f spB8; + Vec3f spAC; + f32 temp_f20; + s16 phi_s0; + s32 i; + + func_80A1BA04(this, &spC4); + + for (i = 0, phi_s0 = 0; i < 10; i++, phi_s0 += 0x1999) { + temp_f20 = (Rand_ZeroOne() * 18.0f) + 2.0f; + + spB8.x = Math_SinS((s32)(Rand_ZeroOne() * 6553.0f) + phi_s0) * temp_f20; + spB8.y = Rand_ZeroOne() * 15.0f; + spB8.z = Math_CosS((s32)(Rand_ZeroOne() * 6553.0f) + phi_s0) * temp_f20; + + spAC.x = spB8.x * 0.23f; + spAC.y = (Rand_ZeroOne() * 8.0f) + 1.5f; + spAC.z = spB8.z * 0.23f; + + Math_Vec3f_Sum(&spB8, &spC4, &spB8); + EffectSsKakera_Spawn(globalCtx, &spB8, &spAC, &spB8, -100, 64, 40, 0, 0, (Rand_ZeroOne() * 16.0f) + 14.0f, 0, 0, + 80, -1, ACTOR_DEMO_GETITEM, object_flowerpot_DL_0014F0); + } +} + +void func_80A1C328(ObjFlowerpot* this, GlobalContext* globalCtx) { + Vec3f spC4; + Vec3f spB8; + Vec3f spAC; + f32 temp_f20; + s16 phi_s0; + s32 i; + + func_80A1BA04(this, &spC4); + + for (i = 0, phi_s0 = 0; i < 10; i++, phi_s0 += 0x1999) { + temp_f20 = (Rand_ZeroOne() * 18.0f) + 2.0f; + + spB8.x = Math_SinS((s32)(Rand_ZeroOne() * 6553.0f) + phi_s0) * temp_f20; + spB8.y = Rand_ZeroOne() * 15.0f; + spB8.z = Math_CosS((s32)(Rand_ZeroOne() * 6553.0f) + phi_s0) * temp_f20; + + spAC.x = spB8.x * 0.18f; + spAC.y = (Rand_ZeroOne() * 4.0f) + 1.2f; + spAC.z = spB8.z * 0.18f; + + Math_Vec3f_Sum(&spB8, &spC4, &spB8); + EffectSsKakera_Spawn(globalCtx, &spB8, &spAC, &spB8, -80, 64, 44, 0, 0, (Rand_ZeroOne() * 16.0f) + 14.0f, 0, 0, + 80, -1, ACTOR_DEMO_GETITEM, object_flowerpot_DL_0014F0); + } +} + +void func_80A1C554(ObjFlowerpot* this) { + if ((this->actor.projectedPos.z < 455.0f) && (this->actor.projectedPos.z > -10.0f)) { + this->actor.shape.shadowDraw = func_800B3FC0; + this->actor.shape.shadowScale = 1.9f; + if (this->actor.projectedPos.z < 255.0f) { + this->actor.shape.shadowAlpha = 200; + } else { + this->actor.shape.shadowAlpha = 455 - (s32)this->actor.projectedPos.z; + } + } else { + this->actor.shape.shadowDraw = NULL; + } +} + +void func_80A1C5E8(ObjFlowerpot* this, GlobalContext* globalCtx) { + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 18.0f, 15.0f, 0.0f, 0x45); +} + +void func_80A1C62C(ObjFlowerpot* this, GlobalContext* globalCtx) { + if (!(this->unk_1EA & 4) && (globalCtx->roomCtx.currRoom.num != this->unk_1EC)) { + this->unk_1EA |= 4; + } +} + +void ObjFlowerpot_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjFlowerpot* this = THIS; + + Actor_ProcessInitChain(&this->actor, sInitChain); + + if (this->actor.shape.rot.y == 0) { + this->actor.shape.rot.y = this->actor.world.rot.y = (u32)Rand_Next() >> 0x10; + } + + Collider_InitJntSph(globalCtx, &this->collider); + Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElements); + Matrix_SetStateRotationAndTranslation(this->actor.home.pos.x, this->actor.home.pos.y, this->actor.home.pos.z, + &this->actor.shape.rot); + Matrix_Scale(0.1f, 0.1f, 0.1f, MTXMODE_APPLY); + Collider_UpdateSpheres(0, &this->collider); + Collider_UpdateSpheres(1, &this->collider); + + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + this->unk_1EC = this->actor.room; + func_80A1C818(this); + + if (D_80A1D404) { + D_80A1DA38 = (u32)Rand_Next() >> 0x10; + D_80A1DA3A = (u32)Rand_Next() >> 0x10; + D_80A1DA3C = (u32)Rand_Next() >> 0x10; + D_80A1DA3E = (u32)Rand_Next() >> 0x10; + D_80A1DA40 = (u32)Rand_Next() >> 0x10; + D_80A1D404 = false; + func_80A1B3D0(); + D_80A1D830 = globalCtx->gameplayFrames; + } + this->unk_1EB = D_80A1D400 & 7; + D_80A1D400++; +} + +void ObjFlowerpot_Destroy(Actor* thisx, GlobalContext* globalCtx) { + Collider_DestroyJntSph(globalCtx, &THIS->collider); +} + +void func_80A1C818(ObjFlowerpot* this) { + this->actionFunc = func_80A1C838; + this->unk_1EA |= 1; +} + +void func_80A1C838(ObjFlowerpot* this, GlobalContext* globalCtx) { + s32 pad; + + if (Actor_HasParent(&this->actor, globalCtx)) { + func_80A1CBF8(this); + this->actor.room = -1; + this->actor.colChkInfo.mass = 180; + this->actor.flags |= 0x10; + if (func_800A817C(ENOBJFLOWERPOT_GET_3F(&this->actor))) { + func_80A1B914(this, globalCtx); + } + func_800B8E58(&this->actor, NA_SE_PL_PULL_UP_POT); + } else if ((this->actor.bgCheckFlags & 0x20) && (this->actor.depthInWater > 19.0f)) { + if (!(this->unk_1EA & 2)) { + func_80A1B914(this, globalCtx); + func_80A1C328(this, globalCtx); + func_80A1B9CC(this, globalCtx); + this->unk_1EA |= 2; + } + func_80A1BD80(this, globalCtx); + func_80A1B994(this, globalCtx); + Actor_MarkForDeath(&this->actor); + } else if ((this->collider.elements[0].info.bumperFlags & 2) && + (this->collider.elements[0].info.acHitInfo->toucher.dmgFlags & 0x058BFFBC)) { + if (!(this->unk_1EA & 2)) { + func_80A1B914(this, globalCtx); + func_80A1C0FC(this, globalCtx); + func_80A1B9CC(this, globalCtx); + this->unk_1EA |= 2; + } + func_80A1BA44(this, globalCtx); + func_80A1B994(this, globalCtx); + Actor_MarkForDeath(&this->actor); + } else { + if (this->collider.elements[1].info.bumperFlags & 2) { + if (!(this->unk_1EA & 2)) { + this->unk_1EA |= 2; + this->collider.elements[1].info.bumperFlags &= ~0x1; + func_80A1C0FC(this, globalCtx); + func_80A1B914(this, globalCtx); + func_80A1B9CC(this, globalCtx); + } + } + + if (this->unk_1EA & 1) { + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + func_80A1C5E8(this, globalCtx); + if (this->actor.bgCheckFlags & 1) { + if (this->actor.colChkInfo.mass == MASS_IMMOVABLE) { + if (DynaPoly_GetActor(&globalCtx->colCtx, this->actor.floorBgId) == NULL) { + this->actor.flags &= ~0x10; + this->unk_1EA &= ~0x1; + } + } else if (Math3D_Vec3fDistSq(&this->actor.world.pos, &this->actor.prevPos) < 0.01f) { + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + } + } + } + + if (!(this->collider.base.ocFlags1 & OC1_TYPE_PLAYER) && (this->actor.xzDistToPlayer > 28.0f)) { + this->collider.base.ocFlags1 |= OC1_TYPE_PLAYER; + } + + this->collider.base.acFlags &= ~AC_HIT; + + if (this->actor.xzDistToPlayer < 600.0f) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + + if (this->actor.xzDistToPlayer < 180.0f) { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + + if (this->actor.xzDistToPlayer < 100.0f) { + s16 temp_v0_3 = this->actor.yawTowardsPlayer - GET_PLAYER(globalCtx)->actor.world.rot.y; + + if (ABS_ALT(temp_v0_3) >= 0x5556) { + func_800B8A1C(&this->actor, globalCtx, 0, 36.0f, 30.0f); + } + } + } + } + } +} + +void func_80A1CBF8(ObjFlowerpot* this) { + this->actionFunc = func_80A1CC0C; +} + +void func_80A1CC0C(ObjFlowerpot* this, GlobalContext* globalCtx) { + s32 pad; + + func_80A1C62C(this, globalCtx); + + if (Actor_HasNoParent(&this->actor, globalCtx)) { + this->actor.room = globalCtx->roomCtx.currRoom.num; + if (fabsf(this->actor.speedXZ) < 0.1f) { + func_80A1C818(this); + func_800B8E58(&GET_PLAYER(globalCtx)->actor, NA_SE_PL_PUT_DOWN_POT); + this->collider.base.ocFlags1 &= ~OC1_TYPE_PLAYER; + } else { + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + func_80A1CD10(this); + } + func_80A1C5E8(this, globalCtx); + } else { + Vec3f sp30; + s32 sp2C; + + sp30.x = this->actor.world.pos.x; + sp30.y = this->actor.world.pos.y + 20.0f; + sp30.z = this->actor.world.pos.z; + this->actor.floorHeight = + BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &sp2C, &this->actor, &sp30); + } +} + +void func_80A1CD10(ObjFlowerpot* this) { + f32 sp1C; + + this->actionFunc = func_80A1CEF4; + this->unk_1E8 = 64; + + if (this->unk_1EA & 2) { + sp1C = (Rand_ZeroOne() * 1.2f) - 1.1f; + if (sp1C < -0.9f) { + sp1C = -0.9f; + } + D_80A1D3F8 = sp1C * 8000.0f; + D_80A1D3FC = ((Rand_ZeroOne() - 0.5f) * 3800.0f) * (fabsf(sp1C) + 0.1f); + this->actor.shape.yOffset = -71.5f; + this->actor.world.pos.y += 7.15f; + } else { + sp1C = (Rand_ZeroOne() - 0.78f) * 1.3f; + if (sp1C < -0.78f) { + sp1C = -0.78f; + } else if (sp1C > 0.22000003f) { + sp1C = 0.22000003f; + } + D_80A1D3F8 = sp1C * 6200.0f; + D_80A1D3FC = (Rand_ZeroOne() - 0.5f) * 4200.0f; + this->actor.shape.yOffset = -110.0f; + this->actor.world.pos.y += 11.0f; + } +} + +void func_80A1CEF4(ObjFlowerpot* this2, GlobalContext* globalCtx) { + ObjFlowerpot* this = this2; + s32 sp28 = this->collider.elements[0].info.toucherFlags & TOUCH_HIT; + + if (sp28) { + this->collider.elements[0].info.toucherFlags &= ~TOUCH_ON; + } + + if (this->unk_1E8 > 0) { + this->unk_1E8--; + } + + func_80A1C62C(this, globalCtx); + + if ((this->actor.bgCheckFlags & (0x8 | 0x2 | 0x1)) || sp28 || (this->unk_1E8 <= 0)) { + if (!(this->unk_1EA & 2)) { + func_80A1B914(this, globalCtx); + func_80A1C0FC(this, globalCtx); + func_80A1B9CC(this, globalCtx); + this->unk_1EA |= 2; + } + func_80A1BA44(this, globalCtx); + func_80A1B994(this, globalCtx); + Actor_MarkForDeath(&this->actor); + return; + } + + if (this->actor.bgCheckFlags & 0x40) { + if (!(this->unk_1EA & 2)) { + func_80A1B914(this, globalCtx); + func_80A1C328(this, globalCtx); + func_80A1B9CC(this, globalCtx); + this->unk_1EA |= 2; + } + func_80A1BD80(this, globalCtx); + func_80A1B994(this, globalCtx); + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 40, NA_SE_EV_DIVE_INTO_WATER_L); + Actor_MarkForDeath(&this->actor); + return; + } + + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + + if (!(this->unk_1EA & 2)) { + D_80A1D3F8 += (s16)(this->actor.shape.rot.x * -0.06f); + } else { + Math_StepToS(&D_80A1D3F8, 0, 80); + Math_StepToS(&D_80A1D3FC, 0, 20); + } + + this->actor.shape.rot.x += D_80A1D3F8; + this->actor.shape.rot.y += D_80A1D3FC; + + func_80A1C5E8(this, globalCtx); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetAT(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void ObjFlowerpot_Update(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + ObjFlowerpot* this = THIS; + + this->actionFunc(this, globalCtx); + + func_80A1C554(this); + + if ((D_80A1D830 != globalCtx->gameplayFrames) && (globalCtx->roomCtx.currRoom.unk3 == 0)) { + func_80A1B3D0(); + D_80A1D830 = globalCtx->gameplayFrames; + } +} + +void ObjFlowerpot_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjFlowerpot* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_flowerpot_DL_0012E0); + + if ((this->actionFunc != func_80A1C838) || (this->unk_1EA & 1)) { + Collider_UpdateSpheres(0, &this->collider); + if (!(this->unk_1EA & 2)) { + Collider_UpdateSpheres(1, &this->collider); + } + } + + if (!(this->unk_1EA & 2)) { + if ((globalCtx->roomCtx.currRoom.unk3 == 0) && (this->actionFunc == func_80A1C838)) { + if ((this->actor.projectedPos.z > -150.0f) && (this->actor.projectedPos.z < 400.0f)) { + func_80A1B840(&D_80A1D838[this->unk_1EB]); + + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + } + } + + gSPDisplayList(POLY_OPA_DISP++, object_flowerpot_DL_001408); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Flowerpot/z_obj_flowerpot.h b/src/overlays/actors/ovl_Obj_Flowerpot/z_obj_flowerpot.h index 3396a1aba..01557bc2b 100644 --- a/src/overlays/actors/ovl_Obj_Flowerpot/z_obj_flowerpot.h +++ b/src/overlays/actors/ovl_Obj_Flowerpot/z_obj_flowerpot.h @@ -7,11 +7,18 @@ struct ObjFlowerpot; typedef void (*ObjFlowerpotActionFunc)(struct ObjFlowerpot*, GlobalContext*); +#define ENOBJFLOWERPOT_GET_3F(thisx) ((thisx)->params & 0x3F) +#define ENOBJFLOWERPOT_GET_7F00(thisx) (((thisx)->params >> 8) & 0x7F) + typedef struct ObjFlowerpot { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0xA0]; + /* 0x0144 */ ColliderJntSph collider; + /* 0x0164 */ ColliderJntSphElement colliderElements[2]; /* 0x01E4 */ ObjFlowerpotActionFunc actionFunc; - /* 0x01E8 */ char unk_1E8[0x8]; + /* 0x01E8 */ s16 unk_1E8; + /* 0x01EA */ u8 unk_1EA; + /* 0x01EB */ s8 unk_1EB; + /* 0x01EC */ s8 unk_1EC; } ObjFlowerpot; // size = 0x1F0 extern const ActorInit Obj_Flowerpot_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Funen/z_obj_funen.c b/src/overlays/actors/ovl_Obj_Funen/z_obj_funen.c index b2b624282..30d0b2f0a 100644 --- a/src/overlays/actors/ovl_Obj_Funen/z_obj_funen.c +++ b/src/overlays/actors/ovl_Obj_Funen/z_obj_funen.c @@ -1,7 +1,7 @@ /* * File: z_obj_funen.c * Overlay: ovl_Obj_Funen - * Description: + * Description: Unused(?) Stone Tower smoke */ #include "z_obj_funen.h" @@ -36,7 +36,7 @@ void ObjFunen_Draw(Actor* thisx, GlobalContext* globalCtx) { OPEN_DISPS(globalCtx->state.gfxCtx); func_8012C2DC(globalCtx->state.gfxCtx); - Matrix_RotateY((s16)(func_800DFCDC(GET_ACTIVE_CAM(globalCtx)) - 0x8000), 1); + Matrix_RotateY((s16)(func_800DFCDC(GET_ACTIVE_CAM(globalCtx)) - 0x8000), MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_MODELVIEW | G_MTX_LOAD | G_MTX_NOPUSH); diff --git a/src/overlays/actors/ovl_Obj_Ghaka/z_obj_ghaka.c b/src/overlays/actors/ovl_Obj_Ghaka/z_obj_ghaka.c index 3d5ee7848..4cfc3fcf7 100644 --- a/src/overlays/actors/ovl_Obj_Ghaka/z_obj_ghaka.c +++ b/src/overlays/actors/ovl_Obj_Ghaka/z_obj_ghaka.c @@ -1,5 +1,5 @@ /* - * File z_obj_ghaka.c + * File: z_obj_ghaka.c * Overlay: ovl_Obj_Ghaka * Description: Darmani's Gravestone */ diff --git a/src/overlays/actors/ovl_Obj_Grass/z_obj_grass.c b/src/overlays/actors/ovl_Obj_Grass/z_obj_grass.c index 88d20d49b..8dc01d386 100644 --- a/src/overlays/actors/ovl_Obj_Grass/z_obj_grass.c +++ b/src/overlays/actors/ovl_Obj_Grass/z_obj_grass.c @@ -1,7 +1,7 @@ /* * File: z_obj_grass.c * Overlay: ovl_Obj_Grass - * Description: + * Description: "Master" instance of grass for unit spawned by Obj_Grass_Unit */ #include "z_obj_grass.h" diff --git a/src/overlays/actors/ovl_Obj_Grass_Carry/z_obj_grass_carry.c b/src/overlays/actors/ovl_Obj_Grass_Carry/z_obj_grass_carry.c index a603509fa..af5ebd44a 100644 --- a/src/overlays/actors/ovl_Obj_Grass_Carry/z_obj_grass_carry.c +++ b/src/overlays/actors/ovl_Obj_Grass_Carry/z_obj_grass_carry.c @@ -1,7 +1,7 @@ /* * File: z_obj_grass_carry.c * Overlay: ovl_Obj_Grass_Carry - * Description: + * Description: Grass that the player is holding (spawned by Obj_Grass_Unit) */ #include "z_obj_grass_carry.h" diff --git a/src/overlays/actors/ovl_Obj_Grass_Unit/z_obj_grass_unit.c b/src/overlays/actors/ovl_Obj_Grass_Unit/z_obj_grass_unit.c index e3787849f..88beb7a6b 100644 --- a/src/overlays/actors/ovl_Obj_Grass_Unit/z_obj_grass_unit.c +++ b/src/overlays/actors/ovl_Obj_Grass_Unit/z_obj_grass_unit.c @@ -1,7 +1,7 @@ /* * File: z_obj_grass_unit.c * Overlay: ovl_Obj_Grass_Unit - * Description: + * Description: Spawner for circular patch of grass */ #include "z_obj_grass_unit.h" diff --git a/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.h b/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.h index 22a38fef1..5c6f1a64a 100644 --- a/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.h +++ b/src/overlays/actors/ovl_Obj_Hakaisi/z_obj_hakaisi.h @@ -11,7 +11,9 @@ typedef struct ObjHakaisi { /* 0x0000 */ Actor actor; /* 0x0144 */ char unk_144[0x18]; /* 0x015C */ ObjHakaisiActionFunc actionFunc; - /* 0x0160 */ char unk_160[0x40]; + /* 0x0160 */ char unk_160[0x38]; + /* 0x0198 */ s16 unk_198; + /* 0x019A */ char unk_19A[0x6]; } ObjHakaisi; // size = 0x1A0 extern const ActorInit Obj_Hakaisi_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c b/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c index 069eb3a66..9784e212c 100644 --- a/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c +++ b/src/overlays/actors/ovl_Obj_Hamishi/z_obj_hamishi.c @@ -1,7 +1,7 @@ /* * File: z_obj_hamishi.c * Overlay: ovl_Obj_Hamishi - * Description: Hammer Stone + * Description: Bronze boulder */ #include "z_obj_hamishi.h" diff --git a/src/overlays/actors/ovl_Obj_Hariko/z_obj_hariko.h b/src/overlays/actors/ovl_Obj_Hariko/z_obj_hariko.h index f77913d88..d9ac284bd 100644 --- a/src/overlays/actors/ovl_Obj_Hariko/z_obj_hariko.h +++ b/src/overlays/actors/ovl_Obj_Hariko/z_obj_hariko.h @@ -10,7 +10,7 @@ typedef void (*ObjHarikoActionFunc)(struct ObjHariko*, GlobalContext*); typedef struct ObjHariko { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjHarikoActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x10]; + /* 0x0148 */ char unk_148[0x10]; } ObjHariko; // size = 0x158 extern const ActorInit Obj_Hariko_InitVars; diff --git a/src/overlays/actors/ovl_Obj_HsStump/z_obj_hsstump.c b/src/overlays/actors/ovl_Obj_HsStump/z_obj_hsstump.c index cca1b9922..d7001bed0 100644 --- a/src/overlays/actors/ovl_Obj_HsStump/z_obj_hsstump.c +++ b/src/overlays/actors/ovl_Obj_HsStump/z_obj_hsstump.c @@ -116,7 +116,7 @@ void ObjHsStump_Appear(ObjHsStump* this, GlobalContext* globalCtx) { offsetAngle = i * angleBinary; Lib_Vec3f_TranslateAndRotateY(&this->dyna.actor.world.pos, offsetAngle, &iceSmokePosOffset, &iceSmokePos); - Lib_Vec3f_TranslateAndRotateY(&D_801D15B0, offsetAngle, &iceSmokeVelOffset, &iceSmokeVel); + Lib_Vec3f_TranslateAndRotateY(&gZeroVec3f, offsetAngle, &iceSmokeVelOffset, &iceSmokeVel); EffectSsIceSmoke_Spawn(globalCtx, &iceSmokePos, &iceSmokeVel, &iceSmokeAccel, 100); } } diff --git a/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.c b/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.c index 31bde1d51..532de8b3b 100644 --- a/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.c +++ b/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.c @@ -1,10 +1,11 @@ /* * File: z_obj_hugebombiwa.c * Overlay: ovl_Obj_Hugebombiwa - * Description: Boulder Blocking Goron Racetrack + * Description: Boulder Blocking Goron Racetrack/Milk Road */ #include "z_obj_hugebombiwa.h" +#include "objects/object_bombiwa/object_bombiwa.h" #define FLAGS 0x00000010 @@ -15,7 +16,16 @@ void ObjHugebombiwa_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjHugebombiwa_Update(Actor* thisx, GlobalContext* globalCtx); void ObjHugebombiwa_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80A54BF0(ObjHugebombiwa* this); +void func_80A54C04(ObjHugebombiwa* this, GlobalContext* globalCtx); +void func_80A54CD8(ObjHugebombiwa* this); +void func_80A54CEC(ObjHugebombiwa* this, GlobalContext* globalCtx); +void func_80A54E10(ObjHugebombiwa* this); +void func_80A55064(ObjHugebombiwa* this, GlobalContext* globalCtx); +void func_80A55310(ObjHugebombiwa* this); +void func_80A55564(ObjHugebombiwa* this, GlobalContext* globalCtx); +void func_80A55B34(Actor* thisx, GlobalContext* globalCtx); + const ActorInit Obj_Hugebombiwa_InitVars = { ACTOR_OBJ_HUGEBOMBIWA, ACTORCAT_PROP, @@ -28,64 +38,683 @@ const ActorInit Obj_Hugebombiwa_InitVars = { (ActorFunc)ObjHugebombiwa_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A55D00 = { - { COLTYPE_HARD, AT_NONE, AC_ON | AC_HARD | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x81C37BB6, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_HARD, + AT_NONE, + AC_ON | AC_HARD | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x81C37BB6, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 180, 226, 0, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80A55D7C[] = { +static Vec3f D_80A55D2C = { 0.0f, 0.3f, 0.0f }; + +void func_80A53BE0(GlobalContext* globalCtx, Vec3f* arg1) { + Vec3f spBC; + Vec3f spB0; + s32 i; + s32 gravity; + s16 phi_v0; + s16 life; + s16 phi_v1; + + for (i = 0, gravity = -300; i < 16; i++, gravity -= 30) { + spBC.x = (Rand_ZeroOne() - 0.5f) * 260.0f; + spBC.y = i * (40.0f / 3); + spBC.z = (Rand_ZeroOne() - 0.5f) * 260.0f; + + spB0.x = ((Rand_ZeroOne() - 0.5f) * 5.7f) + (spBC.x * 0.035f); + spB0.y = (Rand_ZeroOne() * 16.0f) + 5.0f + ((16 - i) * 0.25f); + spB0.z = ((Rand_ZeroOne() - 0.5f) * 5.7f) + (spBC.z * 0.035f); + + spBC.x += arg1->x; + spBC.y += arg1->y; + spBC.z += arg1->z; + + if (i >= 14) { + phi_v0 = 37; + life = 70; + } else { + phi_v0 = 65; + if (i >= 12) { + life = 70; + } else { + life = 40; + if (Rand_ZeroOne() < 0.7f) { + phi_v0 = 64; + } else { + phi_v0 = 32; + } + } + } + + phi_v1 = i; + if (phi_v1 <= 0) { + phi_v1 = 1; + if (1) {} + } + + EffectSsKakera_Spawn(globalCtx, &spBC, &spB0, &spBC, gravity, phi_v0, 15, 0, 0, phi_v1, 1, 0, life, -1, + OBJECT_BOMBIWA, object_bombiwa_DL_001990); + } +} + +void func_80A53E60(GlobalContext* globalCtx, Vec3f* arg1, f32 arg2, f32 arg3) { + static Color_RGBA8 D_80A55D38 = { 210, 210, 210, 255 }; + static Color_RGBA8 D_80A55D3C = { 140, 140, 140, 255 }; + static f32 D_80A55D40[] = { 3.0f, 5.0f, 9.0f, 18.0f }; + Vec3f spDC; + Vec3f spD0; + s32 i; + f32 temp_f0; + s32 phi_s1; + s32 phi_s2; + s32 phi_v0; + s32 phi_v1; + s16 phi_s0; + s32 pad; + + for (phi_s2 = -300, i = 0; phi_s2 > -540; phi_s2 -= 60, i++) { + spDC.x = (Rand_ZeroOne() - 0.5f) * 11.0f; + spDC.y = (Rand_ZeroOne() - 0.2f) * 8.0f; + spDC.z = (Rand_ZeroOne() - 0.5f) * 11.0f; + + spD0.x = ((Rand_ZeroOne() - 0.5f) * 5.0f) + (spDC.x * 1.4f); + spD0.y = (Rand_ZeroOne() * 13.0f) + 8.2f + (arg2 * -0.26f); + if (1) {} + spD0.z = ((Rand_ZeroOne() - 0.5f) * 5.0f) + (spDC.z * 1.4f); + + spDC.x += arg1->x; + spDC.y += arg1->y; + spDC.z += arg1->z; + + if ((s32)(phi_s2 & 0xFFFFFFFF) == -480) { + phi_v0 = 33; + phi_s0 = 70; + } else { + phi_v0 = 65; + if (phi_s2 == -420) { + phi_s0 = 70; + } else { + phi_s0 = 40; + if (Rand_ZeroOne() < 0.7f) { + phi_v0 = 64; + } else { + phi_v0 = 32; + } + } + } + + temp_f0 = D_80A55D40[i] * arg3; + if (temp_f0 <= 1.0f) { + phi_v1 = 1; + } else { + phi_v1 = temp_f0; + } + + EffectSsKakera_Spawn(globalCtx, &spDC, &spD0, &spDC, phi_s2, phi_v0, 15, 0, 0, phi_v1, 1, 0, phi_s0, -1, + OBJECT_BOMBIWA, object_bombiwa_DL_001990); + + spDC.x += (Rand_ZeroOne() - 0.5f) * 270.0f; + spDC.y += (Rand_ZeroOne() - 0.1f) * 150.0f; + spDC.z += (Rand_ZeroOne() - 0.5f) * 270.0f; + + phi_s0 = (Rand_ZeroOne() * 160.0f) + 140.0f; + phi_s1 = (Rand_ZeroOne() * 180.0f) + 120.0f; + func_800B0E48(globalCtx, &spDC, &gZeroVec3f, &D_80A55D2C, &D_80A55D38, &D_80A55D3C, phi_s0, phi_s1); + } +} + +void func_80A541F4(ObjHugebombiwa* this, GlobalContext* globalCtx) { + static s16 D_80A55D50[] = { 24, 17, 13, 7, 6, 5, 3, 2 }; + s32 i; + s32 pad[2]; + s32 phi_s2; + Vec3f spF4; + Vec3f spE8; + Vec3f spDC; + Vec3f spD0; + Vec3f spC4; + f32 temp_f0; + f32 temp_f20; + f32 temp_f22; + f32 temp_f24; + s32 phi_s0; + f32 phi_f30; + + for (i = 0, phi_s2 = 0, phi_f30 = 0.0f; i < 13; i++, phi_s2 += 0x4E20, phi_f30 += (230.0f / 13)) { + temp_f0 = Rand_ZeroOne(); + temp_f22 = (1.0f - SQ(temp_f0)) * 120.0f; + temp_f20 = Math_SinS(phi_s2 & 0xFFFF); + temp_f24 = Math_CosS(phi_s2 & 0xFFFF); + + spF4.x = (temp_f20 * temp_f22) + this->actor.world.pos.x; + spF4.y = this->actor.world.pos.y + phi_f30; + spF4.z = (temp_f24 * temp_f22) + this->actor.world.pos.z; + + spE8.x = temp_f20 * 10.0f; + spE8.y = (Rand_ZeroOne() * 18.0f) + 10.0f; + spE8.z = temp_f24 * 10.0f; + + EffectSsKakera_Spawn(globalCtx, &spF4, &spE8, &spF4, -650, 37, 15, 0, 0, D_80A55D50[i & 7], 1, 0, 60, -1, + OBJECT_BOMBIWA, object_bombiwa_DL_0009E0); + + spDC.x = ((Rand_ZeroOne() - 0.5f) * 230.0f) + spF4.x; + spDC.y = ((Rand_ZeroOne() - 0.2f) * 200.0f) + spF4.y; + spDC.z = ((Rand_ZeroOne() - 0.5f) * 230.0f) + spF4.z; + + spD0.x = temp_f20 * 7.0f; + spD0.y = -7.0f; + spD0.z = temp_f24 * 7.0f; + + spC4.x = temp_f20 * -0.07f; + spC4.y = 0.24f; + spC4.z = temp_f24 * -0.07f; + + func_800B12F0(globalCtx, &spDC, &spD0, &spC4, (s32)(Rand_ZeroOne() * 800.0f) + 1000, -49, 20); + + spDC.x = ((Rand_ZeroOne() - 0.5f) * 160.0f) + spF4.x; + spDC.y = ((Rand_ZeroOne() - 0.2f) * 140.0f) + spF4.y; + spDC.z = ((Rand_ZeroOne() - 0.5f) * 160.0f) + spF4.z; + + spD0.x = temp_f20 * 15.0f; + spD0.y = 0.0f; + spD0.z = temp_f24 * 15.0f; + + spC4.x = temp_f20 * -0.09f; + spC4.y = 0.3f; + spC4.z = temp_f24 * -0.09f; + + func_800B12F0(globalCtx, &spDC, &spD0, &spC4, (s32)(Rand_ZeroOne() * 100.0f) + 40, + (s32)(Rand_ZeroOne() * 200.0f) + 20, 10); + } +} + +void func_80A54600(GlobalContext* globalCtx, Vec3f* arg1, f32 arg2, f32 arg3) { + static f32 D_80A55D60[] = { 3.0f, 5.0f, 9.0f, 18.0f }; + static s8 D_80A55D70 = 0; + Vec3f spCC; + Vec3f spC0; + s32 i; + f32 spA0; + s16 temp_s0; + s16 temp_s1; + s32 phi_v0; + s16 phi_v1; + f32 temp; + + for (i = 0; i < 2; i++) { + spCC.x = (Rand_ZeroOne() - 0.5f) * 11.0f; + spCC.y = (Rand_ZeroOne() - 0.2f) * 8.0f; + spCC.z = (Rand_ZeroOne() - 0.5f) * 11.0f; + + spC0.x = ((Rand_ZeroOne() - 0.5f) * 5.0f) + (spCC.x * 1.4f); + spC0.y = (Rand_ZeroOne() * 13.0f) + 8.2f + (arg2 * -0.38f); + spC0.z = ((Rand_ZeroOne() - 0.5f) * 5.0f) + (spCC.z * 1.4f); + + spCC.x += arg1->x; + spCC.y += arg1->y; + spCC.z += arg1->z; + + temp = D_80A55D60[D_80A55D70] * arg3; + phi_v1 = (D_80A55D70 * -90) - 350; + D_80A55D70++; + D_80A55D70 &= 3; + + if (temp <= 1.0f) { + phi_v0 = 1; + } else { + phi_v0 = temp; + } + + EffectSsKakera_Spawn(globalCtx, &spCC, &spC0, &spCC, phi_v1, 33, 15, 0, 0, phi_v0, 1, 0, 70, -1, OBJECT_BOMBIWA, + object_bombiwa_DL_0009E0); + + spCC.x += (Rand_ZeroOne() - 0.5f) * 270.0f; + spCC.y += (Rand_ZeroOne() - 0.1f) * 150.0f; + spCC.z += (Rand_ZeroOne() - 0.5f) * 270.0f; + + temp_s0 = (Rand_ZeroOne() * 160.0f) + 140.0f; + temp_s1 = (Rand_ZeroOne() * 180.0f) + 120.0f; + func_800B1210(globalCtx, &spCC, &gZeroVec3f, &D_80A55D2C, temp_s0, temp_s1); + } +} + +void func_80A54980(ObjHugebombiwa* this, GlobalContext* globalCtx, s32 arg2) { + s32 pad[2]; + s16 quake = Quake_Add(GET_ACTIVE_CAM(globalCtx), 3); + + Quake_SetSpeed(quake, 0x4E20); + Quake_SetQuakeValues(quake, arg2, 0, 0, 0); + Quake_SetCountdown(quake, 7); + func_8013ECE0(this->actor.xyzDistToPlayerSq, 255, 20, 150); +} + +s32 func_80A54A0C(ObjHugebombiwa* this) { + static f32 D_80A55D74[] = { 62500.0f, 108900.0f }; + s32 sp2C; + Actor* ac; + s32 params; + Vec3f sp20; + + if ((this->collider.base.acFlags & AC_HIT) && (this->collider.info.acHitInfo->toucher.dmgFlags & 0x80000000)) { + ac = this->collider.base.ac; + params = ENHUGEBOMBIWA_GET_100(&this->actor); + + sp20.x = this->actor.world.pos.x; + sp20.y = this->actor.world.pos.y + 50.0f; + sp20.z = this->actor.world.pos.z; + if (ac != NULL) { + if (Math3D_Vec3fDistSq(&sp20, &ac->world.pos) < D_80A55D74[params]) { + return true; + } + } + } + return false; +} + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 3700, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 900, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 900, ICHAIN_STOP), }; -#endif +void ObjHugebombiwa_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjHugebombiwa* this = THIS; -extern ColliderCylinderInit D_80A55D00; -extern InitChainEntry D_80A55D7C[]; + Actor_ProcessInitChain(&this->actor, sInitChain); + Collider_InitCylinder(globalCtx, &this->collider); -extern UNK_TYPE D_060009E0; -extern UNK_TYPE D_06001820; -extern UNK_TYPE D_06001990; -extern UNK_TYPE D_06002F60; + if (Flags_GetSwitch(globalCtx, ENHUGEBOMBIWA_GET_7F(&this->actor))) { + Actor_MarkForDeath(&this->actor); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A53BE0.s") + Collider_SetCylinder(globalCtx, &this->collider, &this->actor, &sCylinderInit); + Collider_UpdateCylinder(&this->actor, &this->collider); + this->actor.colChkInfo.mass = MASS_IMMOVABLE; + if ((ENHUGEBOMBIWA_GET_100(&this->actor)) == 1) { + this->actor.draw = func_80A55B34; + Actor_SetScale(&this->actor, 0.74f); + this->collider.dim.radius = 204; + this->collider.dim.height = 230; + } else { + Actor_SetScale(&this->actor, 0.067f); + this->collider.dim.radius = 120; + this->collider.dim.height = 151; + } + func_80A54BF0(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A53E60.s") +void ObjHugebombiwa_Destroy(Actor* thisx, GlobalContext* globalCtx) { + Collider_DestroyCylinder(globalCtx, &THIS->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A541F4.s") +void func_80A54BF0(ObjHugebombiwa* this) { + this->actionFunc = func_80A54C04; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54600.s") +void func_80A54C04(ObjHugebombiwa* this, GlobalContext* globalCtx) { + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54980.s") + if (this->collider.base.acFlags & AC_HIT) { + this->unk_4B3 = 5; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54A0C.s") + if (func_80A54A0C(this)) { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + func_80A54CD8(this); + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/ObjHugebombiwa_Init.s") + this->collider.base.acFlags &= ~AC_HIT; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/ObjHugebombiwa_Destroy.s") + if (this->unk_4B3 > 0) { + this->unk_4B3--; + if (this->unk_4B3 == 0) { + this->collider.base.colType = COLTYPE_HARD; + } else { + this->collider.base.colType = COLTYPE_NONE; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54BF0.s") + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54C04.s") +void func_80A54CD8(ObjHugebombiwa* this) { + this->actionFunc = func_80A54CEC; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54CD8.s") +void func_80A54CEC(ObjHugebombiwa* this, GlobalContext* globalCtx) { + s32 pad; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54CEC.s") + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + Actor_SetSwitchFlag(globalCtx, ENHUGEBOMBIWA_GET_7F(&this->actor)); + if (!(ENHUGEBOMBIWA_GET_100(&this->actor)) && + ((globalCtx->sceneNum == SCENE_17SETUGEN) || (globalCtx->sceneNum == SCENE_17SETUGEN2))) { + gSaveContext.weekEventReg[19] |= 2; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A54E10.s") + if (!(ENHUGEBOMBIWA_GET_100(&this->actor))) { + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 80, NA_SE_EV_WALL_BROKEN); + } else { + Audio_PlaySoundAtPosition(globalCtx, &this->actor.world.pos, 80, NA_SE_EV_SNOWBALL_BROKEN); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A55064.s") + if (!(ENHUGEBOMBIWA_GET_100(&this->actor))) { + func_80A53BE0(globalCtx, &this->actor.world.pos); + func_80A54E10(this); + } else { + func_80A541F4(this, globalCtx); + func_80A55310(this); + } + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A55310.s") +void func_80A54E10(ObjHugebombiwa* this) { + s32 i; + EnHugebombiwaStruct* ptr; + f32 temp_f20; + f32 temp_f20_2; + s16 phi_s2; + s32 pad; + Vec3f sp84; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A55564.s") + Matrix_StatePush(); + Matrix_RotateY(this->actor.shape.rot.y, 0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/ObjHugebombiwa_Update.s") + for (i = 0, phi_s2 = 0x1000; i < 20; i++, phi_s2 += 0x4000) { + ptr = &this->unk_190[i]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/ObjHugebombiwa_Draw.s") + temp_f20 = (Rand_ZeroOne() * 0.06f) + 0.013f; + ptr->unk_00.x = ((Rand_ZeroOne() * 0.6f) + 0.6f) * temp_f20; + ptr->unk_00.y = ((Rand_ZeroOne() * 0.6f) + 0.4f) * temp_f20; + ptr->unk_00.z = ((Rand_ZeroOne() * 0.6f) + 0.6f) * temp_f20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Hugebombiwa/func_80A55B34.s") + temp_f20_2 = (Rand_ZeroOne() * 55.0f) + 47.0f; + sp84.x = Math_SinS(phi_s2) * temp_f20_2; + sp84.y = (i + 1) * 10.0f; + sp84.z = fabsf(Math_CosS(phi_s2)) * temp_f20_2; + + Matrix_MultiplyVector3fByState(&sp84, &ptr->unk_0C); + + ptr->unk_0C.x += this->actor.world.pos.x; + ptr->unk_0C.y += this->actor.world.pos.y; + ptr->unk_0C.z += this->actor.world.pos.z; + + ptr->unk_18 = (i * 1.04f) + 2.4f; + ptr->unk_1C.x = phi_s2; + ptr->unk_1C.y = (u32)Rand_Next() >> 0x10; + ptr->unk_1C.z = 0; + ptr->unk_22 = Rand_ZeroFloat(5000.0f); + ptr->unk_24 = 0; + } + + this->unk_4B0 = 0; + this->unk_4B2 = 100; + Matrix_StatePop(); + this->actionFunc = func_80A55064; +} + +void func_80A55064(ObjHugebombiwa* this, GlobalContext* globalCtx) { + s32 i; + s32 pad; + Vec3f spA4; + s32 pad2; + CollisionPoly* sp9C; + s32 sp98; + f32 temp_f0; + EnHugebombiwaStruct* ptr; + s16 phi_s3 = this->actor.shape.rot.y - 0x4000; + + for (i = 0; i < ARRAY_COUNT(this->unk_190); i++, phi_s3 += 0x666) { + ptr = &this->unk_190[i]; + if (ptr->unk_24 != 0) { + continue; + } + + ptr->unk_18 -= 3.0f; + if (ptr->unk_18 < -30.0f) { + ptr->unk_18 = -30.0f; + } + + ptr->unk_0C.x += Math_SinS(phi_s3) * 4.0f; + ptr->unk_0C.y += ptr->unk_18; + ptr->unk_0C.z += Math_CosS(phi_s3) * 4.0f; + + ptr->unk_1C.x += ptr->unk_22; + + spA4.x = ptr->unk_0C.x; + spA4.y = ptr->unk_0C.y + 60.0f; + spA4.z = ptr->unk_0C.z; + + temp_f0 = BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &sp9C, &sp98, &this->actor, &spA4); + if ((temp_f0 <= BGCHECK_Y_MIN + 10.0f) || ((ptr->unk_0C.y - (350.0f * ptr->unk_00.y)) < temp_f0)) { + this->unk_4B0++; + ptr->unk_24 = 1; + func_80A53E60(globalCtx, &ptr->unk_0C, ptr->unk_18, ptr->unk_00.y * 9.8f); + if ((globalCtx->gameplayFrames % 4) == 0) { + func_80A54980(this, globalCtx, (s32)(Rand_ZeroOne() * 5.5f) + 1); + } + } + } + + this->unk_4B2--; + if ((this->unk_4B0 >= 20) || (this->unk_4B2 <= 0)) { + ActorCutscene_Stop(this->actor.cutscene); + Actor_MarkForDeath(&this->actor); + } +} + +void func_80A55310(ObjHugebombiwa* this) { + s32 i; + EnHugebombiwaStruct* ptr; + s32 pad; + f32 temp_f20; + f32 temp_f20_2; + s16 phi_s2; + Vec3f sp84; + + Matrix_StatePush(); + Matrix_RotateY(this->actor.shape.rot.y, 0); + + for (i = 0, phi_s2 = 0x1000; i < ARRAY_COUNT(this->unk_190); i++, phi_s2 += 0x4000) { + ptr = &this->unk_190[i]; + + temp_f20 = (Rand_ZeroOne() * 0.09f) + 0.016f; + ptr->unk_00.x = ((Rand_ZeroOne() * 0.1f) + 0.95f) * temp_f20; + ptr->unk_00.y = ((Rand_ZeroOne() * 0.1f) + 0.95f) * temp_f20; + ptr->unk_00.z = ((Rand_ZeroOne() * 0.1f) + 0.95f) * temp_f20; + + temp_f20_2 = (Rand_ZeroOne() * 85.0f) + 77.0f; + sp84.x = Math_SinS(phi_s2) * temp_f20_2; + sp84.y = (i + 1) * 14.0f; + sp84.z = fabsf(Math_CosS(phi_s2)) * temp_f20_2; + Matrix_MultiplyVector3fByState(&sp84, &ptr->unk_0C); + + ptr->unk_0C.x += this->actor.world.pos.x; + ptr->unk_0C.y += this->actor.world.pos.y; + ptr->unk_0C.z += this->actor.world.pos.z; + + ptr->unk_18 = (i * 1.04f) + 2.4f; + + ptr->unk_1C.x = phi_s2; + ptr->unk_1C.y = (u32)Rand_Next() >> 0x10; + ptr->unk_1C.z = 0; + + ptr->unk_22 = Rand_ZeroFloat(5000.0f); + ptr->unk_24 = 0; + } + + this->unk_4B0 = 0; + this->unk_4B2 = 100; + Matrix_StatePop(); + this->actionFunc = func_80A55564; +} + +void func_80A55564(ObjHugebombiwa* this, GlobalContext* globalCtx) { + s32 i; + EnHugebombiwaStruct* ptr; + Vec3f spA4; + s32 pad; + CollisionPoly* sp9C; + s32 sp98; + f32 temp_f0; + s16 phi_s3 = this->actor.shape.rot.y - 0x4000; + + for (i = 0; i < ARRAY_COUNT(this->unk_190); i++, phi_s3 += 0x666) { + ptr = &this->unk_190[i]; + + if (ptr->unk_24 != 0) { + continue; + } + + ptr->unk_18 -= 3.0f; + if (ptr->unk_18 < -30.0f) { + ptr->unk_18 = -30.0f; + } + + ptr->unk_0C.x += (Math_SinS(phi_s3) * 4.0f); + ptr->unk_0C.y += ptr->unk_18; + ptr->unk_0C.z += (Math_CosS(phi_s3) * 4.0f); + + ptr->unk_1C.x += ptr->unk_22; + + spA4.x = ptr->unk_0C.x; + spA4.y = ptr->unk_0C.y + 60.0f; + spA4.z = ptr->unk_0C.z; + + temp_f0 = BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &sp9C, &sp98, &this->actor, &spA4); + if ((temp_f0 <= BGCHECK_Y_MIN + 10.0f) || (ptr->unk_0C.y < temp_f0)) { + this->unk_4B0++; + ptr->unk_24 = 1; + func_80A54600(globalCtx, &ptr->unk_0C, ptr->unk_18, ptr->unk_00.y * 10.1f); + if ((globalCtx->gameplayFrames % 4) == 0) { + func_80A54980(this, globalCtx, (s32)(Rand_ZeroOne() * 5.5f) + 1); + } + } + } + + this->unk_4B2--; + if ((this->unk_4B0 >= 20) || (this->unk_4B2 <= 0)) { + ActorCutscene_Stop(this->actor.cutscene); + Actor_MarkForDeath(&this->actor); + } +} + +void ObjHugebombiwa_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjHugebombiwa* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void ObjHugebombiwa_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjHugebombiwa* this = THIS; + s32 pad[8]; + f32 sp38; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if ((this->actionFunc == func_80A54C04) || (this->actionFunc == func_80A54CEC)) { + if (this->actor.projectedPos.z <= 4300.0f) { + func_8012C28C(globalCtx->state.gfxCtx); + + gSPSegment(POLY_OPA_DISP++, 0x08, D_801AEFA0); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_OPA_DISP++, 0, 0xFF, 255, 255, 255, 255); + gSPDisplayList(POLY_OPA_DISP++, object_bombiwa_DL_002F60); + + func_8012C2DC(globalCtx->state.gfxCtx); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_bombiwa_DL_003110); + + } else if (this->actor.projectedPos.z < 4500.0f) { + sp38 = (4500.0f - this->actor.projectedPos.z) * 1.275f; + func_8012C2DC(globalCtx->state.gfxCtx); + + gSPSegment(POLY_XLU_DISP++, 0x08, D_801AEF88); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0xFF, 255, 255, 255, (s32)sp38); + gSPDisplayList(POLY_XLU_DISP++, object_bombiwa_DL_002F60); + } + } else { + s32 i; + EnHugebombiwaStruct* ptr; + Gfx* gfx = POLY_OPA_DISP; + + gSPDisplayList(gfx++, &sSetupDL[6 * 25]); + + for (i = 0; i < ARRAY_COUNT(this->unk_190); i++) { + ptr = &this->unk_190[i]; + + if (ptr->unk_24 == 0) { + Matrix_SetStateRotationAndTranslation(ptr->unk_0C.x, ptr->unk_0C.y, ptr->unk_0C.z, &ptr->unk_1C); + Matrix_Scale(ptr->unk_00.x, ptr->unk_00.x, ptr->unk_00.x, MTXMODE_APPLY); + + gSPMatrix(gfx++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(gfx++, object_bombiwa_DL_001990); + } + } + + POLY_OPA_DISP = gfx; + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_80A55B34(Actor* thisx, GlobalContext* globalCtx) { + ObjHugebombiwa* this = THIS; + s32 i; + Gfx* gfx; + EnHugebombiwaStruct* ptr; + + if ((this->actionFunc == func_80A54C04) || (this->actionFunc == func_80A54CEC)) { + func_800BDFC0(globalCtx, object_bombiwa_DL_001820); + return; + } + + OPEN_DISPS(globalCtx->state.gfxCtx); + gfx = POLY_OPA_DISP; + + gSPDisplayList(gfx++, &sSetupDL[6 * 25]); + + for (i = 0; i < ARRAY_COUNT(this->unk_190); i++) { + ptr = &this->unk_190[i]; + + if (ptr->unk_24 != 0) { + continue; + } + + Matrix_SetStateRotationAndTranslation(ptr->unk_0C.x, ptr->unk_0C.y + (325.0f * ptr->unk_00.y), ptr->unk_0C.z, + &ptr->unk_1C); + Matrix_Scale(ptr->unk_00.x, ptr->unk_00.y, ptr->unk_00.z, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, -325.0f, 0.0f, MTXMODE_APPLY); + + gSPMatrix(gfx++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(gfx++, object_bombiwa_DL_0009E0); + } + + POLY_OPA_DISP = gfx; + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.h b/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.h index b85add2ef..f1d26aaf4 100644 --- a/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.h +++ b/src/overlays/actors/ovl_Obj_Hugebombiwa/z_obj_hugebombiwa.h @@ -7,9 +7,25 @@ struct ObjHugebombiwa; typedef void (*ObjHugebombiwaActionFunc)(struct ObjHugebombiwa*, GlobalContext*); +#define ENHUGEBOMBIWA_GET_7F(thisx) ((thisx)->params & 0x7F) +#define ENHUGEBOMBIWA_GET_100(thisx) (((thisx)->params >> 8) & 1) + +typedef struct { + /* 0x00 */ Vec3f unk_00; + /* 0x0C */ Vec3f unk_0C; + /* 0x18 */ f32 unk_18; + /* 0x1C */ Vec3s unk_1C; + /* 0x22 */ s16 unk_22; + /* 0x24 */ s16 unk_24; +} EnHugebombiwaStruct; // size = 0x28 + typedef struct ObjHugebombiwa { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x370]; + /* 0x0144 */ ColliderCylinder collider; + /* 0x0190 */ EnHugebombiwaStruct unk_190[20]; + /* 0x04B0 */ s16 unk_4B0; + /* 0x04B2 */ s8 unk_4B2; + /* 0x04B3 */ s8 unk_4B3; /* 0x04B4 */ ObjHugebombiwaActionFunc actionFunc; } ObjHugebombiwa; // size = 0x4B8 diff --git a/src/overlays/actors/ovl_Obj_Iceblock/z_obj_iceblock.c b/src/overlays/actors/ovl_Obj_Iceblock/z_obj_iceblock.c index bbeb4da26..f623ca4f8 100644 --- a/src/overlays/actors/ovl_Obj_Iceblock/z_obj_iceblock.c +++ b/src/overlays/actors/ovl_Obj_Iceblock/z_obj_iceblock.c @@ -5,6 +5,7 @@ */ #include "z_obj_iceblock.h" +#include "objects/object_ice_block/object_ice_block.h" #define FLAGS 0x00000010 @@ -15,7 +16,35 @@ void ObjIceblock_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjIceblock_Update(Actor* thisx, GlobalContext* globalCtx); void ObjIceblock_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80A257A0(ObjIceblock* this); +void func_80A257B4(ObjIceblock* this, GlobalContext* globalCtx); +void func_80A25824(ObjIceblock* this); +void func_80A2586C(ObjIceblock* this, GlobalContext* globalCtx); +void func_80A25978(ObjIceblock* this); +void func_80A25994(ObjIceblock* this, GlobalContext* globalCtx); +void func_80A25A8C(ObjIceblock* this); +void func_80A25AA8(ObjIceblock* this, GlobalContext* globalCtx); +void func_80A25BA0(ObjIceblock* this); +void func_80A25BBC(ObjIceblock* this, GlobalContext* globalCtx); +void func_80A25C5C(ObjIceblock* this); +void func_80A25C70(ObjIceblock* this, GlobalContext* globalCtx); +void func_80A25CF4(ObjIceblock* this); +void func_80A25D28(ObjIceblock* this, GlobalContext* globalCtx); +void func_80A25E3C(ObjIceblock* this); +void func_80A25E50(ObjIceblock* this, GlobalContext* globalCtx); +void func_80A25FA0(ObjIceblock* this); +void func_80A25FD4(ObjIceblock* this, GlobalContext* globalCtx); +void func_80A260E8(ObjIceblock* this); +void func_80A26144(ObjIceblock* this, GlobalContext* globalCtx); +void func_80A262BC(ObjIceblock* this); +void func_80A262EC(ObjIceblock* this, GlobalContext* globalCtx); +void func_80A26574(ObjIceblock* this); +void func_80A265C0(ObjIceblock* this, GlobalContext* globalCtx); +void func_80A266E0(ObjIceblock* this, GlobalContext* globalCtx); +void func_80A26B64(ObjIceblock* this, GlobalContext* globalCtx); +void func_80A26B74(ObjIceblock* this, GlobalContext* globalCtx); +void func_80A26BF8(ObjIceblock* this, GlobalContext* globalCtx); + const ActorInit Obj_Iceblock_InitVars = { ACTOR_OBJ_ICEBLOCK, ACTORCAT_BG, @@ -28,158 +57,1501 @@ const ActorInit Obj_Iceblock_InitVars = { (ActorFunc)ObjIceblock_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80A26E50 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_NO_PUSH | OC1_TYPE_PLAYER, OC2_TYPE_2, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x00000800, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_NO_PUSH | OC1_TYPE_PLAYER, + OC2_TYPE_2, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x00000800, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 44, 62, -31, { 0, 0, 0 } }, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80A26FA4[] = { - ICHAIN_F32_DIV1000(speedXZ, 16000, ICHAIN_CONTINUE), - ICHAIN_F32_DIV1000(gravity, -1800, ICHAIN_CONTINUE), - ICHAIN_F32_DIV1000(minVelocityY, -26000, ICHAIN_CONTINUE), - ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), - ICHAIN_F32(uncullZoneScale, 150, ICHAIN_CONTINUE), +static AnimatedMaterial* D_80A26E7C = NULL; + +s16 func_80A23090(s16 arg0, s16 arg1, s16 arg2) { + if (arg0 >= 0) { + if (arg2 < arg0) { + return arg2; + } else if (arg0 < arg1) { + return arg1; + } + } else if (arg0 < -arg2) { + return -arg2; + } else if (-arg1 < arg0) { + return -arg1; + } + + return arg0; +} + +void func_80A2311C(Vec3f* arg0, Vec3f* arg1, s16 arg2) { + f32 sp1C = Math_SinS(arg2); + f32 sp18 = Math_CosS(arg2); + + arg0->x = (arg1->z * sp1C) + (arg1->x * sp18); + arg0->y = arg1->y; + arg0->z = (arg1->z * sp18) - (arg1->x * sp1C); +} + +void func_80A2319C(ObjIceblock* this, f32 arg1) { + s32 i; + s16 temp_s1 = (u32)Rand_Next() >> 0x10; + s16 temp_s2 = (u32)Rand_Next() >> 0x10; + ObjIceBlockUnkStruct* ptr; + + for (i = 0; i < ARRAY_COUNT(this->unk_1B4); i++) { + ptr = &this->unk_1B4[i]; + temp_s1 += Rand_S16Offset(2700, 10000); + temp_s2 += Rand_S16Offset(2700, 10000); + ptr->unk_00 = temp_s1; + ptr->unk_02 = temp_s2; + ptr->unk_04 = ((Rand_ZeroOne() * 0.2f) + 0.9f) * arg1; + ptr->unk_08 = ((Rand_ZeroOne() * 0.2f) + 0.9f) * arg1; + ptr->unk_0C = ((Rand_ZeroOne() * 0.2f) + 0.9f) * arg1; + } +} + +void func_80A232C4(ObjIceblock* this, s32 arg1) { + static s16 D_80A26E80[] = { 1, -1, 0, 0 }; + static s16 D_80A26E88[] = { 0, 0, 1, -1 }; + + this->unk_276 += D_80A26E80[arg1]; + this->unk_278 += D_80A26E88[arg1]; + + if ((arg1 == 0) || (arg1 == 1)) { + this->unk_264 = &this->dyna.actor.world.pos.x; + this->unk_268 = this->dyna.actor.home.pos.x + (this->unk_276 * 60); + } else { + this->unk_264 = &this->dyna.actor.world.pos.z; + this->unk_268 = this->dyna.actor.home.pos.z + (this->unk_278 * 60); + } + this->unk_26C = arg1; +} + +void func_80A23370(ObjIceblock* this, s32 arg1) { + if ((arg1 == 0) || (arg1 == 1)) { + this->unk_264 = &this->dyna.actor.world.pos.x; + } else { + this->unk_264 = &this->dyna.actor.world.pos.z; + } + this->unk_26C = arg1; +} + +void func_80A2339C(GlobalContext* globalCtx, Vec3f* arg1, f32 arg2, f32 arg3, s32 arg4) { + Vec3f spBC; + Vec3f spB0; + Vec3f spA4; + f32 temp_f20; + f32 temp_f22; + f32 temp_f24; + s32 i; + f32 sp88; + s16 temp_s4; + s16 phi_s0; + s16 temp; + + spA4.z = 0.0f; + spA4.x = 0.0f; + temp_f24 = ((Rand_ZeroOne() * 0.1656f) + 0.3312f) * arg3; + sp88 = 10.0f * arg3; + + for (i = 0, phi_s0 = 0; i < arg4; i++, phi_s0 += temp) { + temp = 0x10000 / arg4; + + temp_f20 = ((Rand_ZeroOne() * 0.4f) + 0.6f) * (arg2 * 3.5f); + temp_s4 = temp_f20 * 100.0f; + temp_f22 = ((Rand_ZeroOne() * 0.7f) + 0.3f) * arg2 * 300.0f; + + spBC.x = Math_SinS(Rand_S16Offset(phi_s0, temp)) * temp_f22; + spBC.y = (Rand_ZeroOne() - 0.5f) * (600.0f * arg2); + spBC.z = Math_CosS(Rand_S16Offset(phi_s0, temp)) * temp_f22; + + spB0.x = spBC.x * temp_f24; + spB0.y = ((Rand_ZeroOne() * 1.2f) + 0.3f + (temp_f20 * 4.0f)) * sp88; + spB0.z = spBC.z * temp_f24; + + spBC.x += arg1->x; + spBC.y += arg1->y; + spBC.z += arg1->z; + + spA4.y = -0.8f - (temp_f20 * 18.0f); + + EffectSsIceBlock_Spawn(globalCtx, &spBC, &spB0, &spA4, temp_s4); + } +} + +void func_80A23690(ObjIceblock* this) { + this->dyna.actor.velocity.y += this->dyna.actor.gravity; + if (this->dyna.actor.velocity.y < this->dyna.actor.minVelocityY) { + this->dyna.actor.velocity.y = this->dyna.actor.minVelocityY; + } + this->dyna.actor.world.pos.y += this->dyna.actor.velocity.y; +} + +s32 func_80A236D4(ObjIceblock* this, Vec3f* arg1) { + f32 sp2C; + f32 sp28; + s16 sp26; + s32 sp20; + + sp26 = Math_Vec3f_Yaw(&this->dyna.actor.world.pos, arg1); + sp2C = Math_SinS(sp26) * this->dyna.actor.speedXZ; + sp2C = fabsf(sp2C) + 0.01f; + + sp28 = Math_CosS(sp26) * this->dyna.actor.speedXZ; + sp28 = fabsf(sp28) + 0.01f; + + sp20 = Math_StepToF(&this->dyna.actor.world.pos.x, arg1->x, sp2C); + sp20 &= 1; + sp20 &= Math_StepToF(&this->dyna.actor.world.pos.z, arg1->z, sp28); + return sp20; +} + +void func_80A237A4(ObjIceblock* this) { + s32 pad[2]; + ObjIceBlockUnkStruct4* ptr = &this->unk_27C; + f32 sp20; + + ptr->unk_10 += ptr->unk_0C; + ptr->unk_12 += ptr->unk_0E; + Math_StepToF(&this->unk_27C.unk_08, this->unk_27C.unk_04, 0.08f); + + if (this->unk_1B0 & 0x20) { + Math_StepToF(&ptr->unk_00, -5.0f, (Math_CosS(fabsf(ptr->unk_00) * 3276.8f) * 0.3f) + 0.02f); + } else { + Math_StepToF(&ptr->unk_00, 0.0f, (Math_SinS(fabsf(ptr->unk_00) * 3276.8f) * 0.3f) + 0.02f); + } + + sp20 = Math_SinS(ptr->unk_10); + this->dyna.actor.world.pos.y = + (Math_SinS(ptr->unk_12) * ptr->unk_08 * 0.5f) + + ((this->unk_244 - ((600.0f * this->dyna.actor.scale.y) - 90.0f)) + (sp20 * ptr->unk_08)) + ptr->unk_00; +} + +void func_80A23938(ObjIceblock* this2) { + ObjIceblock* this = this2; + + if (this->unk_1B0 & 0x80) { + Math_ScaledStepToS(&this->dyna.actor.shape.rot.x, 0, 400); + Math_ScaledStepToS(&this->dyna.actor.shape.rot.z, 0, 400); + } else { + ObjIceBlockUnkStruct4* ptr = &this->unk_27C; + f32 phi_f0; + s16 temp; + + if (this->unk_1B0 & 0x20) { + phi_f0 = 0.3f; + ptr->unk_14 = this->dyna.actor.yawTowardsPlayer; + } else { + phi_f0 = 0.08f; + } + + Math_StepToF(&ptr->unk_1C, phi_f0, 0.04f); + ptr->unk_22 += (s16)(ptr->unk_20 * -0.02f); + ptr->unk_22 = func_80A23090(ptr->unk_22, 50, 800); + ptr->unk_20 += ptr->unk_22; + + temp = ptr->unk_16 - ptr->unk_14; + + ptr->unk_18 += + (s16)(temp * -0.04f * this->dyna.actor.xzDistToPlayer * this->dyna.actor.scale.x * (1.0f / 600.0f)); + ptr->unk_18 = func_80A23090(ptr->unk_18, 50, 800); + ptr->unk_16 += ptr->unk_18; + + this->dyna.actor.shape.rot.x = Math_CosS(ptr->unk_16) * ptr->unk_20 * ptr->unk_1C; + this->dyna.actor.shape.rot.x = CLAMP(this->dyna.actor.shape.rot.x, -2000, 2000); + + this->dyna.actor.shape.rot.z = -Math_SinS(ptr->unk_16) * ptr->unk_20 * ptr->unk_1C; + this->dyna.actor.shape.rot.z = CLAMP(this->dyna.actor.shape.rot.z, -2000, 2000); + } +} + +void func_80A23B88(ObjIceblock* this) { + f32 f4; + f32 f2; + f32 f14; + f32 f16; + f32 f6; + + f14 = this->dyna.actor.world.pos.x - this->dyna.actor.home.pos.x; + f2 = (f14 >= 0.0f) ? (0.5f) : (-0.5f); + f4 = (((s32)(f2 + f14)) / 30) * 30; + f14 -= f4; + if (fabsf(f14) < 3.0f) { + this->dyna.actor.world.pos.x = this->dyna.actor.home.pos.x + f4; + } + + f16 = this->dyna.actor.world.pos.z - this->dyna.actor.home.pos.z; + f2 = (f16 >= 0.0f) ? (0.5f) : (-0.5f); + f6 = (((s32)(f2 + f16)) / 30) * 30; + f16 -= f6; + if (fabsf(f16) < 3.0f) { + this->dyna.actor.world.pos.z = this->dyna.actor.home.pos.z + f6; + } +} + +s32 func_80A23D08(ObjIceblock* this, GlobalContext* globalCtx) { + static ObjIceBlockUnkStruct3 D_80A26E90[] = { + { -300.0f, 300.0f }, { 300.0f, 300.0f }, { -300.0f, -300.0f }, { 300.0f, -300.0f }, { 0.0f, 0.0f }, + }; + static ObjIceBlockUnkStruct3 D_80A26EB8[] = { + { 0.5f, -0.5f }, { -0.5f, -0.5f }, { 0.5f, 0.5f }, { -0.5f, 0.5f }, { 0.0f, 0.0f }, + }; + s32 pad3; + ObjIceBlockUnkStruct2* ptr; + WaterBox* spC4; + s32 i; + s32 spBC; + s32 spB8; + s32 pad; + f32 phi_f20; + Vec3f spA4; + Vec3f sp98; + s32 sp94 = 0; + f32 phi_f22; + + sp98.y = this->dyna.actor.world.pos.y + 40.0f; + spBC = spB8 = -1; + phi_f20 = BGCHECK_Y_MIN; + phi_f22 = BGCHECK_Y_MIN; + + for (i = 0; i < ARRAY_COUNT(this->unk_1F4); i++) { + ptr = &this->unk_1F4[i]; + + ptr->unk_00 = NULL; + ptr->unk_04 = BGCHECK_Y_MIN; + ptr->unk_08 = 50; + + sp98.x = (D_80A26E90[i].unk_00 * this->dyna.actor.scale.x) + D_80A26EB8[i].unk_00; + sp98.z = (D_80A26E90[i].unk_04 * this->dyna.actor.scale.z) + D_80A26EB8[i].unk_04; + + func_80A2311C(&spA4, &sp98, this->dyna.actor.shape.rot.y); + spA4.x += this->dyna.actor.world.pos.x; + spA4.z += this->dyna.actor.world.pos.z; + + ptr->unk_04 = + BgCheck_EntityRaycastFloor6(&globalCtx->colCtx, &ptr->unk_00, &ptr->unk_08, &this->dyna.actor, &spA4, 0.0f); + if (ptr->unk_04 > BGCHECK_Y_MIN + 1) { + sp94 = 1; + if (phi_f22 < ptr->unk_04) { + spBC = i; + phi_f22 = ptr->unk_04; + } + } + + if (WaterBox_GetSurface1_2(globalCtx, &globalCtx->colCtx, spA4.x, spA4.z, &ptr->unk_0C, &spC4)) { + if (phi_f20 < ptr->unk_0C) { + spB8 = i; + phi_f20 = ptr->unk_0C; + } + } else { + ptr->unk_0C = BGCHECK_Y_MIN; + } + } + + if (spBC >= 0) { + this->dyna.actor.floorPoly = this->unk_1F4[spBC].unk_00; + this->dyna.actor.floorHeight = this->unk_1F4[spBC].unk_04; + this->dyna.actor.floorBgId = this->unk_1F4[spBC].unk_08; + } else { + this->dyna.actor.floorPoly = NULL; + this->dyna.actor.floorHeight = BGCHECK_Y_MIN; + this->dyna.actor.floorBgId = BGCHECK_SCENE; + } + + if (spB8 >= 0) { + this->unk_244 = this->unk_1F4[spB8].unk_0C; + } else { + this->unk_244 = BGCHECK_Y_MIN; + } + + return sp94; +} + +s32 func_80A23F90(ObjIceblock* this, GlobalContext* globalCtx) { + this->unk_1B0 &= ~4; + + if (func_80A23D08(this, globalCtx)) { + f32 phi_f2 = BGCHECK_Y_MIN; + s32 ret = false; + s32 i; + ObjIceBlockUnkStruct2* ptr; + + for (i = 0; i < ARRAY_COUNT(this->unk_1F4); i++) { + ptr = &this->unk_1F4[i]; + if (((this->dyna.actor.world.pos.y - 10.0f) < ptr->unk_04) && (phi_f2 < ptr->unk_04)) { + phi_f2 = ptr->unk_04; + ret = true; + } + } + + if (ret) { + this->dyna.actor.world.pos.y = phi_f2; + this->unk_1B0 |= 4; + this->dyna.actor.velocity.y = 0.0f; + } + return ret; + } + return false; +} + +s32 func_80A24118(ObjIceblock* this, GlobalContext* globalCtx, f32 arg2, Vec3f* arg3) { + static ObjIceBlockUnkStruct3 D_80A26EE0[] = { + { -300.0f, -300.0f }, { 300.0f, -300.0f }, { -300.0f, 600.0f }, { 300.0f, 600.0f }, { 0.0f, 0.0f }, + }; + static ObjIceBlockUnkStruct3 D_80A26F08[] = { + { 1.0f, 1.0f }, { -1.0f, 1.0f }, { 1.0f, -1.0f }, { -1.0f, -1.0f }, { 0.0f, 0.0f }, + }; + f32 temp_f20; + f32 spF0; + f32 spEC; + f32 phi_f20; + Vec3f spDC; + Vec3f spD0; + Vec3f spC4; + Vec3f spB8; + s32 pad[2]; + s32 spAC; + CollisionPoly* spA8; + s32 ret; + s32 i; + s16 sp9E; + f32 temp_f24; + f32 temp_f26; + + sp9E = this->dyna.yRotation; + if (this->dyna.pushForce < 0.0f) { + sp9E -= 0x8000; + } + + spF0 = Math_SinS(sp9E); + spEC = Math_CosS(sp9E); + temp_f20 = Math3D_Distance(&this->dyna.actor.world.pos, &this->dyna.actor.prevPos) + + (300.0f * this->dyna.actor.scale.z) + arg2; + temp_f24 = temp_f20 * spF0; + temp_f26 = temp_f20 * spEC; + ret = false; + phi_f20 = FLT_MAX; + + for (i = 0; i < ARRAY_COUNT(D_80A26EE0); i++) { + spC4.x = (D_80A26EE0[i].unk_00 * this->dyna.actor.scale.x) + D_80A26F08[i].unk_00; + spC4.y = (D_80A26EE0[i].unk_04 * this->dyna.actor.scale.y) + D_80A26F08[i].unk_04 + + (this->dyna.actor.shape.yOffset * this->dyna.actor.scale.y); + spC4.z = 0.0f; + + func_80A2311C(&spDC, &spC4, sp9E); + + spDC.x += this->dyna.actor.prevPos.x; + spDC.y += this->dyna.actor.prevPos.y; + spDC.z += this->dyna.actor.prevPos.z; + + spD0.x = temp_f24 + spDC.x; + spD0.y = spDC.y; + spD0.z = temp_f26 + spDC.z; + + if (BgCheck_EntityLineTest3(&globalCtx->colCtx, &spDC, &spD0, &spB8, &spA8, 1, 0, 0, 1, &spAC, + &this->dyna.actor, 0.0f)) { + temp_f20 = Math3D_Vec3fDistSq(&spDC, &spB8); + if (temp_f20 < phi_f20) { + phi_f20 = temp_f20; + ret = true; + Math_Vec3f_Diff(&spB8, &spD0, arg3); + } + } + } + return ret; +} + +s32 func_80A24384(ObjIceblock* this, GlobalContext* globalCtx) { + Vec3f sp1C; + + if (func_80A24118(this, globalCtx, 0.0f, &sp1C)) { + this->dyna.actor.world.pos.x += sp1C.x; + this->dyna.actor.world.pos.z += sp1C.z; + return true; + } + return false; +} + +s32 func_80A243E0(ObjIceblock* this, GlobalContext* globalCtx, Vec3f* arg0) { + static f32 D_80A26F30[] = { -300.0f, 300.0f }; + static f32 D_80A26F38[] = { 1.0f, -1.0f }; + s32 i; + f32 sp100; + f32 spFC; + f32 phi_f22; + Vec3f spEC; + Vec3f spE0; + Vec3f spD4; + Vec3f spC8; + s16 temp_s6; + f32 temp_f28; + s32 spBC; + CollisionPoly* spB8; + s32 ret; + f32 temp_f30; + f32 temp_f0; + f32 temp_f12; + + temp_s6 = this->dyna.yRotation; + if (this->dyna.pushForce < 0.0f) { + temp_s6 -= 0x8000; + } + + sp100 = Math_SinS(temp_s6); + spFC = Math_CosS(temp_s6); + + temp_f0 = ((Math3D_Distance(&this->dyna.actor.world.pos, &this->dyna.actor.prevPos) + + (300.0f * this->dyna.actor.scale.z)) + + 2.0f); + temp_f12 = -temp_f0; + ret = false; + temp_f28 = temp_f12 * sp100; + temp_f30 = temp_f12 * spFC; + phi_f22 = FLT_MAX; + + for (i = 0; i < ARRAY_COUNT(D_80A26F30); i++) { + spD4.x = (D_80A26F30[i] * this->dyna.actor.scale.x) + D_80A26F38[i]; + spD4.y = -10.0f; + spD4.z = 0.0f; + + func_80A2311C(&spEC, &spD4, temp_s6); + + spEC.x += this->dyna.actor.world.pos.x; + spEC.y += this->dyna.actor.world.pos.y; + spEC.z += this->dyna.actor.world.pos.z; + + spE0.x = temp_f28 + spEC.x; + spE0.y = spEC.y; + spE0.z = temp_f30 + spEC.z; + + if (BgCheck_EntityLineTest3(&globalCtx->colCtx, &spEC, &spE0, &spC8, &spB8, 1, 0, 0, 1, &spBC, + &this->dyna.actor, 0.0f)) { + temp_f12 = Math3D_Vec3fDistSq(&spEC, &spC8); + if (temp_f12 < phi_f22) { + phi_f22 = temp_f12; + ret = true; + arg0->x = (spC8.x - spEC.x) + (300.0f * this->dyna.actor.scale.z * sp100); + arg0->y = 0.0f; + arg0->z = (spC8.z - spEC.z) + (300.0f * this->dyna.actor.scale.z * spFC); + } + } + } + return ret; +} + +s32 func_80A24680(ObjIceblock* this, GlobalContext* globalCtx) { + Vec3f sp1C; + + if (func_80A243E0(this, globalCtx, &sp1C)) { + this->dyna.actor.world.pos.x += sp1C.x; + this->dyna.actor.world.pos.z += sp1C.z; + return true; + } + return false; +} + +s32 func_80A246D8(ObjIceblock* this, GlobalContext* globalCtx, Vec3f* arg2) { + static ObjIceBlockUnkStruct3 D_80A26F40[] = { + { -300.0f, -300.0f }, { 300.0f, -300.0f }, { -300.0f, 600.0f }, { 300.0f, 600.0f }, { 0.0f, 0.0f }, + }; + static ObjIceBlockUnkStruct3 D_80A26F68[] = { + { 1.0f, 1.0f }, { -1.0f, 1.0f }, { 1.0f, -1.0f }, { -1.0f, -1.0f }, { 0.0f, 0.0f }, + }; + s32 pad; + s32 i; + s32 j; + Vec3f spC0; + Vec3f spB4; + Vec3f spA8; + Vec3f sp9C; + s32 sp98; + CollisionPoly* sp94; + ObjIceblock* temp_v0; + f32 temp_f20 = (this->dyna.actor.scale.z * 300.0f) + 2.0f; + s16 phi_s3; + s32 ret = false; + + for (i = 0, phi_s3 = 0; i < 4; i++, phi_s3 += 0x4000) { + for (j = 0; j < ARRAY_COUNT(D_80A26F40); j++) { + spA8.x = (D_80A26F40[j].unk_00 * this->dyna.actor.scale.x) + D_80A26F68[j].unk_00; + spA8.y = ((D_80A26F40[j].unk_04 * this->dyna.actor.scale.y) + D_80A26F68[j].unk_04) + + (this->dyna.actor.shape.yOffset * this->dyna.actor.scale.y); + spA8.z = 0.0f; + + func_80A2311C(&spC0, &spA8, phi_s3); + + spC0.x += arg2->x; + spC0.y += arg2->y; + spC0.z += arg2->z; + + spB4.x = (Math_SinS(phi_s3) * temp_f20) + spC0.x; + spB4.y = spC0.y; + spB4.z = (Math_CosS(phi_s3) * temp_f20) + spC0.z; + + if (BgCheck_EntityLineTest3(&globalCtx->colCtx, &spC0, &spB4, &sp9C, &sp94, 1, 0, 0, 1, &sp98, + &this->dyna.actor, 0.0f)) { + ret = true; + temp_v0 = (ObjIceblock*)DynaPoly_GetActor(&globalCtx->colCtx, sp98); + if ((temp_v0 != NULL) && (temp_v0->dyna.actor.id == ACTOR_OBJ_ICEBLOCK) && (temp_v0->unk_2B0 == 3)) { + temp_v0->unk_1B0 |= 0x80; + } + } + } + } + + return ret; +} + +void func_80A2491C(ObjIceblock* this) { + Math_Vec3f_Copy(&this->dyna.actor.home.pos, &this->dyna.actor.world.pos); + this->unk_278 = 0; + this->unk_276 = this->unk_278; +} + +s32 func_80A24954(ObjIceblock* this, GlobalContext* globalCtx) { + s32 pad[2]; + s8 sp27 = this->unk_2B0; + f32 temp = (this->dyna.actor.scale.y * 600.0f) - 90.0f; + + if ((this->unk_244 > BGCHECK_Y_MIN + 1) && (temp < (this->unk_244 - this->dyna.actor.world.pos.y))) { + func_80A262BC(this); + this->unk_2B0 = 3; + } else if (this->unk_1B0 & 4) { + if (func_800C99D4(&globalCtx->colCtx, this->dyna.actor.floorPoly, this->dyna.actor.floorBgId) == 5) { + func_80A25FA0(this); + this->unk_2B0 = 2; + } else { + func_80A25CF4(this); + this->unk_2B0 = 1; + } + } + return sp27 != this->unk_2B0; +} + +void func_80A24A48(ObjIceblock* this, GlobalContext* globalCtx) { + if (!(this->unk_1B0 & 0x10) && !(this->collider.base.ocFlags1 & OC1_HIT)) { + func_800C6314(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + this->unk_1B0 |= 0x10; + } +} + +void func_80A24AA8(ObjIceblock* this, GlobalContext* globalCtx) { + s32 i; + f32 x; + ObjIceblock* temp_v0; + + if (this->unk_1B0 & 4) { + for (i = 0; i < ARRAY_COUNT(this->unk_1F4); i++) { + temp_v0 = (ObjIceblock*)DynaPoly_GetActor(&globalCtx->colCtx, ((void)0, this->unk_1F4[i]).unk_08); + if ((temp_v0 != NULL) && (temp_v0->dyna.actor.id == ACTOR_OBJ_ICEBLOCK)) { + x = this->dyna.actor.world.pos.y - this->unk_1F4[i].unk_04; + + if (fabsf(x) < 0.1f) { + temp_v0->unk_1B0 |= 2; + } + } + } + } +} + +void func_80A24B74(ObjIceblock* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp20; + + if (this->dyna.actor.flags & 0x40) { + if (1) {} + sp20.x = this->dyna.actor.world.pos.x; + sp20.y = this->unk_244; + sp20.z = this->dyna.actor.world.pos.z; + EffectSsGRipple_Spawn(globalCtx, &sp20, 480, 880, 0); + } +} + +void func_80A24BDC(ObjIceblock* this, GlobalContext* globalCtx, f32 arg2, f32 arg3, s32 arg4) { + s32 i; + Vec3f sp88; + f32 temp_f20; + s16 temp_f22; + s16 phi_s0; + s32 phi_s1 = 0; + + if (this->dyna.actor.flags & 0x40) { + sp88.y = this->unk_244; + temp_f22 = 0x10000 / arg4; + + for (i = 0, phi_s0 = 0; i < arg4; i++, phi_s0 += temp_f22) { + temp_f20 = ((Rand_ZeroOne() * 5.0f) + 40.0f) * arg2; + sp88.x = (Math_SinS((s32)(Rand_ZeroOne() * temp_f22) + phi_s0) * temp_f20) + this->dyna.actor.world.pos.x; + sp88.z = (Math_CosS((s32)(Rand_ZeroOne() * temp_f22) + phi_s0) * temp_f20) + this->dyna.actor.world.pos.z; + EffectSsGSplash_Spawn(globalCtx, &sp88, NULL, NULL, 0, ((Rand_ZeroOne() * 60.0f) + 320.0f) * arg3); + } + } +} + +void func_80A24DC4(ObjIceblock* this) { + this->unk_2A2 = 0; +} + +void func_80A24DD0(ObjIceblock* this, GlobalContext* globalCtx) { + static Vec3f D_80A26F90 = { 0.0f, 0.3f, 0.0f }; + static Color_RGBA8 D_80A26F9C = { 250, 250, 250, 255 }; + static Color_RGBA8 D_80A26FA0 = { 180, 180, 180, 255 }; + s32 pad; + Vec3f spA8; + Vec3f sp9C; + s32 i; + f32 temp_f20; + f32 phi_f22; + s32 pad2; + s16 sp8A; + + sp8A = this->dyna.yRotation; + if (this->dyna.pushForce < 0.0f) { + sp8A -= 0x8000; + } + + this->unk_2A2++; + if (this->dyna.actor.flags & 0x40) { + if (this->unk_2A2 >= 0x2E) { + phi_f22 = 1.0f; + } else { + phi_f22 = (this->unk_2A2 * 0.017777778f) + 0.2f; + } + sp9C.y = 12.0f; + + for (i = 0; i < 2; i++) { + if (phi_f22 < (Rand_ZeroOne() * 1.2f)) { + continue; + } + + this->unk_2A4 += Rand_ZeroOne(); + if (this->unk_2A4 > 1.0f) { + this->unk_2A4 -= 1.0f; + } + + sp9C.x = (this->unk_2A4 - 0.5f) * 600.0f * this->dyna.actor.scale.x; + sp9C.z = (this->dyna.actor.scale.z * -300.0f) + 4.0f; + + func_80A2311C(&spA8, &sp9C, sp8A); + + spA8.x += this->dyna.actor.world.pos.x; + spA8.y += this->dyna.actor.world.pos.y; + spA8.z += this->dyna.actor.world.pos.z; + + temp_f20 = ((Rand_ZeroOne() * 800.0f) + (1600.0f * this->dyna.actor.scale.x)) * phi_f22; + func_800B0E48(globalCtx, &spA8, &gZeroVec3f, &D_80A26F90, &D_80A26F9C, &D_80A26FA0, temp_f20, + (Rand_ZeroOne() * 20.0f) + 30.0f); + } + } +} + +void func_80A2508C(ObjIceblock* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp40; + Vec3f sp34; + f32 temp_f0; + s32 temp_v0; + + if (this->dyna.actor.flags & 0x40) { + temp_v0 = (s32)(this->dyna.actor.scale.y * 130.0f) - 3; + if (temp_v0 > 0) { + this->unk_2AC += temp_v0; + } + + if (this->unk_2AC >= 10) { + this->unk_2AC = 0; + sp34.x = (Rand_ZeroOne() * 600.0f) - 300.0f; + sp34.y = 600.0f; + sp34.z = (Rand_ZeroOne() * 600.0f) - 300.0f; + + temp_f0 = sqrtf(this->dyna.actor.scale.y + 0.01f); + sp40.x = sp34.x * 0.006935f * temp_f0; + sp40.y = 2.0f; + sp40.z = sp34.z * 0.006935f * temp_f0; + + sp34.x = (this->dyna.actor.scale.x * sp34.x) + this->dyna.actor.world.pos.x; + sp34.y = (this->dyna.actor.scale.y * sp34.y) + this->dyna.actor.world.pos.y; + sp34.z = (this->dyna.actor.scale.z * sp34.z) + this->dyna.actor.world.pos.z; + + if ((this->unk_244 - 3.0f) < sp34.y) { + EffectSsIceSmoke_Spawn(globalCtx, &sp34, &sp40, &gZeroVec3f, + (s32)(this->dyna.actor.scale.y * 1300.0f) + 60); + } + } + } +} + +s32 func_80A25238(ObjIceblock* this) { + s16 phi_v0; + + if (fabsf(this->dyna.pushForce) > 0.1f) { + if (this->dyna.pushForce > 0.0f) { + phi_v0 = this->dyna.yRotation + 0x2000; + } else { + phi_v0 = this->dyna.yRotation - 0x6000; + } + + if (phi_v0 < -0x4000) { + return 3; + } + + if (phi_v0 < 0) { + return 1; + } + + if (phi_v0 < 0x4000) { + return 2; + } + return 0; + } + return -1; +} + +void func_80A252DC(ObjIceblock* this, s32 arg1) { + s32 phi_v0; + s32 i; + + if (this->unk_2B0 == 1) { + phi_v0 = true; + } else if (this->unk_2B0 == 2) { + phi_v0 = (this->dyna.pushForce > 0.0f); + } else { + phi_v0 = false; + } + + for (i = 0; i < ARRAY_COUNT(this->unk_26E); i++) { + if ((arg1 == i) && phi_v0) { + this->unk_26E[i]++; + } else if (this->unk_26E[i] > 0) { + this->unk_26E[i]--; + } + } +} + +void func_80A25404(ObjIceblock* this) { + this->unk_26E[1] = 0; + this->unk_26E[2] = 0; + this->unk_26E[3] = 0; + this->unk_26E[0] = 0; +} + +void func_80A2541C(ObjIceblock* this, GlobalContext* globalCtx) { + Player* player = GET_PLAYER(globalCtx); + + player->stateFlags2 &= ~0x10; + this->dyna.pushForce = 0.0f; +} + +void func_80A25440(ObjIceblock* this) { + s32 pad[2]; + MtxF sp40; + Vec3f sp34; + Vec3f sp28; + f32 sp24; + Actor* temp_s1 = this->dyna.actor.parent; + + if (temp_s1 != NULL) { + if (this->unk_2B0 == 3) { + sp24 = this->dyna.actor.shape.yOffset * this->dyna.actor.scale.y; + + Matrix_RotateY(this->dyna.actor.shape.rot.y, MTXMODE_NEW); + Matrix_InsertXRotation_s(this->dyna.actor.shape.rot.x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->dyna.actor.shape.rot.z, MTXMODE_APPLY); + + sp34.x = this->unk_248.x; + sp34.y = this->unk_248.y - sp24; + sp34.z = this->unk_248.z; + + Matrix_MultiplyVector3fByState(&sp34, &sp28); + + sp34.x = this->dyna.actor.world.pos.x; + sp34.y = this->dyna.actor.world.pos.y + sp24; + sp34.z = this->dyna.actor.world.pos.z; + + Math_Vec3f_Sum(&sp34, &sp28, &temp_s1->world.pos); + Matrix_RotateY(this->unk_254.y + this->dyna.actor.home.rot.y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->unk_254.x + this->dyna.actor.home.rot.x, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->unk_254.z + this->dyna.actor.home.rot.z, MTXMODE_APPLY); + Matrix_CopyCurrentState(&sp40); + func_8018219C(&sp40, &temp_s1->shape.rot, MTXMODE_APPLY); + } else { + Math_Vec3f_Sum(&this->dyna.actor.world.pos, &this->unk_248, &temp_s1->world.pos); + } + } +} + +static InitChainEntry sInitChain[] = { + ICHAIN_F32_DIV1000(speedXZ, 16000, ICHAIN_CONTINUE), ICHAIN_F32_DIV1000(gravity, -1800, ICHAIN_CONTINUE), + ICHAIN_F32_DIV1000(minVelocityY, -26000, ICHAIN_CONTINUE), ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 150, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 200, ICHAIN_STOP), }; -#endif - -extern ColliderCylinderInit D_80A26E50; -extern InitChainEntry D_80A26FA4[]; - -extern UNK_TYPE D_060001A0; -extern UNK_TYPE D_06000438; - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A23090.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A2311C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A2319C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A232C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A23370.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A2339C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A23690.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A236D4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A237A4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A23938.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A23B88.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A23D08.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A23F90.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A24118.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A24384.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A243E0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A24680.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A246D8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A2491C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A24954.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A24A48.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A24AA8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A24B74.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A24BDC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A24DC4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A24DD0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A2508C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A25238.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A252DC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A25404.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A2541C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A25440.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/ObjIceblock_Init.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/ObjIceblock_Destroy.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A257A0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A257B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A25824.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A2586C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A25978.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A25994.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A25A8C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A25AA8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A25BA0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A25BBC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A25C5C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A25C70.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A25CF4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A25D28.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A25E3C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A25E50.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A25FA0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A25FD4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A260E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A26144.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A262BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A262EC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A26574.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A265C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A266C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A266E0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/ObjIceblock_Update.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A26B64.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A26B74.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/func_80A26BF8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Iceblock/ObjIceblock_Draw.s") +void ObjIceblock_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjIceblock* this = THIS; + Actor* parent; + s32 pad2; + + Actor_ProcessInitChain(&this->dyna.actor, sInitChain); + this->dyna.actor.shape.rot.x = 0; + this->dyna.actor.shape.rot.z = 0; + this->dyna.actor.world.rot.x = 0; + this->dyna.actor.world.rot.z = 0; + this->dyna.actor.home.rot.x = 0; + this->dyna.actor.home.rot.z = 0; + if (!OBJICEBLOCK_GET_2(&this->dyna.actor)) { + this->dyna.actor.shape.rot.y = (this->dyna.actor.shape.rot.y + 0x2000) & 0xC000; + this->dyna.actor.home.rot.y = this->dyna.actor.shape.rot.y; + this->dyna.actor.world.rot.y = this->dyna.actor.shape.rot.y; + } + + DynaPolyActor_Init(&this->dyna, 1); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &object_ice_block_Colheader_000438); + func_800C62BC(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit); + + if (OBJICEBLOCK_GET_1(&this->dyna.actor)) { + this->collider.dim.yShift = -100; + this->collider.dim.height = 126; + this->collider.dim.radius = 29; + } + + if (D_80A26E7C == NULL) { + D_80A26E7C = Lib_SegmentedToVirtual(&object_ice_block_Matanimheader_000328); + } + + if (!(this->unk_1B0 & 8)) { + parent = this->dyna.actor.parent; + if (parent != NULL) { + this->unk_1B0 |= 8; + Math_Vec3f_Diff(&parent->world.pos, &this->dyna.actor.world.pos, &this->unk_248); + this->unk_254.x = parent->shape.rot.x - this->dyna.actor.home.rot.x; + this->unk_254.y = parent->shape.rot.y - this->dyna.actor.home.rot.y; + this->unk_254.z = parent->shape.rot.z - this->dyna.actor.home.rot.z; + } + } + + if (OBJICEBLOCK_GET_1(&this->dyna.actor)) { + this->unk_2B4 = -1.0f; + } + + this->unk_2B0 = 0; + this->unkFunc = func_80A26B64; + func_80A257A0(this); + this->unk_2AE = 450; +} + +void ObjIceblock_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjIceblock* this = THIS; + + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId); + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void func_80A257A0(ObjIceblock* this) { + this->actionFunc = func_80A257B4; +} + +void func_80A257B4(ObjIceblock* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->dyna.actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->dyna.actor.cutscene, &this->dyna.actor); + this->unkFunc = func_80A26BF8; + this->unk_2B1 = 80; + func_80A25824(this); + } else { + ActorCutscene_SetIntentToPlay(this->dyna.actor.cutscene); + } +} + +void func_80A25824(ObjIceblock* this) { + this->actionFunc = func_80A2586C; + this->unk_2A0 = 2; + Actor_SetScale(&this->dyna.actor, 0.01f); + func_80A2319C(this, this->dyna.actor.scale.x); +} + +void func_80A2586C(ObjIceblock* this, GlobalContext* globalCtx) { + func_80A236D4(this, &this->dyna.actor.home.pos); + + if (this->unk_2A0 > 0) { + this->unk_2A0--; + return; + } + + if (Math_StepToF(&this->dyna.actor.scale.x, 0.1f, 0.02f)) { + Actor_SetScale(&this->dyna.actor, 0.1f); + if (OBJICEBLOCK_GET_1(&this->dyna.actor)) { + this->unk_2B4 = 0.05f; + } + func_80A25978(this); + } else { + Actor_SetScale(&this->dyna.actor, this->dyna.actor.scale.x); + this->unk_2A0 = 2; + } + + func_80A2319C(this, this->dyna.actor.scale.x); + + if (this->dyna.actor.flags & 0x40) { + func_80A2339C(globalCtx, &this->dyna.actor.world.pos, (this->dyna.actor.scale.x + 0.05f) * 0.6666666f, 1.0f, 3); + } +} + +void func_80A25978(ObjIceblock* this) { + this->actionFunc = func_80A25994; + this->unk_2A0 = 4; +} + +void func_80A25994(ObjIceblock* this, GlobalContext* globalCtx) { + s32 pad; + Vec3f sp30; + + func_80A236D4(this, &this->dyna.actor.home.pos); + if (this->unk_2A0 > 0) { + this->unk_2A0--; + return; + } + + if (this->dyna.actor.flags & 0x40) { + func_80A2339C(globalCtx, &this->dyna.actor.world.pos, this->dyna.actor.scale.x, 1.2f, 15); + if (OBJICEBLOCK_GET_1(&this->dyna.actor)) { + sp30.x = this->dyna.actor.world.pos.x; + sp30.y = this->dyna.actor.world.pos.y - 30.0f; + sp30.z = this->dyna.actor.world.pos.z; + func_80A2339C(globalCtx, &sp30, this->dyna.actor.scale.x, 1.2f, 10); + } + } + + if (OBJICEBLOCK_GET_1(&this->dyna.actor)) { + this->unk_2B4 = 0.1f; + } + + func_80A25A8C(this); + this->unkFunc = func_80A26B74; +} + +void func_80A25A8C(ObjIceblock* this) { + this->actionFunc = func_80A25AA8; + this->unk_2A0 = 2; +} + +void func_80A25AA8(ObjIceblock* this, GlobalContext* globalCtx) { + s32 pad[2]; + f32 sp24; + s32 temp = func_80A236D4(this, &this->dyna.actor.home.pos); + + if (this->unk_2A0 > 0) { + this->unk_2A0--; + return; + } + + if (temp) { + sp24 = this->dyna.actor.scale.y * 300.0f; + func_80A23D08(this, globalCtx); + if (sp24 < (this->dyna.actor.world.pos.y - this->dyna.actor.floorHeight)) { + func_80A25BA0(this); + } else { + func_80A25C5C(this); + } + + this->dyna.actor.world.pos.y -= sp24; + this->dyna.actor.shape.yOffset = 300.0f; + this->unk_248.y += sp24; + + if (OBJICEBLOCK_GET_1(&this->dyna.actor)) { + this->collider.dim.yShift = -69; + } else { + this->collider.dim.yShift = 0; + } + this->unk_1B0 |= 0x100; + } +} + +void func_80A25BA0(ObjIceblock* this) { + this->actionFunc = func_80A25BBC; + this->dyna.actor.velocity.y = 0.0f; +} + +void func_80A25BBC(ObjIceblock* this, GlobalContext* globalCtx) { + if (func_80A25238(this) != -1) { + func_80A2541C(this, globalCtx); + } + + func_80A23690(this); + + if (func_80A23F90(this, globalCtx)) { + Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + } + + if (func_80A24954(this, globalCtx)) { + func_80A2491C(this); + if (this->unk_2B0 == 3) { + Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_DIVE_INTO_WATER_L); + } + } +} + +void func_80A25C5C(ObjIceblock* this) { + this->actionFunc = func_80A25C70; +} + +void func_80A25C70(ObjIceblock* this, GlobalContext* globalCtx) { + if (func_80A25238(this) != -1) { + func_80A2541C(this, globalCtx); + } + + if (Math_StepToF(&this->dyna.actor.world.pos.y, this->dyna.actor.floorHeight - 0.1f, 14.0f)) { + func_80A23F90(this, globalCtx); + func_80A24954(this, globalCtx); + } +} + +void func_80A25CF4(ObjIceblock* this) { + func_80A25404(this); + this->actionFunc = func_80A25D28; +} + +void func_80A25D28(ObjIceblock* this, GlobalContext* globalCtx) { + s32 sp34; + s32 sp30; + Vec3f sp24; + + func_80A23690(this); + func_80A23F90(this, globalCtx); + sp30 = func_80A25238(this); + func_80A252DC(this, sp30); + sp34 = true; + if (sp30 == -1) { + sp34 = false; + } else if (!(this->unk_1B0 & 2) && (this->unk_26E[sp30] >= 11)) { + sp34 = true; + if (!func_80A24118(this, globalCtx, (this->dyna.pushForce > 0.0f) ? 59.9f : 89.9f, &sp24)) { + func_80A232C4(this, sp30); + func_80A25E3C(this); + sp34 = false; + } + } + + if (sp34) { + func_80A2541C(this, globalCtx); + } + + func_80A24A48(this, globalCtx); +} + +void func_80A25E3C(ObjIceblock* this) { + this->actionFunc = func_80A25E50; +} + +void func_80A25E50(ObjIceblock* this, GlobalContext* globalCtx) { + s32 pad; + f32 temp_f0 = this->unk_268 - *this->unk_264; + f32 temp_f2 = (Math_SinS(fabsf(temp_f0) * 546.13336f) * 2.8f) + 1.2f; + s32 sp38 = Math_StepToF(this->unk_264, this->unk_268, CLAMP_MAX(temp_f2, 3.5f)); + s32 pad2; + Vec3f sp28; + + func_80A23690(this); + if (!func_80A23F90(this, globalCtx)) { + func_80A24680(this, globalCtx); + func_80A23B88(this); + func_80A2541C(this, globalCtx); + func_80A25BA0(this); + } else if (sp38) { + if (func_80A24118(this, globalCtx, 59.9f, &sp28)) { + Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + } + func_80A2541C(this, globalCtx); + func_80A25CF4(this); + } else { + func_800B9010(&this->dyna.actor, 0xDF); + } +} + +void func_80A25FA0(ObjIceblock* this) { + func_80A25404(this); + this->actionFunc = func_80A25FD4; +} + +void func_80A25FD4(ObjIceblock* this, GlobalContext* globalCtx) { + s32 pad; + s32 sp30; + s32 sp2C; + Vec3f sp20; + + func_80A23690(this); + func_80A23F90(this, globalCtx); + sp2C = func_80A25238(this); + func_80A252DC(this, sp2C); + sp30 = true; + + if (sp2C == -1) { + sp30 = false; + } else if (!(this->unk_1B0 & 2) && (this->unk_26E[sp2C] >= 11) && !func_80A24118(this, globalCtx, 2.0f, &sp20) && + !func_801233E4(globalCtx)) { + func_80A23370(this, sp2C); + func_80A260E8(this); + sp30 = false; + func_800B7298(globalCtx, &this->dyna.actor, 7); + this->unk_1B0 |= 1; + } + + if (this) {} + + if (sp30) { + func_80A2541C(this, globalCtx); + } + func_80A24A48(this, globalCtx); +} + +void func_80A260E8(ObjIceblock* this) { + static f32 D_80A26FC0[] = { 14.0, -14.0, 14.0, -14.0 }; + + this->unk_260 = D_80A26FC0[this->unk_26C]; + this->unk_25C = 0.0f; + this->dyna.actor.velocity.y = 0.0f; + this->unk_2A0 = 15; + func_80A24DC4(this); + this->actionFunc = func_80A26144; +} + +void func_80A26144(ObjIceblock* this, GlobalContext* globalCtx) { + s32 pad2; + s32 sp28; + s32 isBool; + s32 sp24; + + if (this->unk_2A0 > 0) { + this->unk_2A0--; + } + + Math_StepToF(&this->unk_25C, this->unk_260, 0.75f); + *this->unk_264 += this->unk_25C; + sp28 = func_80A24384(this, globalCtx); + func_80A23690(this); + sp24 = func_80A23F90(this, globalCtx); + isBool = sp24 == 0; + + if (isBool || sp28 || (this->unk_2A0 == 1)) { + func_80A2541C(this, globalCtx); + } + + if ((this->unk_1B0 & 1) && (isBool || sp28 || (this->dyna.actor.xzDistToPlayer > 400.0f))) { + this->unk_1B0 &= ~1; + func_800B7298(globalCtx, &this->dyna.actor, 6); + } + + if (isBool) { + func_80A24680(this, globalCtx); + func_80A23B88(this); + func_80A25BA0(this); + } else if (sp28) { + Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_BLOCK_BOUND); + func_80A23B88(this); + func_80A25FA0(this); + } else { + func_800B9010(&this->dyna.actor, 0xDF); + } + + func_80A24DD0(this, globalCtx); +} + +void func_80A262BC(ObjIceblock* this) { + this->actionFunc = func_80A262EC; + this->dyna.actor.velocity.y *= 0.7f; + this->unk_2A0 = -1; +} + +void func_80A262EC(ObjIceblock* this, GlobalContext* globalCtx) { + s32 pad; + f32 temp_f14; + f32 temp_f18; + Vec3f sp38; + f32 temp; + + if (func_80A25238(this) != -1) { + func_80A2541C(this, globalCtx); + } + + if (this->unk_2A0 > 0) { + this->unk_2A0--; + } + + if (this->unk_2A0 == -1) { + if ((this->dyna.actor.velocity.y < 0.0f) && (this->dyna.actor.world.pos.y < this->unk_244) && + ((this->unk_244 - (600.0f * this->dyna.actor.scale.y)) <= this->dyna.actor.world.pos.y)) { + func_80A24BDC(this, globalCtx, 1.0f, 0.9f, 11); + func_80A24B74(this, globalCtx); + this->unk_2A0 = 3; + } else { + this->unk_2A0 = 0; + } + } else if (this->unk_2A0 == 1) { + func_80A24BDC(this, globalCtx, 0.7f, 1.3f, 6); + func_80A24B74(this, globalCtx); + } + + this->dyna.actor.velocity.y += 5.0f; + if (this->dyna.actor.velocity.y > 3.0f) { + this->dyna.actor.velocity.y = 3.0f; + } + + temp = this->dyna.actor.velocity.y; + this->dyna.actor.world.pos.y += temp; + temp_f14 = this->dyna.actor.world.pos.y + (600.0f * this->dyna.actor.scale.y); + if (this->unk_244 < (temp_f14 - 90.0f)) { + func_80A24B74(this, globalCtx); + func_80A26574(this); + } else { + if ((this->dyna.actor.velocity.y > 0.0f) && (temp_f14 < (this->unk_244 + 3.0f)) && + (this->unk_244 <= temp_f14)) { + func_80A24BDC(this, globalCtx, 0.8f, 1.0f, 11); + func_80A24B74(this, globalCtx); + } + + sp38.x = this->dyna.actor.world.pos.x; + sp38.y = (this->unk_244 - (600.0f * this->dyna.actor.scale.y)) + 90.0f; + sp38.z = this->dyna.actor.world.pos.z; + + if (func_80A246D8(this, globalCtx, &sp38)) { + this->unk_1B0 |= 0x80; + } + } +} + +void func_80A26574(ObjIceblock* this) { + this->actionFunc = func_80A265C0; + this->unk_27C.unk_10 = 0; + this->unk_27C.unk_12 = 0; + this->unk_27C.unk_0C = 2111; + this->unk_27C.unk_0E = 3000; + this->unk_27C.unk_18 = 500; + this->unk_27C.unk_22 = 500; + this->unk_27C.unk_08 = 7.0f; + this->unk_2A0 = 40; +} + +void func_80A265C0(ObjIceblock* this, GlobalContext* globalCtx) { + s32 pad; + ObjIceBlockUnkStruct4* ptr; + + if (func_80A25238(this) != -1) { + func_80A2541C(this, globalCtx); + } + + if (this->unk_2A0 > 0) { + this->unk_2A0--; + } else { + ptr = &this->unk_27C; + this->unk_2A0 = Rand_S16Offset(30, 60); + ptr->unk_0C = Rand_S16Offset(300, 300); + ptr->unk_0E = Rand_S16Offset(900, 600); + ptr->unk_04 = (2.0f * Rand_ZeroOne()) + 1.0f; + ptr->unk_14 = (u32)Rand_Next() >> 0x10; + func_80A24B74(this, globalCtx); + } + + func_80A237A4(this); + func_80A23938(this); + + if (this->unk_1B0 & 0x40) { + func_80A24B74(this, globalCtx); + } + + func_80A24A48(this, globalCtx); +} + +void func_80A266C4(ObjIceblock* this) { + this->actionFunc = func_80A266E0; + this->unk_2A8 = 0.0f; +} + +void func_80A266E0(ObjIceblock* this, GlobalContext* globalCtx) { + f32 temp; + s32 sp20; + Actor* actor = &this->dyna.actor; + + Math_StepToF(&this->unk_2A8, (1.0f / 600.0f), (1.0f / 6000.0f)); + sp20 = Math_StepToF(&actor->scale.y, 0.0f, this->unk_2A8); + temp = actor->scale.y * 10.0f * 300.0f; + actor->shape.yOffset = temp; + + if (actor->scale.y < 0.075f) { + actor->scale.x = Math_SinS(actor->scale.y * 218453.33f) * 0.1f; + if (actor->scale.x < 0.0f) { + actor->scale.x = 0.0f; + } + actor->scale.z = actor->scale.x; + } + + if (OBJICEBLOCK_GET_1(&this->dyna.actor)) { + this->unk_2B4 = actor->scale.y; + this->collider.dim.height = (s32)(actor->scale.y * 1230.0f) + 1; + this->collider.dim.yShift = actor->scale.y * -1000.0f; + this->collider.dim.radius = actor->scale.x * 290.0f; + } + + func_80A2508C(this, globalCtx); + + if (sp20) { + Actor_MarkForDeath(&this->dyna.actor); + } +} + +void ObjIceblock_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjIceblock* this = THIS; + Actor* parent = this->dyna.actor.parent; + + if (parent != NULL) { + if ((parent->update == NULL) || (&this->dyna.actor != parent->child)) { + this->dyna.actor.parent = NULL; + parent = NULL; + } + } + + if (DynaPolyActor_IsInRidingMovingState(&this->dyna)) { + if (this->unk_1B0 & 0x20) { + this->unk_1B0 &= ~0x40; + } else { + this->unk_1B0 |= 0x40; + this->unk_1B0 |= 0x20; + } + } else if (this->unk_1B0 & 0x20) { + this->unk_1B0 |= 0x40; + this->unk_1B0 &= ~0x20; + } else { + this->unk_1B0 &= ~0x40; + } + + if ((this->unk_2B0 == 1) || (this->unk_2B0 == 2) || (this->unk_2B0 == 3)) { + if (this->unk_2AE > 0) { + this->unk_2AE--; + } + } + + if (((this->collider.base.acFlags & AC_HIT) && (this->collider.info.acHitInfo->toucher.dmgFlags & 0x800)) || + (this->unk_2AE == 0)) { + this->unk_2AE = -1; + this->unk_2B0 = 4; + this->unk_1B0 &= ~0x100; + if (this->unk_1B0 & 1) { + this->unk_1B0 &= ~1; + func_800B7298(globalCtx, &this->dyna.actor, 6); + } + func_80A266C4(this); + } + + if (this->unk_2B1 > 0) { + this->unk_2B1--; + if (this->unk_2B1 == 0) { + ActorCutscene_Stop(this->dyna.actor.cutscene); + } + } + + this->actionFunc(this, globalCtx); + if (this->dyna.actor.update == NULL) { + if (parent != NULL) { + parent->child = NULL; + parent->shape.rot.x = this->unk_254.x + this->dyna.actor.home.rot.x; + parent->shape.rot.y = this->unk_254.y + this->dyna.actor.home.rot.y; + parent->shape.rot.z = this->unk_254.z + this->dyna.actor.home.rot.z; + this->dyna.actor.parent = NULL; + } + return; + } + + this->collider.base.ocFlags1 &= ~OC1_HIT; + this->collider.base.acFlags &= ~AC_HIT; + Collider_UpdateCylinder(&this->dyna.actor, &this->collider); + + if (this->unk_1B0 & 0x10) { + if (OBJICEBLOCK_GET_1(&this->dyna.actor) && (this->unk_2B4 > 0.0f)) { + this->collider.base.ocFlags1 &= ~OC1_NO_PUSH; + this->collider.base.ocFlags1 |= (OC1_TYPE_2 | OC1_TYPE_1 | OC1_TYPE_PLAYER); + this->collider.info.bumper.dmgFlags |= + (0x800000 | 0x400000 | 0x10000 | 0x2000 | 0x1000 | 0x800 | 0x200 | 0x100 | 0x80 | 0x20 | 0x10 | 0x2); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + } else { + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + if (this->unk_1B0 & 0x100) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + } + + func_80A25440(this); + Actor_SetHeight(&this->dyna.actor, this->dyna.actor.shape.yOffset * this->dyna.actor.scale.y); + this->unk_1B0 &= ~0x2; + + if (parent) {} +} + +void func_80A26B64(ObjIceblock* this, GlobalContext* globalCtx) { +} + +void func_80A26B74(ObjIceblock* this, GlobalContext* globalCtx) { + func_800BE03C(globalCtx, object_ice_block_DL_0001A0); + if (OBJICEBLOCK_GET_1(&this->dyna.actor) && (this->unk_2B4 > 0.0f)) { + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_ice_block_Matanimheader_0009D0)); + func_800BE03C(globalCtx, object_ice_block_DL_0007F0); + } +} + +void func_80A26BF8(ObjIceblock* this, GlobalContext* globalCtx) { + s32 pad[2]; + ObjIceBlockUnkStruct* ptr; + s32 i; + Vec3s sp70; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C2DC(globalCtx->state.gfxCtx); + sp70.z = 0; + + for (i = 0; i < ARRAY_COUNT(this->unk_1B4); i++) { + ptr = &this->unk_1B4[i]; + sp70.x = ptr->unk_00; + sp70.y = ptr->unk_02; + Matrix_SetStateRotationAndTranslation(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y, + this->dyna.actor.world.pos.z, &sp70); + Matrix_Scale(ptr->unk_04, ptr->unk_08, ptr->unk_0C, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_ice_block_DL_0001A0); + } + + if (OBJICEBLOCK_GET_1(&this->dyna.actor) && (this->unk_2B4 > 0.0f)) { + AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&object_ice_block_Matanimheader_0009D0)); + Matrix_SetStateRotationAndTranslation(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y - 20.0f, + this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); + Matrix_Scale(this->unk_2B4, this->unk_2B4, this->unk_2B4, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, object_ice_block_DL_0007F0); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void ObjIceblock_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjIceblock* this = THIS; + + AnimatedMat_Draw(globalCtx, D_80A26E7C); + this->unkFunc(this, globalCtx); + func_80A24AA8(this, globalCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Iceblock/z_obj_iceblock.h b/src/overlays/actors/ovl_Obj_Iceblock/z_obj_iceblock.h index 4851a8763..6a4875bb3 100644 --- a/src/overlays/actors/ovl_Obj_Iceblock/z_obj_iceblock.h +++ b/src/overlays/actors/ovl_Obj_Iceblock/z_obj_iceblock.h @@ -6,12 +6,76 @@ struct ObjIceblock; typedef void (*ObjIceblockActionFunc)(struct ObjIceblock*, GlobalContext*); +typedef void (*ObjIceblockUnkFunc)(struct ObjIceblock*, GlobalContext*); + +#define OBJICEBLOCK_GET_2(thisx) (((thisx)->params >> 1) & 1) +#define OBJICEBLOCK_GET_1(thisx) ((thisx)->params & 1) + +typedef struct { + /* 0x00 */ s16 unk_00; + /* 0x02 */ s16 unk_02; + /* 0x04 */ f32 unk_04; + /* 0x08 */ f32 unk_08; + /* 0x0C */ f32 unk_0C; +} ObjIceBlockUnkStruct; // size = 0x10 + +typedef struct { + /* 0x00 */ CollisionPoly* unk_00; + /* 0x04 */ f32 unk_04; + /* 0x08 */ s32 unk_08; + /* 0x0C */ f32 unk_0C; +} ObjIceBlockUnkStruct2; // size = 0x10 + +typedef struct { + f32 unk_00; + f32 unk_04; +} ObjIceBlockUnkStruct3; // size = 0x8 + +typedef struct { + /* 0x00 */ f32 unk_00; + /* 0x04 */ f32 unk_04; + /* 0x08 */ f32 unk_08; + /* 0x0C */ s16 unk_0C; + /* 0x0E */ s16 unk_0E; + /* 0x10 */ s16 unk_10; + /* 0x12 */ s16 unk_12; + /* 0x14 */ s16 unk_14; + /* 0x14 */ s16 unk_16; + /* 0x18 */ s16 unk_18; + /* 0x1C */ f32 unk_1C; + /* 0x20 */ s16 unk_20; + /* 0x22 */ s16 unk_22; +} ObjIceBlockUnkStruct4; // size = 0x24 typedef struct ObjIceblock { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x64]; + /* 0x0000 */ DynaPolyActor dyna; + /* 0x015C */ ColliderCylinder collider; /* 0x01A8 */ ObjIceblockActionFunc actionFunc; - /* 0x01AC */ char unk_1AC[0x10C]; + /* 0x01AC */ ObjIceblockUnkFunc unkFunc; + /* 0x01B0 */ s32 unk_1B0; + /* 0x01B4 */ ObjIceBlockUnkStruct unk_1B4[4]; + /* 0x01F4 */ ObjIceBlockUnkStruct2 unk_1F4[5]; + /* 0x0244 */ f32 unk_244; + /* 0x0248 */ Vec3f unk_248; + /* 0x0254 */ Vec3s unk_254; + /* 0x025C */ f32 unk_25C; + /* 0x0260 */ f32 unk_260; + /* 0x0264 */ f32* unk_264; + /* 0x0268 */ f32 unk_268; + /* 0x026C */ s16 unk_26C; + /* 0x026E */ s16 unk_26E[4]; + /* 0x0276 */ s16 unk_276; + /* 0x0278 */ s16 unk_278; + /* 0x027C */ ObjIceBlockUnkStruct4 unk_27C; + /* 0x02A0 */ s16 unk_2A0; + /* 0x02A2 */ s16 unk_2A2; + /* 0x02A4 */ f32 unk_2A4; + /* 0x02A8 */ f32 unk_2A8; + /* 0x02AC */ s16 unk_2AC; + /* 0x02AE */ s16 unk_2AE; + /* 0x02B0 */ s8 unk_2B0; + /* 0x02B1 */ s8 unk_2B1; + /* 0x02B4 */ f32 unk_2B4; } ObjIceblock; // size = 0x2B8 extern const ActorInit Obj_Iceblock_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Jg_Gakki/z_obj_jg_gakki.c b/src/overlays/actors/ovl_Obj_Jg_Gakki/z_obj_jg_gakki.c index e85548758..8a5c99a79 100644 --- a/src/overlays/actors/ovl_Obj_Jg_Gakki/z_obj_jg_gakki.c +++ b/src/overlays/actors/ovl_Obj_Jg_Gakki/z_obj_jg_gakki.c @@ -15,7 +15,6 @@ void ObjJgGakki_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjJgGakki_Update(Actor* thisx, GlobalContext* globalCtx); void ObjJgGakki_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Jg_Gakki_InitVars = { ACTOR_OBJ_JG_GAKKI, ACTORCAT_PROP, @@ -28,14 +27,42 @@ const ActorInit Obj_Jg_Gakki_InitVars = { (ActorFunc)ObjJgGakki_Draw, }; -#endif +extern AnimationHeader D_0601B1E8; // gGoronElderDrumAnim +extern SkeletonHeader D_0601B210; // gGoronElderDrumSkel -extern UNK_TYPE D_0601B1E8; +void ObjJgGakki_Init(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + ObjJgGakki* this = THIS; + f32 frameCount = Animation_GetLastFrame(&D_0601B1E8); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Jg_Gakki/ObjJgGakki_Init.s") + ActorShape_Init(&this->actor.shape, 0.0f, func_800B3FC0, 24.0f); + SkelAnime_Init(globalCtx, &this->skelAnime, &D_0601B210, NULL, NULL, NULL, 0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Jg_Gakki/ObjJgGakki_Destroy.s") + if (((globalCtx->sceneNum == SCENE_SPOT00) && (gSaveContext.sceneSetupIndex == 7)) && + (globalCtx->csCtx.unk_12 == 0)) { + Animation_Change(&this->skelAnime, &D_0601B1E8, 1.0f, frameCount, frameCount, 2, 0.0f); + } else if ((globalCtx->sceneNum == SCENE_17SETUGEN) || (globalCtx->sceneNum == SCENE_10YUKIYAMANOMURA)) { + Animation_Change(&this->skelAnime, &D_0601B1E8, 1.0f, 0.0f, frameCount, 2, 0.0f); + } else { + Actor_MarkForDeath(&this->actor); + } + Actor_SetScale(&this->actor, 0.01f); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Jg_Gakki/ObjJgGakki_Update.s") +void ObjJgGakki_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjJgGakki* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Jg_Gakki/ObjJgGakki_Draw.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} + +void ObjJgGakki_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjJgGakki* this = THIS; + + SkelAnime_Update(&this->skelAnime); +} + +void ObjJgGakki_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjJgGakki* this = THIS; + + SkelAnime_DrawOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, NULL, NULL, &this->actor); +} diff --git a/src/overlays/actors/ovl_Obj_Jg_Gakki/z_obj_jg_gakki.h b/src/overlays/actors/ovl_Obj_Jg_Gakki/z_obj_jg_gakki.h index 75a02ed4a..a3e8ae8eb 100644 --- a/src/overlays/actors/ovl_Obj_Jg_Gakki/z_obj_jg_gakki.h +++ b/src/overlays/actors/ovl_Obj_Jg_Gakki/z_obj_jg_gakki.h @@ -7,7 +7,8 @@ struct ObjJgGakki; typedef struct ObjJgGakki { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x90]; + /* 0x144 */ SkelAnime skelAnime; + /* 0x188 */ ColliderCylinder collider; } ObjJgGakki; // size = 0x1D4 extern const ActorInit Obj_Jg_Gakki_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.c b/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.c index 204b50663..bda43e48d 100644 --- a/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.c +++ b/src/overlays/actors/ovl_Obj_Kibako/z_obj_kibako.c @@ -5,6 +5,8 @@ */ #include "z_obj_kibako.h" +#include "objects/gameplay_dangeon_keep/gameplay_dangeon_keep.h" +#include "objects/object_kibako/object_kibako.h" #define FLAGS 0x04000010 @@ -66,14 +68,11 @@ static ColliderCylinderInit sCylinderInit = { { 15, 30, 0, { 0, 0, 0 } }, }; -extern Gfx D_06001A70[]; -extern Gfx D_06001180[]; - static s16 sObjectIdList[] = { GAMEPLAY_DANGEON_KEEP, OBJECT_KIBAKO }; -static Gfx* sKakeraDisplayLists[] = { D_05007980, D_06001A70 }; +static Gfx* sKakeraDisplayLists[] = { gameplay_dangeon_keep_DL_007980, gSmallCrateFragmentDL }; -static Gfx* sDisplayLists[] = { D_05007890, D_06001180 }; +static Gfx* sDisplayLists[] = { gameplay_dangeon_keep_DL_007890, gSmallCrateDL }; static InitChainEntry sInitChain[] = { ICHAIN_F32_DIV1000(gravity, -1500, ICHAIN_CONTINUE), diff --git a/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.c b/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.c index 69bfaad18..6bb1bbdb6 100644 --- a/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.c +++ b/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.c @@ -5,6 +5,7 @@ */ #include "z_obj_kibako2.h" +#include "objects/object_kibako2/object_kibako2.h" #include "overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h" #define FLAGS 0x00000000 @@ -57,10 +58,6 @@ static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneDownward, 200, ICHAIN_STOP), }; -extern Gfx D_06000960[]; -extern CollisionHeader D_06000B70; -extern Gfx D_06001040[]; - s32 ObjKibako2_ContainsSkulltula(ObjKibako2* this, GlobalContext* globalCtx) { s32 actorSpawnParam = KIBAKO2_SKULLTULA_SPAWN_PARAM(&this->dyna.actor); s32 flag = -1; @@ -103,7 +100,7 @@ void ObjKibako2_Break(ObjKibako2* this, GlobalContext* globalCtx) { phi_s0 = 0x20; } EffectSsKakera_Spawn(globalCtx, &pos, &velocity, &pos, -200, phi_s0, 28, 2, 0, (Rand_ZeroOne() * 30.0f) + 5.0f, - 0, 0, 70, KAKERA_COLOR_NONE, OBJECT_KIBAKO2, D_06001040); + 0, 0, 70, KAKERA_COLOR_NONE, OBJECT_KIBAKO2, gLargeCrateFragment1DL); } func_800BBFB0(globalCtx, thisPos, 90.0f, 6, 100, 160, 1); } @@ -147,12 +144,12 @@ void ObjKibako2_SpawnContents(ObjKibako2* this, GlobalContext* globalCtx) { void ObjKibako2_Init(Actor* thisx, GlobalContext* globalCtx) { ObjKibako2* this = THIS; s32 pad; - ObjKibako2Contents contents = KIBAKO2_CONTENTS(&this->dyna.actor); + s32 contents = KIBAKO2_CONTENTS(&this->dyna.actor); DynaPolyActor_Init(&this->dyna, 0); Collider_InitCylinder(globalCtx, &this->collider); Actor_ProcessInitChain(&this->dyna.actor, sInitChain); - DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &D_06000B70); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &gLargeCrateCol); Collider_SetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit); Collider_UpdateCylinder(&this->dyna.actor, &this->collider); this->dyna.actor.home.rot.z = 0; @@ -250,5 +247,5 @@ void ObjKibako2_Update(Actor* thisx, GlobalContext* globalCtx) { } void ObjKibako2_Draw(Actor* thisx, GlobalContext* globalCtx) { - func_800BDFC0(globalCtx, D_06000960); + func_800BDFC0(globalCtx, gLargeCrateDL); } diff --git a/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.h b/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.h index b6de7da89..dd4687ab2 100644 --- a/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.h +++ b/src/overlays/actors/ovl_Obj_Kibako2/z_obj_kibako2.h @@ -18,11 +18,11 @@ struct ObjKibako2; typedef void (*ObjKibako2ActionFunc)(struct ObjKibako2*, GlobalContext*); typedef struct ObjKibako2 { - /* 0x0000 */ DynaPolyActor dyna; - /* 0x015C */ ColliderCylinder collider; - /* 0x01A8 */ ObjKibako2ActionFunc actionFunc; - /* 0x01AC */ s8 unk_1AC; - /* 0x01AD */ s8 skulltulaNoiseTimer; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ ColliderCylinder collider; + /* 0x1A8 */ ObjKibako2ActionFunc actionFunc; + /* 0x1AC */ s8 unk_1AC; + /* 0x1AD */ s8 skulltulaNoiseTimer; } ObjKibako2; // size = 0x1B0 extern const ActorInit Obj_Kibako2_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c b/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c index 35c81daa9..eab5d8f1c 100644 --- a/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c +++ b/src/overlays/actors/ovl_Obj_Lightswitch/z_obj_lightswitch.c @@ -145,7 +145,7 @@ void ObjLightswitch_SpawnEffects(ObjLightswitch* this, GlobalContext* globalCtx) effectPos.y = this->actor.world.pos.y + tempResultDiff + 10.0f; effectPos.z = this->actor.world.pos.z + ((rand * cosResult) - (tempResult * sinResult)); - EffectSsDeadDb_Spawn(globalCtx, &effectPos, &D_801D15B0, &D_801D15B0, &sLightswitchEffectPrimColor, + EffectSsDeadDb_Spawn(globalCtx, &effectPos, &gZeroVec3f, &gZeroVec3f, &sLightswitchEffectPrimColor, &sLightswitchEffectEnvColor, 100, 0, 9); } } diff --git a/src/overlays/actors/ovl_Obj_Makekinsuta/z_obj_makekinsuta.c b/src/overlays/actors/ovl_Obj_Makekinsuta/z_obj_makekinsuta.c index f0cc27a9c..19c078792 100644 --- a/src/overlays/actors/ovl_Obj_Makekinsuta/z_obj_makekinsuta.c +++ b/src/overlays/actors/ovl_Obj_Makekinsuta/z_obj_makekinsuta.c @@ -1,7 +1,7 @@ /* * File: z_obj_makekinsuta.c * Overlay: ovl_Obj_Makekinsuta - * Description: Dirt Patch with Skulltula hiding in it + * Description: Swamp Spider House - Soft soil with Skulltula hiding in it */ #include "z_obj_makekinsuta.h" diff --git a/src/overlays/actors/ovl_Obj_Moon_Stone/z_obj_moon_stone.c b/src/overlays/actors/ovl_Obj_Moon_Stone/z_obj_moon_stone.c index fa1101ea0..153a4a914 100644 --- a/src/overlays/actors/ovl_Obj_Moon_Stone/z_obj_moon_stone.c +++ b/src/overlays/actors/ovl_Obj_Moon_Stone/z_obj_moon_stone.c @@ -1,5 +1,5 @@ /* - * File z_obj_moon_stone.c + * File: z_obj_moon_stone.c * Overlay: ovl_Obj_Moon_Stone * Description: Moon's Tear */ @@ -156,7 +156,7 @@ void ObjMoonStone_Draw(Actor* thisx, GlobalContext* globalCtx) { AnimatedMat_Draw(globalCtx, Lib_SegmentedToVirtual(&D_06001C60)); gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_OPA_DISP++, D_06000D78); - Matrix_NormalizeXYZ(&globalCtx->mf_187FC); + Matrix_NormalizeXYZ(&globalCtx->billboardMtxF); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); gSPDisplayList(POLY_XLU_DISP++, D_06000C80); CLOSE_DISPS(globalCtx->state.gfxCtx); diff --git a/src/overlays/actors/ovl_Obj_Mu_Pict/z_obj_mu_pict.c b/src/overlays/actors/ovl_Obj_Mu_Pict/z_obj_mu_pict.c index 41446b805..0e510d6b3 100644 --- a/src/overlays/actors/ovl_Obj_Mu_Pict/z_obj_mu_pict.c +++ b/src/overlays/actors/ovl_Obj_Mu_Pict/z_obj_mu_pict.c @@ -1,7 +1,7 @@ /* * File: z_obj_mu_pict.c * Overlay: ovl_Obj_Mu_Pict - * Description: + * Description: Handles dialogue for checking the Garo/Gibdo poster in the Music Box House */ #include "z_obj_mu_pict.h" diff --git a/src/overlays/actors/ovl_Obj_Mure/z_obj_mure.c b/src/overlays/actors/ovl_Obj_Mure/z_obj_mure.c index 7191ca259..1519f92eb 100644 --- a/src/overlays/actors/ovl_Obj_Mure/z_obj_mure.c +++ b/src/overlays/actors/ovl_Obj_Mure/z_obj_mure.c @@ -14,11 +14,12 @@ void ObjMure_Init(Actor* thisx, GlobalContext* globalCtx); void ObjMure_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjMure_Update(Actor* thisx, GlobalContext* globalCtx); -void func_808D7FFC(ObjMure* this, GlobalContext* globalCtx); -void func_808D8014(ObjMure* this, GlobalContext* globalCtx); -void func_808D8678(ObjMure* this, GlobalContext* globalCtx); +void ObjMure_InitialAction(ObjMure* this, GlobalContext* globalCtx); +void ObjMure_CulledState(ObjMure* this, GlobalContext* globalCtx); +void ObjMure_ActiveState(ObjMure* this, GlobalContext* globalCtx); +void ObjMure_KillActors(ObjMure* this, GlobalContext* globalCtx); +void ObjMure_CheckChildren(ObjMure* this, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Mure_InitVars = { ACTOR_OBJ_MURE, ACTORCAT_ITEMACTION, @@ -31,53 +32,368 @@ const ActorInit Obj_Mure_InitVars = { (ActorFunc)NULL, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_808D87BC[] = { +static f32 sZClip[] = { + 1600.0f, 1600.0f, 1000.0f, 1000.0f, 1000.0f, +}; + +static s32 sMaxChildSpawns[] = { + 12, + 9, + 8, + 0, +}; + +static s16 sSpawnActorIds[] = { + ACTOR_EN_KUSA, 0, ACTOR_EN_FISH, ACTOR_EN_INSECT, ACTOR_EN_BUTTE, +}; + +static s16 sSpawnParams[] = { + 0, 2, -1, 0, -1, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 1200, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneScale, 200, ICHAIN_CONTINUE), ICHAIN_F32(uncullZoneDownward, 1200, ICHAIN_STOP), }; -#endif +typedef enum { + /* 0 */ OBJMURE_TYPE_GRASS, + /* 1 */ OBJMURE_TYPE_UNDEFINED, + /* 2 */ OBJMURE_TYPE_FISH, + /* 3 */ OBJMURE_TYPE_BUGS, + /* 4 */ OBJMURE_TYPE_BUTTERFLY, + /* 5 */ OBJMURE_TYPE_MAX +} ObjMureType; -extern InitChainEntry D_808D87BC[]; +typedef enum { + /* 0 */ OBJMURE_CHILD_STATE_0, + /* 1 */ OBJMURE_CHILD_STATE_DEAD, + /* 2 */ OBJMURE_CHILD_STATE_2 +} ObjMureChildState; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D78D0.s") +s32 func_808D78D0(ObjMure* this, GlobalContext* globalCtx) { + if (this->type == OBJMURE_TYPE_FISH || this->type == OBJMURE_TYPE_BUGS || this->type == OBJMURE_TYPE_BUTTERFLY) { + Actor_ProcessInitChain(&this->actor, sInitChain); + } else { + return false; + } + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D7928.s") +s32 func_808D7928(ObjMure* this, GlobalContext* globalCtx) { + if (!func_808D78D0(this, globalCtx)) { + return false; + } + return true; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/ObjMure_Init.s") +void ObjMure_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjMure* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/ObjMure_Destroy.s") + this->chNum = OBJ_MURE_GET_CHNUM(this->actor.params); + this->ptn = OBJ_MURE_GET_PTN(this->actor.params); + this->svNum = OBJ_MURE_GET_SVNUM(this->actor.params); + this->type = OBJ_MURE_GET_TYPE(this->actor.params); + if (this->ptn >= 4) { + Actor_MarkForDeath(&this->actor); + return; + } + if (this->type >= OBJMURE_TYPE_MAX) { + Actor_MarkForDeath(&this->actor); + return; + } + if (!func_808D7928(this, globalCtx)) { + Actor_MarkForDeath(&this->actor); + return; + } + this->actionFunc = ObjMure_InitialAction; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D7A14.s") +void ObjMure_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D7A40.s") +s32 ObjMure_GetMaxChildSpawns(ObjMure* this) { + if (this->chNum == 0) { + return sMaxChildSpawns[this->ptn]; + } + return this->chNum; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D7A68.s") +void ObjMure_GetSpawnPos(Vec3f* outPos, Vec3f* inPos, s32 ptn, s32 idx) { + *outPos = *inPos; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D7C64.s") +void ObjMure_SpawnActors0(Actor* thisx, GlobalContext* globalCtx) { + ObjMure* this = THIS; + s32 i; + Vec3f pos; + s32 pad; + s32 maxChildren = ObjMure_GetMaxChildSpawns(this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D7DC4.s") + for (i = 0; i < maxChildren; i++) { + switch (this->childrenStates[i]) { + case OBJMURE_CHILD_STATE_DEAD: + break; + case OBJMURE_CHILD_STATE_2: + ObjMure_GetSpawnPos(&pos, &this->actor.world.pos, this->ptn, i); + this->children[i] = Actor_SpawnAsChildAndCutscene( + &globalCtx->actorCtx, globalCtx, sSpawnActorIds[this->type], pos.x, pos.y, pos.z, + this->actor.world.rot.x, this->actor.world.rot.y, this->actor.world.rot.z, sSpawnParams[this->type], + this->actor.cutscene, this->actor.unk20, NULL); + if (this->children[i] != NULL) { + if (this->type == 0x90) { + ((ObjMureChild*)this->children[i])->unk_197 = 1; + } + this->children[i]->room = this->actor.room; + } + break; + default: + ObjMure_GetSpawnPos(&pos, &this->actor.world.pos, this->ptn, i); + this->children[i] = Actor_SpawnAsChildAndCutscene( + &globalCtx->actorCtx, globalCtx, sSpawnActorIds[this->type], pos.x, pos.y, pos.z, + this->actor.world.rot.x, this->actor.world.rot.y, this->actor.world.rot.z, sSpawnParams[this->type], + this->actor.cutscene, this->actor.unk20, NULL); + if (this->children[i] != NULL) { + this->children[i]->room = this->actor.room; + } + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D7E14.s") +void ObjMure_SpawnActors1(ObjMure* this, GlobalContext* globalCtx) { + GlobalContext* globalCtx2 = globalCtx; + Actor* actor = &this->actor; + Vec3f spawnPos; + s32 maxChildren = ObjMure_GetMaxChildSpawns(this); + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D7F0C.s") + for (i = 0; i < maxChildren; i++) { + ObjMure_GetSpawnPos(&spawnPos, &actor->world.pos, this->ptn, i); + this->children[i] = Actor_SpawnAsChildAndCutscene( + &globalCtx->actorCtx, globalCtx, sSpawnActorIds[this->type], spawnPos.x, spawnPos.y, spawnPos.z, + actor->world.rot.x, actor->world.rot.y, actor->world.rot.z, + (this->type == OBJMURE_TYPE_BUTTERFLY && i == 0) ? 1 : sSpawnParams[this->type], this->actor.cutscene, + this->actor.unk20, NULL); + if (this->children[i] != NULL) { + this->childrenStates[i] = OBJMURE_CHILD_STATE_0; + this->children[i]->room = actor->room; + } else { + this->childrenStates[i] = OBJMURE_CHILD_STATE_DEAD; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D7F2C.s") +void ObjMure_SpawnActors(ObjMure* this, GlobalContext* globalCtx) { + switch (this->svNum) { + case 0: + ObjMure_SpawnActors0(&this->actor, globalCtx); + break; + case 1: + ObjMure_SpawnActors1(this, globalCtx); + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D7FFC.s") +void ObjMure_KillActorsImpl(ObjMure* this, GlobalContext* globalCtx) { + s32 maxChildren = ObjMure_GetMaxChildSpawns(this); + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D8014.s") + for (i = 0; i < maxChildren; i++) { + switch (this->childrenStates[i]) { + case OBJMURE_CHILD_STATE_DEAD: + this->children[i] = NULL; + break; + case OBJMURE_CHILD_STATE_2: + if (this->children[i] != NULL) { + Actor_MarkForDeath(this->children[i]); + this->children[i] = NULL; + } + break; + default: + if (this->children[i] != NULL) { + if (Actor_HasParent(this->children[i], globalCtx)) { + this->children[i] = NULL; + } else { + Actor_MarkForDeath(this->children[i]); + this->children[i] = NULL; + } + } + break; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D8074.s") +void ObjMure_KillActors(ObjMure* this, GlobalContext* globalCtx) { + ObjMure_KillActorsImpl(this, globalCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D814C.s") +void ObjMure_CheckChildren(ObjMure* this, GlobalContext* globalCtx) { + s32 maxChildren = ObjMure_GetMaxChildSpawns(this); + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D82CC.s") + for (i = 0; i < maxChildren; i++) { + if (this->children[i] != NULL) { + if (this->childrenStates[i] == OBJMURE_CHILD_STATE_0) { + if (this->children[i]->update != NULL) { + if ((this->type == 0x90) && (((ObjMureChild*)this->children[i])->unk_197 != 0)) { + this->childrenStates[i] = OBJMURE_CHILD_STATE_2; + } + } else { + this->childrenStates[i] = OBJMURE_CHILD_STATE_DEAD; + this->children[i] = NULL; + } + } else if (this->childrenStates[i] == OBJMURE_CHILD_STATE_2 && this->children[i]->update == NULL) { + this->childrenStates[i] = OBJMURE_CHILD_STATE_DEAD; + this->children[i] = NULL; + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D84F4.s") +void ObjMure_InitialAction(ObjMure* this, GlobalContext* globalCtx) { + this->actionFunc = ObjMure_CulledState; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/func_808D8678.s") +void ObjMure_CulledState(ObjMure* this, GlobalContext* globalCtx) { + if (fabsf(this->actor.projectedPos.z) < sZClip[this->type]) { + this->actionFunc = ObjMure_ActiveState; + this->actor.flags |= 0x10; + ObjMure_SpawnActors(this, globalCtx); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Mure/ObjMure_Update.s") +void ObjMure_SetFollowTargets(ObjMure* this, f32 randMax) { + s32 index; + s32 maxChildren = ObjMure_GetMaxChildSpawns(this); + s32 i; + + for (i = 0; i < maxChildren; i++) { + if (this->children[i] != NULL) { + this->children[i]->child = NULL; + if (Rand_ZeroOne() <= randMax) { + index = Rand_ZeroOne() * (maxChildren - 0.5f); + if (i != index) { + this->children[i]->child = this->children[index]; + } + } + } + } +} + +/** + * Selects a child that will follow after the player + * `idx1` is the index + 1 of the child that will follow the player. If `idx1` is zero, no actor will follow the player + */ +void ObjMure_SetChildToFollowPlayer(ObjMure* this, s32 idx1) { + s32 maxChildren = ObjMure_GetMaxChildSpawns(this); + s32 i; + s32 i2; + s32 j; + + for (i = 0, i2 = 0; i < maxChildren; i++) { + if (this->children[i] != NULL) { + if (i2 < idx1) { + i2++; + this->children[i]->child = this->children[i]; + for (j = 0; j < maxChildren; j++) { + if (i != j && this->children[j]->child == this->children[i]) { + this->children[j]->child = NULL; + } + } + } else if (this->children[i]->child == this->children[i]) { + this->children[i]->child = NULL; + } + } + } +} + +// Fish, Bugs +void ObjMure_GroupBehavior0(ObjMure* this, GlobalContext* globalCtx) { + if (this->unk_19C <= 0) { + if (this->unk_19E) { + this->unk_19E = false; + ObjMure_SetFollowTargets(this, (Rand_ZeroOne() * 0.5f) + 0.1f); + if (this->actor.xzDistToPlayer < 60.0f) { + this->unk_19C = (s32)(Rand_ZeroOne() * 5.5f) + 4; + } else { + this->unk_19C = (s32)(Rand_ZeroOne() * 40.5f) + 4; + } + } else { + this->unk_19E = true; + if (this->actor.xzDistToPlayer < 60.0f) { + this->unk_19C = (s32)(Rand_ZeroOne() * 10.5f) + 4; + ObjMure_SetFollowTargets(this, (Rand_ZeroOne() * 0.2f) + 0.8f); + } else { + this->unk_19C = (s32)(Rand_ZeroOne() * 10.5f) + 4; + ObjMure_SetFollowTargets(this, (Rand_ZeroOne() * 0.2f) + 0.6f); + } + } + } + if (this->actor.xzDistToPlayer < 120.0f) { + this->unk_1A0++; + } else { + this->unk_1A0 = 0; + } + if (this->unk_1A0 >= 80) { + ObjMure_SetChildToFollowPlayer(this, 1); + } else { + ObjMure_SetChildToFollowPlayer(this, 0); + } +} + +// Butterflies +void ObjMure_GroupBehavior1(ObjMure* this, GlobalContext* globalCtx) { + s32 maxChildren; + s32 i; + + if (this->unk_19C <= 0) { + if (this->unk_19E) { + this->unk_19E = false; + ObjMure_SetFollowTargets(this, Rand_ZeroOne() * 0.2f); + if (this->actor.xzDistToPlayer < 60.0f) { + this->unk_19C = (s32)(Rand_ZeroOne() * 5.5f) + 4; + } else { + this->unk_19C = (s32)(Rand_ZeroOne() * 40.5f) + 4; + } + } else { + this->unk_19E = true; + ObjMure_SetFollowTargets(this, Rand_ZeroOne() * 0.7f); + this->unk_19C = (s32)(Rand_ZeroOne() * 10.5f) + 4; + } + } + + maxChildren = ObjMure_GetMaxChildSpawns(this); + for (i = 0; i < maxChildren; i++) { + if (this->children[i] != NULL) { + if (this->children[i]->child != NULL && this->children[i]->child->update == NULL) { + this->children[i]->child = NULL; + } + } + } +} + +static ObjMureActionFunc sTypeGroupBehaviorFunc[] = { + NULL, NULL, ObjMure_GroupBehavior0, ObjMure_GroupBehavior0, ObjMure_GroupBehavior1, +}; + +void ObjMure_ActiveState(ObjMure* this, GlobalContext* globalCtx) { + ObjMure_CheckChildren(this, globalCtx); + if (sZClip[this->type] + 40.0f <= fabsf(this->actor.projectedPos.z)) { + this->actionFunc = ObjMure_CulledState; + this->actor.flags &= ~0x10; + ObjMure_KillActors(this, globalCtx); + } else if (sTypeGroupBehaviorFunc[this->type] != NULL) { + sTypeGroupBehaviorFunc[this->type](this, globalCtx); + } +} + +void ObjMure_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjMure* this = THIS; + + if (this->unk_19C > 0) { + this->unk_19C--; + } + this->actionFunc(this, globalCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Mure/z_obj_mure.h b/src/overlays/actors/ovl_Obj_Mure/z_obj_mure.h index dfb6e10c7..1cb9a653a 100644 --- a/src/overlays/actors/ovl_Obj_Mure/z_obj_mure.h +++ b/src/overlays/actors/ovl_Obj_Mure/z_obj_mure.h @@ -7,12 +7,33 @@ struct ObjMure; typedef void (*ObjMureActionFunc)(struct ObjMure*, GlobalContext*); +#define OBJMURE_MAX_SPAWNS 15 + +typedef struct { + Actor actor; + /* 0x144 */ char unk_144[0x53]; + /* 0x197 */ u8 unk_197; +} ObjMureChild; + typedef struct ObjMure { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjMureActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x5C]; + /* 0x0148 */ s16 chNum; + /* 0x014A */ s16 ptn; + /* 0x014C */ s16 svNum; + /* 0x014E */ s16 type; + /* 0x0150 */ Actor* children[OBJMURE_MAX_SPAWNS]; + /* 0x018C */ u8 childrenStates[OBJMURE_MAX_SPAWNS]; + /* 0x019C */ s16 unk_19C; + /* 0x019E */ s16 unk_19E; + /* 0x01A0 */ s16 unk_1A0; } ObjMure; // size = 0x1A4 extern const ActorInit Obj_Mure_InitVars; +#define OBJ_MURE_GET_CHNUM(params) ((params >> 12) & 0xF) +#define OBJ_MURE_GET_PTN(params) ((params >> 8) & 0x7) +#define OBJ_MURE_GET_SVNUM(params) ((params >> 5) & 0x3) +#define OBJ_MURE_GET_TYPE(params) (params & 0x1F) + #endif // Z_OBJ_MURE_H diff --git a/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.h b/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.h index 4ee73ecbe..b306e2552 100644 --- a/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.h +++ b/src/overlays/actors/ovl_Obj_Mure2/z_obj_mure2.h @@ -10,7 +10,7 @@ typedef void (*ObjMure2ActionFunc)(struct ObjMure2*, GlobalContext*); typedef struct ObjMure2 { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjMure2ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x38]; + /* 0x0148 */ char unk_148[0x38]; } ObjMure2; // size = 0x180 extern const ActorInit Obj_Mure2_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Mure3/z_obj_mure3.h b/src/overlays/actors/ovl_Obj_Mure3/z_obj_mure3.h index c000b1e6f..67252a147 100644 --- a/src/overlays/actors/ovl_Obj_Mure3/z_obj_mure3.h +++ b/src/overlays/actors/ovl_Obj_Mure3/z_obj_mure3.h @@ -10,7 +10,7 @@ typedef void (*ObjMure3ActionFunc)(struct ObjMure3*, GlobalContext*); typedef struct ObjMure3 { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjMure3ActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x20]; + /* 0x0148 */ char unk_148[0x20]; } ObjMure3; // size = 0x168 extern const ActorInit Obj_Mure3_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Ocarinalift/z_obj_ocarinalift.c b/src/overlays/actors/ovl_Obj_Ocarinalift/z_obj_ocarinalift.c index fe7d90062..66dbd49fb 100644 --- a/src/overlays/actors/ovl_Obj_Ocarinalift/z_obj_ocarinalift.c +++ b/src/overlays/actors/ovl_Obj_Ocarinalift/z_obj_ocarinalift.c @@ -1,7 +1,7 @@ /* * File: z_obj_ocarinalift.c * Overlay: ovl_Obj_Ocarinalift - * Description: Elevator With Triforce Texture + * Description: Elevator With Triforce Texture (unused?) */ #include "z_obj_ocarinalift.h" diff --git a/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c b/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c index e398d3336..01e13e95c 100644 --- a/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c +++ b/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.c @@ -18,7 +18,6 @@ void func_80973CD8(ObjRoomtimer* this, GlobalContext* globalCtx); void func_80973D3C(ObjRoomtimer* this, GlobalContext* globalCtx); void func_80973DE0(ObjRoomtimer* this, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Roomtimer_InitVars = { ACTOR_OBJ_ROOMTIMER, ACTORCAT_ENEMY, @@ -31,16 +30,64 @@ const ActorInit Obj_Roomtimer_InitVars = { (ActorFunc)NULL, }; -#endif +void ObjRoomtimer_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjRoomtimer* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Roomtimer/ObjRoomtimer_Init.s") + this->switchFlag = ROOMTIMER_GET_SWITCHFLAG(thisx); + this->actor.params &= 0x1FF; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Roomtimer/ObjRoomtimer_Destroy.s") + if (this->actor.params != 0x1FF) { + this->actor.params = CLAMP_MAX(this->actor.params, 500); + } + this->actionFunc = func_80973CD8; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Roomtimer/func_80973CD8.s") +void ObjRoomtimer_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjRoomtimer* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Roomtimer/func_80973D3C.s") + if (this->actor.params != 0x1FF && gSaveContext.unk_3DD0[4] > 0) { + gSaveContext.unk_3DD0[4] = 5; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Roomtimer/func_80973DE0.s") +void func_80973CD8(ObjRoomtimer* this, GlobalContext* globalCtx) { + if (this->actor.params != 0x1FF) { + func_8010E9F0(4, this->actor.params); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Roomtimer/ObjRoomtimer_Update.s") + func_800BC154(globalCtx, &globalCtx->actorCtx, &this->actor, ACTORCAT_PROP); + this->actionFunc = func_80973D3C; +} + +void func_80973D3C(ObjRoomtimer* this, GlobalContext* globalCtx) { + if (Actor_GetRoomClearedTemp(globalCtx, this->actor.room)) { + if (this->actor.params != 0x1FF) { + gSaveContext.unk_3DD0[4] = 5; + } + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + this->actionFunc = func_80973DE0; + } else if (this->actor.params != 0x1FF && gSaveContext.unk_3DD0[4] == 0) { + play_sound(NA_SE_OC_ABYSS); + func_80169EFC(globalCtx); + Actor_MarkForDeath(&this->actor); + } +} + +void func_80973DE0(ObjRoomtimer* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + Actor_SetRoomCleared(globalCtx, this->actor.room); + Actor_SetSwitchFlag(globalCtx, this->switchFlag); + if (ActorCutscene_GetLength(this->actor.cutscene) != -1) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + } + Actor_MarkForDeath(&this->actor); + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } +} + +void ObjRoomtimer_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjRoomtimer* this = THIS; + + this->actionFunc(this, globalCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.h b/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.h index 0a98759d0..b58d5da49 100644 --- a/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.h +++ b/src/overlays/actors/ovl_Obj_Roomtimer/z_obj_roomtimer.h @@ -3,6 +3,8 @@ #include "global.h" +#define ROOMTIMER_GET_SWITCHFLAG(thisx) (((thisx)->params >> 9) & 0x7F) + struct ObjRoomtimer; typedef void (*ObjRoomtimerActionFunc)(struct ObjRoomtimer*, GlobalContext*); @@ -10,7 +12,7 @@ typedef void (*ObjRoomtimerActionFunc)(struct ObjRoomtimer*, GlobalContext*); typedef struct ObjRoomtimer { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjRoomtimerActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x4]; + /* 0x0148 */ s32 switchFlag; } ObjRoomtimer; // size = 0x14C extern const ActorInit Obj_Roomtimer_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Shutter/z_obj_shutter.c b/src/overlays/actors/ovl_Obj_Shutter/z_obj_shutter.c index 80cad625f..61bc5570c 100644 --- a/src/overlays/actors/ovl_Obj_Shutter/z_obj_shutter.c +++ b/src/overlays/actors/ovl_Obj_Shutter/z_obj_shutter.c @@ -1,7 +1,7 @@ /* * File: z_obj_shutter.c * Overlay: ovl_Obj_Shutter - * Description: + * Description: Unused West Clock Town bank closing shutter */ #include "z_obj_shutter.h" diff --git a/src/overlays/actors/ovl_Obj_Snowball/z_obj_snowball.c b/src/overlays/actors/ovl_Obj_Snowball/z_obj_snowball.c index 42cec6623..088e881ed 100644 --- a/src/overlays/actors/ovl_Obj_Snowball/z_obj_snowball.c +++ b/src/overlays/actors/ovl_Obj_Snowball/z_obj_snowball.c @@ -5,6 +5,8 @@ */ #include "z_obj_snowball.h" +#include "objects/object_goroiwa/object_goroiwa.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x00000000 @@ -15,7 +17,22 @@ void ObjSnowball_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjSnowball_Update(Actor* thisx, GlobalContext* globalCtx); void ObjSnowball_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void func_80B02CD0(ObjSnowball* this, GlobalContext* globalCtx); +void func_80B02D58(ObjSnowball* this, GlobalContext* globalCtx); +void func_80B02DB0(ObjSnowball* this, GlobalContext* globalCtx); +void func_80B02E54(ObjSnowball* this, GlobalContext* globalCtx); +void func_80B04338(ObjSnowball* this, GlobalContext* globalCtx); +void func_80B04350(ObjSnowball* this, GlobalContext* globalCtx); +void func_80B04540(ObjSnowball* this, GlobalContext* globalCtx); +void func_80B0457C(ObjSnowball* this, GlobalContext* globalCtx); +void func_80B04608(ObjSnowball* this, GlobalContext* globalCtx); +void func_80B04648(ObjSnowball* this, GlobalContext* globalCtx); +void func_80B046E4(ObjSnowball* this, GlobalContext* globalCtx); +void func_80B047C0(ObjSnowball* this, GlobalContext* globalCtx); +void func_80B04B48(ObjSnowball* this, GlobalContext* globalCtx); +void func_80B04B60(ObjSnowball* this, GlobalContext* globalCtx); +void func_80B04D34(Actor* thisx, GlobalContext* globalCtx); + const ActorInit Obj_Snowball_InitVars = { ACTOR_OBJ_SNOWBALL, ACTORCAT_PROP, @@ -28,80 +45,799 @@ const ActorInit Obj_Snowball_InitVars = { (ActorFunc)ObjSnowball_Draw, }; -// static ColliderJntSphElementInit sJntSphElementsInit[1] = { -static ColliderJntSphElementInit D_80B04F50[1] = { +static ColliderJntSphElementInit sJntSphElementsInit[1] = { { - { ELEMTYPE_UNK0, { 0x00000000, 0x00, 0x00 }, { 0x81837FBE, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, + { + ELEMTYPE_UNK0, + { 0x00000000, 0x00, 0x00 }, + { 0x81837FBE, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 0, { { 0, 0, 0 }, 73 }, 100 }, }, }; -// static ColliderJntSphInit sJntSphInit = { -static ColliderJntSphInit D_80B04F74 = { - { COLTYPE_NONE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_2, COLSHAPE_JNTSPH, }, - 1, D_80B04F50, // sJntSphElementsInit, +static ColliderJntSphInit sJntSphInit = { + { + COLTYPE_NONE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_2, + COLSHAPE_JNTSPH, + }, + 1, + sJntSphElementsInit, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80B04FD4[] = { +typedef struct { + /* 0x00 */ s16 unk_00; + /* 0x02 */ s16 unk_02; + /* 0x04 */ ObjSnowballActionFunc unk_04; +} ObjSnowballStruct2; + +static ObjSnowballStruct2 D_80B04F84[] = { + { -1, 0, func_80B02D58 }, + { ACTOR_EN_JG, 0, func_80B02DB0 }, + { ACTOR_EN_WF, 1, func_80B02E54 }, + { ACTOR_EN_TITE, -4, func_80B02CD0 }, + { ACTOR_EN_KAME, 0, func_80B02CD0 }, + { -1, 0, NULL }, +}; + +static Color_RGBA8 D_80B04FB4 = { 250, 250, 250, 255 }; +static Color_RGBA8 D_80B04FB8 = { 180, 180, 180, 255 }; +static Vec3f D_80B04FBC = { 0.0f, 0.3f, 0.0f }; + +static Gfx* D_80B04FC8[] = { + object_goroiwa_DL_0072F0, + object_goroiwa_DL_0077D0, + object_goroiwa_DL_007C60, +}; + +static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 2000, ICHAIN_STOP), }; +void func_80B02CD0(ObjSnowball* this, GlobalContext* globalCtx) { + ObjSnowballStruct2* ptr = &D_80B04F84[this->actor.home.rot.y]; + + Actor_SpawnAsChildAndCutscene(&globalCtx->actorCtx, globalCtx, ptr->unk_00, this->actor.home.pos.x, + this->actor.home.pos.y, this->actor.home.pos.z, this->actor.home.rot.x, 0, + this->actor.home.rot.z, ptr->unk_02, -1, this->actor.unk20, NULL); +} + +void func_80B02D58(ObjSnowball* this, GlobalContext* globalCtx) { + s32 temp_v0 = func_800A8150(OBJSNOWBALL_GET_3F(&this->actor)); + + if (temp_v0 >= 0) { + Item_DropCollectible(globalCtx, &this->actor.home.pos, (OBJSNOWBALL_GET_7F00(&this->actor) << 8) | temp_v0); + } +} + +void func_80B02DB0(ObjSnowball* this, GlobalContext* globalCtx) { + s32 pad; + ObjSnowballStruct2* ptr = &D_80B04F84[this->actor.home.rot.y]; + + Actor_SpawnAsChildAndCutscene(&globalCtx->actorCtx, globalCtx, ptr->unk_00, this->actor.home.pos.x, + this->actor.home.pos.y, this->actor.home.pos.z, this->actor.home.rot.x, 0, + this->actor.home.rot.z, this->actor.params | ptr->unk_02, + ActorCutscene_GetAdditionalCutscene(this->actor.cutscene), this->actor.unk20, NULL); +} + +void func_80B02E54(ObjSnowball* this, GlobalContext* globalCtx) { + ObjSnowballStruct2* ptr = &D_80B04F84[this->actor.home.rot.y]; + + Actor_SpawnAsChildAndCutscene(&globalCtx->actorCtx, globalCtx, ptr->unk_00, this->actor.home.pos.x, + this->actor.home.pos.y, this->actor.home.pos.z, this->actor.home.rot.x, 0, + this->actor.home.rot.z, this->actor.params | ptr->unk_02, -1, this->actor.unk20, + NULL); +} + +void func_80B02EE4(ObjSnowball* this, GlobalContext* globalCtx) { + Vec3f spAC; + Vec3f spA0; + Vec3f sp94; + Vec3s* hitPos = &this->collider.elements->info.bumper.hitPos; + s32 i; + + for (i = 0; i < 4; i++) { + sp94.x = ((Rand_ZeroOne() * 14.0f) - 7.0f) + hitPos->x; + sp94.y = ((Rand_ZeroOne() * 14.0f) - 7.0f) + hitPos->y; + sp94.z = ((Rand_ZeroOne() * 14.0f) - 7.0f) + hitPos->z; + + spA0.x = (Rand_ZeroOne() - 0.5f) * 1.6f; + spA0.y = -0.8f; + spA0.z = (Rand_ZeroOne() - 0.5f) * 1.6f; + + spAC.x = spA0.x * -0.06f; + spAC.y = spA0.y * -0.06f; + spAC.z = spA0.z * -0.06f; + + func_800B0E48(globalCtx, &sp94, &spA0, &spAC, &D_80B04FB4, &D_80B04FB8, (s32)(Rand_ZeroOne() * 30.0f) + 15, + (s32)(Rand_ZeroOne() * 40.0f) + 30); + } +} + +void func_80B030F8(ObjSnowball* this, GlobalContext* globalCtx) { + s32 pad; + f32 temp_f28 = sqrtf(this->unk_20C); + Vec3f spFC; + Vec3f spF0; + Vec3f spE4; + s32 i; + s32 phi_s6; + Gfx* temp_s2; + s16 scale; + s32 temp_s1; + f32 temp_f20; + f32 temp_f22; + f32 temp_f26; + s16 temp_s0; + s32 temp_s7; + f32 phi_f22; + s32 gravity; + s32 phi_s0; + s32 phi_s4; + + for (i = 0, phi_s6 = 0; i < 25; i++, phi_s6 += 0xA3D) { + temp_s7 = i & 7; + if (temp_s7 < 4) { + temp_s2 = D_80B04FC8[2]; + gravity = -280; + phi_s4 = 0; + phi_s0 = 0x40; + phi_f22 = 1.0f; + } else if (temp_s7 < 6) { + temp_s2 = D_80B04FC8[1]; + gravity = -340; + phi_s4 = 0; + phi_f22 = 0.9f; + if (Rand_ZeroOne() < 0.4f) { + phi_s0 = 0x20; + } else { + phi_s0 = 0x40; + } + } else { + temp_s2 = D_80B04FC8[0]; + gravity = -400; + phi_s4 = 1; + phi_f22 = 0.8f; + if (Rand_Next() > 0) { + phi_s0 = 0x21; + } else { + phi_s0 = 0x41; + } + } + + temp_f20 = (Rand_ZeroOne() * (40.0f * this->unk_20C)) + 20.0f; + + spFC.x = Math_SinS((s32)(Rand_ZeroOne() * 2621.44f) + phi_s6) * temp_f20; + spFC.y = (Rand_ZeroOne() - 0.4f) * temp_f20 * 1.6666666f; + spFC.z = Math_CosS((s32)(Rand_ZeroOne() * 2621.44f) + phi_s6) * temp_f20; + + spF0.x = spFC.x * 0.16f * phi_f22; + spF0.y = (Rand_ZeroOne() * 16.0f) + 3.0f; + spF0.z = spFC.z * 0.16f * phi_f22; + + spFC.x += this->actor.world.pos.x; + spFC.y += this->actor.world.pos.y; + spFC.z += this->actor.world.pos.z; + + scale = ((Rand_ZeroOne() * 15.0f) + 30.0f) * this->unk_20C; + + EffectSsKakera_Spawn(globalCtx, &spFC, &spF0, &spFC, gravity, phi_s0, 30, 0, 0, scale, phi_s4, 0, 50, -1, 0xEF, + temp_s2); + if ((this->unk_210 == 0) && (temp_s7 >= 3)) { + spFC.x += (Rand_ZeroOne() * 120.0f) - 60.0f; + spFC.y += Rand_ZeroOne() * 80.0f; + spFC.z += (Rand_ZeroOne() * 120.0f) - 60.0f; + + temp_s0 = (s32)(Rand_ZeroOne() * 50.0f * temp_f28) + 40; + temp_s1 = (s32)(Rand_ZeroOne() * 60.0f * temp_f28) + 50; + func_800B0E48(globalCtx, &spFC, &gZeroVec3f, &D_80B04FBC, &D_80B04FB4, &D_80B04FB8, temp_s0, temp_s1); + } + } + + if (this->unk_210 != 0) { + temp_f26 = this->unk_20C * 60.0f; + + for (i = 0, phi_s6 = 0; i < 16; i++, phi_s6 += 0x1000) { + temp_s0 = (u32)Rand_Next() >> 0x10; + temp_f20 = Math_SinS(temp_s0); + temp_f22 = Math_CosS(temp_s0); + + spFC.x = Math_SinS(phi_s6); + spFC.z = Math_CosS(phi_s6); + + spF0.x = 2.0f * spFC.x; + spF0.y = (2.0f * Rand_ZeroOne()) + 1.0f; + spF0.z = 2.0f * spFC.z; + + spFC.x *= temp_f22 * temp_f26; + spFC.y = temp_f20 * temp_f26; + spFC.z *= temp_f22 * temp_f26; + + spFC.x += this->actor.world.pos.x; + spFC.y += this->actor.world.pos.y; + spFC.z += this->actor.world.pos.z; + + spE4.x = spF0.x * -0.02f; + spE4.y = spF0.y * -0.05f; + spE4.z = spF0.z * -0.02f; + + EffectSsIceSmoke_Spawn(globalCtx, &spFC, &spF0, &spE4, ((s32)(Rand_ZeroOne() * 170.0f) + 150) * temp_f28); + } + } +} + +void func_80B03688(ObjSnowball* this, GlobalContext* globalCtx) { + s32 i; + Vec3f spB8; + Vec3f spAC; + Vec3f spA0; + s32 pad[2]; + f32 temp_f20; + f32 temp_f22 = sqrtf(this->unk_20C); + s16 temp_s3; + s32 phi_s0; + + if (this->unk_210 == 0) { + for (i = 0, phi_s0 = 0; i < 10; i++, phi_s0 += 0x1999) { + temp_f20 = (Rand_ZeroOne() * (45.0f * this->unk_20C)) + 50.0f; + + spB8.x = Math_SinS((s32)(Rand_ZeroOne() * 6553.6f) + phi_s0) * temp_f20; + spB8.y = Rand_ZeroOne() * 20.0f; + spB8.z = Math_CosS((s32)(Rand_ZeroOne() * 6553.6f) + phi_s0) * temp_f20; + + spAC.x = spB8.x * 0.06f; + spAC.y = 0.0f; + spAC.z = spB8.z * 0.06f; + + spA0.x = spAC.x * -0.08f; + spA0.y = 0.3f; + spA0.z = spAC.z * -0.08f; + + spB8.x += this->actor.home.pos.x; + spB8.y += this->actor.home.pos.y; + spB8.z += this->actor.home.pos.z; + + temp_s3 = (s32)(Rand_ZeroOne() * 60.0f * temp_f22) + 70; + + func_800B0E48(globalCtx, &spB8, &spAC, &spA0, &D_80B04FB4, &D_80B04FB8, temp_s3, + (s32)(Rand_ZeroOne() * 70.0f * temp_f22) + 70); + } + } else { + for (i = 0, phi_s0 = 0; i < 18; i++, phi_s0 += 0xE38) { + temp_f20 = (Rand_ZeroOne() * (45.0f * this->unk_20C)) + 50.0f; + + spB8.x = Math_SinS((s32)(Rand_ZeroOne() * 3640.889f) + phi_s0); + spB8.z = Math_CosS((s32)(Rand_ZeroOne() * 3640.889f) + phi_s0); + + spAC.x = spB8.x * 3.0f * temp_f22; + spAC.y = 0.0f; + spAC.z = spB8.z * 3.0f * temp_f22; + + spA0.x = spAC.x * -0.02f; + spA0.y = 0.03f; + spA0.z = spAC.z * -0.02f; + + spB8.x = (spB8.x * temp_f20) + this->actor.home.pos.x; + spB8.y = (Rand_ZeroOne() * 20.0f) + this->actor.home.pos.y; + spB8.z = (spB8.z * temp_f20) + this->actor.home.pos.z; + + EffectSsIceSmoke_Spawn(globalCtx, &spB8, &spAC, &spA0, (s32)(Rand_ZeroOne() * 140.0f * temp_f22) + 100); + } + } +} + +#ifdef NON_MATCHING +void func_80B03A80(GlobalContext* globalCtx, f32 arg1, Vec3f* arg2) { + f32 temp_f30 = sqrtf(arg1); + Vec3f spD8; + Vec3f spCC; + s32 i; + Gfx* temp_s1; + f32 temp_f20; + s32 phi_s5; + s32 pad; + s16 phi_s2; + s32 pad2; + s16 phi_s0; + s16 phi_s3; + + for (i = 0, phi_s5 = 0; i < 13; i++, phi_s5 += 0x1999) { + temp_f20 = (Rand_ZeroOne() * (40.0f * arg1)) + 20.0f; + + spD8.x = Math_SinS((s32)(Rand_ZeroOne() * 6553.6f) + phi_s5) * temp_f20; + spD8.y = Rand_ZeroOne() * temp_f20; + spD8.z = Math_CosS((s32)(Rand_ZeroOne() * 6553.6f) + phi_s5) * temp_f20; + + spCC.x = spD8.x * 0.17f; + spCC.y = (Rand_ZeroOne() * 14.0f) + 3.0f; + spCC.z = spD8.z * 0.17f; + + spD8.x += arg2->x; + spD8.y += arg2->y; + spD8.z += arg2->z; + + if ((i & 3) == 0) { + temp_s1 = D_80B04FC8[0]; + phi_s2 = -400; + phi_s3 = 1; + if (Rand_Next() > 0) { + phi_s0 = 0x21; + } else { + phi_s0 = 0x41; + } + } else if ((i & 3) == 1) { + temp_s1 = D_80B04FC8[1]; + phi_s2 = -340; + phi_s3 = 1; + if (Rand_Next() > 0) { + phi_s0 = 0x21; + } else { + phi_s0 = 0x41; + } + } else { + temp_s1 = D_80B04FC8[2]; + phi_s2 = -280; + phi_s3 = 0; + phi_s0 = 0x40; + } + + EffectSsKakera_Spawn(globalCtx, &spD8, &spCC, &spD8, phi_s2, phi_s0, 30, 0, 0, + ((Rand_ZeroOne() * 15.0f) + 25.0f) * arg1, phi_s3, 0, 0x36, -1, 0xEF, temp_s1); + + spD8.x += (Rand_ZeroOne() * 80.0f) - 40.0f; + spD8.y += Rand_ZeroOne() * 55.0f; + spD8.z += (Rand_ZeroOne() * 80.0f) - 40.0f; + + phi_s0 = (s32)(Rand_ZeroOne() * 60.0f * temp_f30) + 60; + + func_800B0E48(globalCtx, &spD8, &gZeroVec3f, &D_80B04FBC, &D_80B04FB4, &D_80B04FB8, phi_s0, + (s32)(Rand_ZeroOne() * 30.0f * temp_f30) + 60); + } +} +#else +void func_80B03A80(GlobalContext* globalCtx, f32 arg1, Vec3f* arg2); +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B03A80.s") #endif -extern ColliderJntSphElementInit D_80B04F50[1]; -extern ColliderJntSphInit D_80B04F74; -extern InitChainEntry D_80B04FD4[]; +void func_80B03E2C(ObjSnowball* this, GlobalContext* globalCtx) { + ObjSnowballStruct* ptr; + s32 i; -extern UNK_TYPE D_060082D0; -extern UNK_TYPE D_06008B90; + this->unk_1A8[0].unk_1C.y = this->actor.yawTowardsPlayer - 0x4000; + this->unk_1A8[0].unk_24 = Rand_ZeroOne() * -600.0f; + this->unk_1A8[1].unk_1C.y = this->actor.yawTowardsPlayer + 0x4000; + this->unk_1A8[1].unk_24 = Rand_ZeroOne() * 600.0f; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B02CD0.s") + for (i = 0; i < ARRAY_COUNT(this->unk_1A8); i++) { + ptr = &this->unk_1A8[i]; + ptr->unk_00.x = this->actor.home.pos.x; + ptr->unk_00.y = this->actor.home.pos.y + (61.0f * this->unk_20C); + ptr->unk_00.z = this->actor.home.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B02D58.s") + ptr->unk_0C = Math_SinS(ptr->unk_1C.y) * (Rand_ZeroOne() + 5.0f); + ptr->unk_10 = (Rand_ZeroOne() * 11.0f) + 20.0f; + ptr->unk_14 = Math_CosS(ptr->unk_1C.y) * (Rand_ZeroOne() + 5.0f); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B02DB0.s") + ptr->unk_1C.x = 0; + ptr->unk_1C.z = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B02E54.s") + ptr->unk_22 = (s32)(Rand_ZeroOne() * 400.0f) + 1100; + ptr->unk_26 = Rand_ZeroOne() * -600.0f; + ptr->unk_2D = 0; + ptr->unk_2C = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B02EE4.s") +void func_80B03FF8(ObjSnowball* this, GlobalContext* globalCtx) { + s32 pad; + s16 rotY = this->actor.home.rot.y; + ObjSnowballStruct2* sp18 = &D_80B04F84[rotY]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B030F8.s") + if (sp18->unk_04 != NULL) { + sp18->unk_04(this, globalCtx); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B03688.s") + Audio_PlayActorSound2(&this->actor, NA_SE_EV_SNOWBALL_BROKEN); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B03A80.s") + if (rotY == 5) { + Actor_SetSwitchFlag(globalCtx, OBJSNOWBALL_GET_3F(&this->actor)); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B03E2C.s") +void ObjSnowball_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjSnowball* this = THIS; + Sphere16* sphere; + ColliderJntSphElementDim* elementDim; + Vec3f sp48; + s32 sp44; + s32 sp40 = this->actor.home.rot.y; + f32 phi_f20; + s32 sp34; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B03FF8.s") + Actor_ProcessInitChain(&this->actor, sInitChain); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/ObjSnowball_Init.s") + sp34 = sp40 == 1; + if (sp34) { + phi_f20 = 1.5f; + } else { + phi_f20 = 1.0f; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/ObjSnowball_Destroy.s") + Actor_SetScale(&this->actor, 0.1f * phi_f20); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04338.s") + this->actor.shape.rot.x = 0; + this->actor.shape.rot.z = 0; + this->actor.world.pos.y += 20.0f * phi_f20; + this->actor.uncullZoneScale = 150.0f * phi_f20; + this->actor.uncullZoneDownward = 300.0f * phi_f20; + this->actor.shape.rot.y = (u32)Rand_Next() >> 0x10; + this->unk_20C = phi_f20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04350.s") + if (sp34) { + this->actor.textId = 0x238; + this->actor.flags |= 1; + this->actor.targetArrowOffset = 1400.0f / 3.0f; + Actor_SetHeight(&this->actor, 24.0f); + this->actor.targetMode = 3; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04540.s") + Collider_InitJntSph(globalCtx, &this->collider); + Collider_SetJntSph(globalCtx, &this->collider, &this->actor, &sJntSphInit, this->colliderElements); + this->actor.colChkInfo.mass = MASS_HEAVY; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B0457C.s") + sphere = &this->collider.elements[0].dim.worldSphere; + sphere->center.x = this->actor.world.pos.x; + sphere->center.y = this->actor.world.pos.y; + sphere->center.z = this->actor.world.pos.z; + sphere->radius = + (this->collider.elements[0].dim.scale * this->collider.elements[0].dim.modelSphere.radius) * phi_f20; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04608.s") + sp48.x = this->actor.home.pos.x; + sp48.y = this->actor.home.pos.y + 30.0f; + sp48.z = this->actor.home.pos.z; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04648.s") + this->actor.floorHeight = + BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &this->actor.floorPoly, &sp44, &this->actor, &sp48); + if (this->actor.floorHeight < (this->actor.home.pos.y - 10.0f)) { + this->actor.floorPoly = NULL; + } else { + ActorShape_Init(&this->actor.shape, 0.0f, NULL, 13.0f); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B046E4.s") + func_80B04338(this, globalCtx); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B047C0.s") + if ((sp40 == 5) && Flags_GetSwitch(globalCtx, OBJSNOWBALL_GET_3F(&this->actor))) { + Actor_MarkForDeath(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04B48.s") +void ObjSnowball_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjSnowball* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04B60.s") + Collider_DestroyJntSph(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/ObjSnowball_Update.s") +void func_80B04338(ObjSnowball* this, GlobalContext* globalCtx) { + this->actionFunc = func_80B04350; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/ObjSnowball_Draw.s") +void func_80B04350(ObjSnowball* this, GlobalContext* globalCtx) { + s32 pad; + s32 flag = (this->collider.base.acFlags & AC_HIT) != 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Snowball/func_80B04D34.s") + if (flag) { + this->collider.base.acFlags &= ~AC_HIT; + } + + if (flag && (this->unk_211 == 0) && + (this->collider.elements->info.acHitInfo->toucher.dmgFlags & + (0x80000000 | 0x4000 | 0x800 | 0x400 | 0x100 | 0x8))) { + this->actor.flags |= 0x10; + if (this->actor.home.rot.y == 1) { + this->actor.flags &= ~(8 | 1); + } + + if (this->collider.elements->info.acHitInfo->toucher.dmgFlags & 0x4000) { + this->unk_20A = 1; + } else { + if (this->collider.elements->info.acHitInfo->toucher.dmgFlags & 0x800) { + this->unk_210 = 1; + } + this->unk_20A = 0; + } + + if (this->actor.cutscene < 0) { + func_80B03FF8(this, globalCtx); + if (this->unk_20A == 0) { + func_80B04608(this, globalCtx); + } else { + func_80B046E4(this, globalCtx); + } + } else { + func_80B04540(this, globalCtx); + } + return; + } + + if (flag && + !(this->collider.elements->info.acHitInfo->toucher.dmgFlags & (0x10000 | 0x2000 | 0x1000 | 0x800 | 0x20))) { + if (this->unk_209 <= 0) { + func_80B02EE4(this, globalCtx); + if (this->collider.elements->info.acHitInfo->toucher.dmgFlags & 0x1000000) { + this->unk_209 = 25; + } else { + this->unk_209 = 10; + } + Audio_PlayActorSound2(&this->actor, NA_SE_IT_REFLECTION_SNOW); + } + } + + if (this->unk_209 > 0) { + this->unk_209--; + } + + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); +} + +void func_80B04540(ObjSnowball* this, GlobalContext* globalCtx) { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + this->actionFunc = func_80B0457C; +} + +void func_80B0457C(ObjSnowball* this, GlobalContext* globalCtx) { + if (ActorCutscene_GetCanPlayNext(this->actor.cutscene)) { + ActorCutscene_StartAndSetUnkLinkFields(this->actor.cutscene, &this->actor); + func_80B03FF8(this, globalCtx); + this->unk_20B = 1; + if (this->unk_20A == 0) { + func_80B04608(this, globalCtx); + } else { + func_80B046E4(this, globalCtx); + } + } else { + ActorCutscene_SetIntentToPlay(this->actor.cutscene); + } +} + +void func_80B04608(ObjSnowball* this, GlobalContext* globalCtx) { + func_80B030F8(this, globalCtx); + this->actor.draw = NULL; + this->unk_208 = 50; + this->actor.floorPoly = NULL; + this->actionFunc = func_80B04648; +} + +void func_80B04648(ObjSnowball* this, GlobalContext* globalCtx) { + this->unk_208--; + if (this->unk_208 <= 0) { + if (this->unk_20B != 0) { + ActorCutscene_Stop(this->actor.cutscene); + } + + if (this->actor.home.rot.y == 1) { + func_80B04B48(this, globalCtx); + } else { + Actor_MarkForDeath(&this->actor); + } + } else if (this->unk_208 == 0x2D) { + func_80B03688(this, globalCtx); + } +} + +void func_80B046E4(ObjSnowball* this, GlobalContext* globalCtx) { + Vec3f sp44; + s32 i; + + func_80B03E2C(this, globalCtx); + + for (i = 0; i < ARRAY_COUNT(this->unk_1A8); i++) { + sp44.x = this->unk_1A8[i].unk_00.x; + sp44.y = this->unk_1A8[i].unk_00.y - (60.0f * this->unk_20C); + sp44.z = this->unk_1A8[i].unk_00.z; + func_80B03A80(globalCtx, this->unk_20C, &sp44); + } + + this->actor.draw = func_80B04D34; + this->actor.floorPoly = NULL; + this->unk_208 = 50; + this->actionFunc = func_80B047C0; +} + +void func_80B047C0(ObjSnowball* this, GlobalContext* globalCtx) { + static Vec3f D_80B04FD8 = { 0.0f, 1.0f, 0.0f }; + static Vec3f D_80B04FE4 = { 0.0f, 0.0f, 1.0f }; + s32 pad; + ObjSnowballStruct* ptr; + Vec3f sp9C; + s32 sp98; + s32 i; + Vec3f sp88; + f32 sp84; + f32 phi_f2; + f32 sp7C; + Vec3f sp70; + + for (i = 0; i < ARRAY_COUNT(this->unk_1A8); i++) { + ptr = &this->unk_1A8[i]; + + if (!(ptr->unk_2D & 1)) { + ptr->unk_10 -= 6.0f; + ptr->unk_10 *= 0.96f; + if (ptr->unk_10 < -20.0f) { + ptr->unk_10 = -20.0f; + } + + ptr->unk_00.x += ptr->unk_0C; + ptr->unk_00.y += ptr->unk_10; + ptr->unk_00.z += ptr->unk_14; + + ptr->unk_1C.x += ptr->unk_22; + ptr->unk_1C.y += ptr->unk_24; + ptr->unk_1C.z += ptr->unk_26; + + sp9C.x = ptr->unk_00.x; + sp9C.y = ptr->unk_00.y + 25.0f; + sp9C.z = ptr->unk_00.z; + + ptr->unk_18 = BgCheck_EntityRaycastFloor5(&globalCtx->colCtx, &ptr->unk_28, &sp98, &this->actor, &sp9C); + + if (ptr->unk_10 <= 0.0f) { + Matrix_InsertRotation(ptr->unk_1C.x, ptr->unk_1C.y, ptr->unk_1C.z, MTXMODE_NEW); + Matrix_MultiplyVector3fByState(&D_80B04FE4, &sp88); + + sp84 = this->unk_20C * 60.0f * 0.9f; + if (sp88.y > 0.0f) { + if (Math3D_AngleBetweenVectors(&D_80B04FD8, &sp88, &sp7C)) { + phi_f2 = 1.0f; + } else { + phi_f2 = 1.0f - SQ(sp7C); + } + + if (phi_f2 <= 0.0f) { + sp84 = 0.0f; + } else { + sp84 *= sqrtf(phi_f2); + } + } + + if (((ptr->unk_00.y - sp84) < ptr->unk_18) || (ptr->unk_18 < BGCHECK_Y_MIN + 10.0f)) { + ptr->unk_2D |= 1; + sp70.x = ptr->unk_00.x; + sp70.y = ptr->unk_00.y - sp84; + sp70.z = ptr->unk_00.z; + func_80B03A80(globalCtx, this->unk_20C, &sp70); + } + } + } + } + + this->unk_208--; + + if ((this->unk_208 <= 0) || ((this->unk_1A8[0].unk_2D & 1) && (this->unk_1A8[1].unk_2D & 1))) { + if (this->unk_20B != 0) { + ActorCutscene_Stop(this->actor.cutscene); + } + + if (this->actor.home.rot.y == 1) { + func_80B04B48(this, globalCtx); + } else { + Actor_MarkForDeath(&this->actor); + } + } else { + for (i = 0; i < ARRAY_COUNT(this->unk_1A8); i++) { + ptr = &this->unk_1A8[i]; + + if (ptr->unk_2D & 1) { + ptr->unk_2C = 0; + } else if (ptr->unk_2C < 136) { + ptr->unk_2C += 24; + } else { + ptr->unk_2C = 160; + } + } + } +} + +void func_80B04B48(ObjSnowball* this, GlobalContext* globalCtx) { + this->actionFunc = func_80B04B60; +} + +void func_80B04B60(ObjSnowball* this, GlobalContext* globalCtx) { +} + +void ObjSnowball_Update(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjSnowball* this = THIS; + s32 sp24 = false; + + if (this->actor.home.rot.y == 1) { + if (this->unk_211 != 0) { + if (func_800B867C(&this->actor, globalCtx)) { + this->actor.flags &= ~0x10; + this->unk_211 = 0; + } + } else if (func_800B84D0(&this->actor, globalCtx)) { + this->actor.flags |= 0x10; + this->unk_211 = 1; + } else if (this->actor.isTargeted) { + sp24 = true; + } + } + + this->actionFunc(this, globalCtx); + + if (sp24 && (this->actionFunc == func_80B04350)) { + func_800B8614(&this->actor, globalCtx, 100.0f); + } + + if ((this->actor.floorPoly != NULL) && (this->actor.projectedPos.z < 920.0f)) { + if (this->actor.projectedPos.z > 400.0f) { + this->actor.shape.shadowAlpha = (920 - (s32)this->actor.projectedPos.z) >> 2; + this->actor.shape.shadowDraw = func_800B3FC0; + } else if (this->actor.projectedPos.z > -30.0f) { + this->actor.shape.shadowAlpha = 130; + this->actor.shape.shadowDraw = func_800B3FC0; + } else { + this->actor.shape.shadowDraw = NULL; + } + } else { + this->actor.shape.shadowDraw = NULL; + } +} + +void ObjSnowball_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjSnowball* this = THIS; + + func_800BDFC0(globalCtx, object_goroiwa_DL_008B90); +} + +void func_80B04D34(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjSnowball* this = THIS; + ObjSnowballStruct* ptr; + s32 i; + MtxF sp88; + Vec3s sp80; + + for (i = 0; i < ARRAY_COUNT(this->unk_1A8); i++) { + ptr = &this->unk_1A8[i]; + + if (!(ptr->unk_2D & 1)) { + sp80.x = ptr->unk_1C.x; + sp80.y = ptr->unk_1C.y; + sp80.z = ptr->unk_1C.z; + + Matrix_SetStateRotationAndTranslation(ptr->unk_00.x, ptr->unk_00.y, ptr->unk_00.z, &sp80); + Matrix_Scale(this->actor.scale.x, this->actor.scale.y, this->actor.scale.z, MTXMODE_APPLY); + func_800BDFC0(globalCtx, object_goroiwa_DL_0082D0); + + if ((ptr->unk_28 != NULL) && (ptr->unk_2C > 0)) { + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C448(globalCtx->state.gfxCtx); + + gDPSetCombineLERP(POLY_XLU_DISP++, 0, 0, 0, PRIMITIVE, TEXEL0, 0, PRIMITIVE, 0, 0, 0, 0, COMBINED, 0, 0, + 0, COMBINED); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 0, 0, 0, ptr->unk_2C); + + func_800C0094(ptr->unk_28, ptr->unk_00.x, ptr->unk_18, ptr->unk_00.z, &sp88); + Matrix_SetCurrentState(&sp88); + Matrix_Scale(this->actor.scale.x * 7.5f, 1.0f, this->actor.scale.z * 7.5f, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_076BC0); + + CLOSE_DISPS(globalCtx->state.gfxCtx); + } + } + } +} diff --git a/src/overlays/actors/ovl_Obj_Snowball/z_obj_snowball.h b/src/overlays/actors/ovl_Obj_Snowball/z_obj_snowball.h index fc5aafdde..c6bc03100 100644 --- a/src/overlays/actors/ovl_Obj_Snowball/z_obj_snowball.h +++ b/src/overlays/actors/ovl_Obj_Snowball/z_obj_snowball.h @@ -7,11 +7,37 @@ struct ObjSnowball; typedef void (*ObjSnowballActionFunc)(struct ObjSnowball*, GlobalContext*); +#define OBJSNOWBALL_GET_3F(thisx) ((thisx)->params & 0x3F) +#define OBJSNOWBALL_GET_7F00(thisx) (((thisx)->params >> 8) & 0x7F) + +typedef struct { + /* 0x00 */ Vec3f unk_00; + /* 0x0C */ f32 unk_0C; + /* 0x10 */ f32 unk_10; + /* 0x14 */ f32 unk_14; + /* 0x18 */ f32 unk_18; + /* 0x1C */ Vec3s unk_1C; + /* 0x22 */ s16 unk_22; + /* 0x24 */ s16 unk_24; + /* 0x26 */ s16 unk_26; + /* 0x28 */ CollisionPoly* unk_28; + /* 0x2C */ u8 unk_2C; + /* 0x2D */ u8 unk_2D; +} ObjSnowballStruct; // size = 0x30 + typedef struct ObjSnowball { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x60]; - /* 0x01A4 */ ObjSnowballActionFunc actionFunc; - /* 0x01A8 */ char unk_1A8[0x6C]; + /* 0x000 */ Actor actor; + /* 0x144 */ ColliderJntSph collider; + /* 0x164 */ ColliderJntSphElement colliderElements[1]; + /* 0x1A4 */ ObjSnowballActionFunc actionFunc; + /* 0x1A8 */ ObjSnowballStruct unk_1A8[2]; + /* 0x208 */ s8 unk_208; + /* 0x209 */ s8 unk_209; + /* 0x20A */ s8 unk_20A; + /* 0x20B */ s8 unk_20B; + /* 0x20C */ f32 unk_20C; + /* 0x210 */ s8 unk_210; + /* 0x211 */ s8 unk_211; } ObjSnowball; // size = 0x214 extern const ActorInit Obj_Snowball_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Spinyroll/z_obj_spinyroll.c b/src/overlays/actors/ovl_Obj_Spinyroll/z_obj_spinyroll.c index e0e1c99a4..cf7c48431 100644 --- a/src/overlays/actors/ovl_Obj_Spinyroll/z_obj_spinyroll.c +++ b/src/overlays/actors/ovl_Obj_Spinyroll/z_obj_spinyroll.c @@ -1,7 +1,7 @@ /* * File: z_obj_spinyroll.c * Overlay: ovl_Obj_Spinyroll - * Description: Spike-Covered Log + * Description: Horizontal Spike-Covered Log */ #include "z_obj_spinyroll.h" diff --git a/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.c b/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.c index bc56c60d2..3d94f31b6 100644 --- a/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.c +++ b/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.c @@ -1,7 +1,7 @@ /* * File: z_obj_swprize.c * Overlay: ovl_Obj_Swprize - * Description: Spawner for dirt square prize? + * Description: Spawns item drop from soft soil */ #include "z_obj_swprize.h" diff --git a/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.h b/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.h index 148c8deb6..680417d50 100644 --- a/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.h +++ b/src/overlays/actors/ovl_Obj_Swprize/z_obj_swprize.h @@ -10,7 +10,7 @@ typedef void (*ObjSwprizeActionFunc)(struct ObjSwprize*, GlobalContext*); typedef struct ObjSwprize { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjSwprizeActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x4]; + /* 0x0148 */ char unk_148[0x4]; } ObjSwprize; // size = 0x14C extern const ActorInit Obj_Swprize_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c b/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c index 3eb50153b..b88dc23fa 100644 --- a/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c +++ b/src/overlays/actors/ovl_Obj_Syokudai/z_obj_syokudai.c @@ -5,6 +5,7 @@ */ #include "z_obj_syokudai.h" +#include "objects/gameplay_keep/gameplay_keep.h" #include "overlays/actors/ovl_En_Arrow/z_en_arrow.h" #define FLAGS 0x00000410 @@ -314,7 +315,7 @@ void ObjSyokudai_Draw(Actor* thisx, GlobalContext* globalCtx) { Matrix_RotateY(BINANG_ROT180(func_800DFCDC(GET_ACTIVE_CAM(globalCtx)) - thisx->shape.rot.y), MTXMODE_APPLY); Matrix_Scale(flameScale, flameScale, flameScale, MTXMODE_APPLY); gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(POLY_XLU_DISP++, D_0407D590); + gSPDisplayList(POLY_XLU_DISP++, gGameplayKeepDrawFlameDL); } CLOSE_DISPS(globalCtx->state.gfxCtx); } diff --git a/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.h b/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.h index 0d734b85e..83f267d37 100644 --- a/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.h +++ b/src/overlays/actors/ovl_Obj_Takaraya_Wall/z_obj_takaraya_wall.h @@ -10,7 +10,7 @@ typedef void (*ObjTakarayaWallActionFunc)(struct ObjTakarayaWall*, GlobalContext typedef struct ObjTakarayaWall { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjTakarayaWallActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x98]; + /* 0x0148 */ char unk_148[0x98]; } ObjTakarayaWall; // size = 0x1E0 extern const ActorInit Obj_Takaraya_Wall_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Tokei_Step/z_obj_tokei_step.c b/src/overlays/actors/ovl_Obj_Tokei_Step/z_obj_tokei_step.c index 837c05ae9..f7710909f 100644 --- a/src/overlays/actors/ovl_Obj_Tokei_Step/z_obj_tokei_step.c +++ b/src/overlays/actors/ovl_Obj_Tokei_Step/z_obj_tokei_step.c @@ -5,6 +5,7 @@ */ #include "z_obj_tokei_step.h" +#include "objects/object_tokei_step/object_tokei_step.h" #define FLAGS 0x00400010 @@ -37,11 +38,11 @@ const ActorInit Obj_Tokei_Step_InitVars = { (ActorFunc)ObjTokeiStep_Draw, }; -static f32 panelXOffsets[] = { -105.0f, -90.0f, -75.0f, -60.0f, -45.0f, -30.0f, -15.0f }; +static f32 sPanelXOffsets[] = { -105.0f, -90.0f, -75.0f, -60.0f, -45.0f, -30.0f, -15.0f }; -static f32 dustSpawnXOffsets[] = { -60.0f, -40.0f, -20.0f, 0.0f, 20.0f, 40.0f, 60.0f }; +static f32 sDustSpawnXOffsets[] = { -60.0f, -40.0f, -20.0f, 0.0f, 20.0f, 40.0f, 60.0f }; -static Vec3f dustEffectAccel = { 0.0f, 0.3f, 0.0f }; +static Vec3f sDustEffectAccel = { 0.0f, 0.3f, 0.0f }; static InitChainEntry sInitChain[] = { ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), @@ -50,27 +51,22 @@ static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -extern Gfx D_06000088[]; -extern CollisionHeader D_06000968; - void ObjTokeiStep_SetSysMatrix(ObjTokeiStepPanel* panel) { - MtxF* sysMatrix; + MtxF* mtx = Matrix_GetCurrentState(); - sysMatrix = Matrix_GetCurrentState(); - sysMatrix->wx = panel->pos.x; - sysMatrix->wy = panel->pos.y; - sysMatrix->wz = panel->pos.z; + mtx->wx = panel->pos.x; + mtx->wy = panel->pos.y; + mtx->wz = panel->pos.z; } void ObjTokeiStep_AddQuake(ObjTokeiStep* this, GlobalContext* globalCtx) { s32 pad[2]; - s16 quake; + s16 quake = Quake_Add(GET_ACTIVE_CAM(globalCtx), 3); - quake = Quake_Add(GET_ACTIVE_CAM(globalCtx), 3); - Quake_SetSpeed(quake, 0x4E20); + Quake_SetSpeed(quake, 20000); Quake_SetQuakeValues(quake, 1, 0, 0, 0); Quake_SetCountdown(quake, 7); - func_8013ECE0(this->dyna.actor.xyzDistToPlayerSq, 0x78, 0x14, 0xA); + func_8013ECE0(this->dyna.actor.xyzDistToPlayerSq, 120, 20, 10); } void ObjTokeiStep_SpawnDust(ObjTokeiStep* this, ObjTokeiStepPanel* panel, GlobalContext* globalCtx) { @@ -79,17 +75,17 @@ void ObjTokeiStep_SpawnDust(ObjTokeiStep* this, ObjTokeiStepPanel* panel, Global Vec3f dustSpawnOffset; Vec3f dustSpawnPos; - Matrix_RotateY(this->dyna.actor.shape.rot.y, 0); + Matrix_RotateY(this->dyna.actor.shape.rot.y, MTXMODE_NEW); dustSpawnOffset.y = 115.0f; dustSpawnOffset.z = -10.0f; for (i = 0; i < 7; i++) { - dustSpawnOffset.x = dustSpawnXOffsets[i]; + dustSpawnOffset.x = sDustSpawnXOffsets[i]; Matrix_MultiplyVector3fByState(&dustSpawnOffset, &dustSpawnPos); dustSpawnPos.x += panel->pos.x; dustSpawnPos.y += panel->pos.y; dustSpawnPos.z += panel->pos.z; - func_800B1210(globalCtx, &dustSpawnPos, &D_801D15B0, &dustEffectAccel, (s32)((Rand_ZeroOne() * 40.0f) + 80.0f), + func_800B1210(globalCtx, &dustSpawnPos, &gZeroVec3f, &sDustEffectAccel, (s32)((Rand_ZeroOne() * 40.0f) + 80.0f), (s32)((Rand_ZeroOne() * 20.0f) + 50.0f)); } } @@ -105,7 +101,7 @@ void ObjTokeiStep_InitSteps(ObjTokeiStep* this) { panelOffset.x = 0.0f; panelOffset.y = 0.0f; - for (i = 0; i < 7; i++) { + for (i = 0; i < ARRAY_COUNT(this->panels); i++) { panel = &this->panels[i]; panelOffset.z = i * -20.0f; Matrix_MultiplyVector3fByState(&panelOffset, &panel->pos); @@ -123,9 +119,9 @@ void ObjTokeiStep_InitStepsOpen(ObjTokeiStep* this) { this->dyna.actor.world.pos.z, &this->dyna.actor.shape.rot); panelOffset.x = 0.0f; - for (i = 0; i < 7; i++) { + for (i = 0; i < ARRAY_COUNT(this->panels); i++) { panel = &this->panels[i]; - panelOffset.y = panelXOffsets[i]; + panelOffset.y = sPanelXOffsets[i]; panelOffset.z = i * -20.0f; Matrix_MultiplyVector3fByState(&panelOffset, &panel->pos); } @@ -135,7 +131,7 @@ void ObjTokeiStep_InitTimers(ObjTokeiStep* this) { s32 i; this->panels[0].startFallingTimer = 0; - for (i = 1; i < 7; i++) { + for (i = 1; i < ARRAY_COUNT(this->panels); i++) { this->panels[i].startFallingTimer = 10; } } @@ -145,17 +141,17 @@ s32 ObjTokeiStep_OpenProcess(ObjTokeiStep* this, GlobalContext* globalCtx) { s32 i; ObjTokeiStepPanel* panel; f32 finalPosY; - s32 isOpen = 1; - s32 prevBounced = 1; + s32 isOpen = true; + s32 hasPrevBounced = true; - for (i = 0; i < 7; i++) { + for (i = 0; i < ARRAY_COUNT(this->panels); i++) { panel = &this->panels[i]; - if (prevBounced && panel->startFallingTimer > 0) { + if (hasPrevBounced && (panel->startFallingTimer > 0)) { panel->startFallingTimer--; - isOpen = 0; + isOpen = false; } - if (prevBounced && panel->numBounces < 3 && panel->startFallingTimer <= 0) { - finalPosY = panelXOffsets[i] + this->dyna.actor.world.pos.y; + if (hasPrevBounced && (panel->numBounces < 3) && (panel->startFallingTimer <= 0)) { + finalPosY = sPanelXOffsets[i] + this->dyna.actor.world.pos.y; if (!panel->hasSoundPlayed) { Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_CLOCK_TOWER_STAIR_MOVE); panel->hasSoundPlayed = true; @@ -163,7 +159,7 @@ s32 ObjTokeiStep_OpenProcess(ObjTokeiStep* this, GlobalContext* globalCtx) { panel->posChangeY += -2.5f; panel->posChangeY *= 0.83f; panel->pos.y += panel->posChangeY; - isOpen = 0; + isOpen = false; if (panel->pos.y < finalPosY) { panel->numBounces++; if (panel->numBounces >= 3) { @@ -186,7 +182,7 @@ s32 ObjTokeiStep_OpenProcess(ObjTokeiStep* this, GlobalContext* globalCtx) { } } } - prevBounced = panel->numBounces > 0; + hasPrevBounced = panel->numBounces > 0; } return isOpen; } @@ -196,16 +192,17 @@ void ObjTokeiStep_Init(Actor* thisx, GlobalContext* globalCtx) { Actor_ProcessInitChain(&this->dyna.actor, sInitChain); DynaPolyActor_Init(&this->dyna, 0); - if ((globalCtx->sceneNum == 0x6F) && (gSaveContext.sceneSetupIndex == 2) && (globalCtx->csCtx.unk_12 == 0)) { - DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &D_06000968); + if ((globalCtx->sceneNum == SCENE_CLOCKTOWER) && (gSaveContext.sceneSetupIndex == 2) && + (globalCtx->csCtx.unk_12 == 0)) { + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &gClocktowerPanelCol); ObjTokeiStep_InitSteps(this); ObjTokeiStep_SetupBeginOpen(this); - } else if (!((CURRENT_DAY != 3) || (gSaveContext.time >= 0x4000)) || gSaveContext.day >= 4) { + } else if (((CURRENT_DAY == 3) && (gSaveContext.time < CLOCK_TIME(6, 0))) || (gSaveContext.day >= 4)) { this->dyna.actor.draw = ObjTokeiStep_DrawOpen; ObjTokeiStep_InitStepsOpen(this); ObjTokeiStep_SetupDoNothingOpen(this); } else { - DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &D_06000968); + DynaPolyActor_LoadMesh(globalCtx, &this->dyna, &gClocktowerPanelCol); ObjTokeiStep_InitSteps(this); ObjTokeiStep_SetupDoNothing(this); } @@ -226,7 +223,7 @@ void ObjTokeiStep_BeginOpen(ObjTokeiStep* this, GlobalContext* globalCtx) { if (func_800EE29C(globalCtx, 0x86)) { action = globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x86)]; - if ((globalCtx->csCtx.frames == (*action).startFrame) && action->unk0) { + if ((action->startFrame == globalCtx->csCtx.frames) && (action->unk0 != 0)) { this->dyna.actor.draw = ObjTokeiStep_DrawOpen; ObjTokeiStep_SetupOpen(this); } @@ -269,12 +266,12 @@ void ObjTokeiStep_Update(Actor* thisx, GlobalContext* globalCtx) { void ObjTokeiStep_Draw(Actor* thisx, GlobalContext* globalCtx) { ObjTokeiStep* this = THIS; - func_800BDFC0(globalCtx, D_06000088); + func_800BDFC0(globalCtx, gClocktowerPanelDL); } void ObjTokeiStep_DrawOpen(Actor* thisx, GlobalContext* globalCtx) { ObjTokeiStep* this = THIS; - int i; + s32 i; ObjTokeiStepPanel* panel; Gfx* gfx; @@ -282,11 +279,11 @@ void ObjTokeiStep_DrawOpen(Actor* thisx, GlobalContext* globalCtx) { gfx = POLY_OPA_DISP; gSPDisplayList(gfx++, &sSetupDL[6 * 0x19]); - for (i = 0; i < 7; i++) { + for (i = 0; i < ARRAY_COUNT(this->panels); i++) { panel = &this->panels[i]; ObjTokeiStep_SetSysMatrix(panel); gSPMatrix(gfx++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); - gSPDisplayList(gfx++, D_06000088); + gSPDisplayList(gfx++, gClocktowerPanelDL); } POLY_OPA_DISP = gfx; CLOSE_DISPS(globalCtx->state.gfxCtx); diff --git a/src/overlays/actors/ovl_Obj_Tokeidai/z_obj_tokeidai.c b/src/overlays/actors/ovl_Obj_Tokeidai/z_obj_tokeidai.c index 76a38e117..729464350 100644 --- a/src/overlays/actors/ovl_Obj_Tokeidai/z_obj_tokeidai.c +++ b/src/overlays/actors/ovl_Obj_Tokeidai/z_obj_tokeidai.c @@ -1,43 +1,51 @@ /* * File: z_obj_tokeidai.c * Overlay: ovl_Obj_Tokeidai - * Description: Clock Face + * Description: Components of the Clock Tower (gears, clock face, counterweight, etc). Also used for wall clocks. + * + * This actor handles most of the functionality related to the Clock Tower and the various + * wall clocks around Clock Town. Among its responsibilities are making the clocks correctly + * tell the time by spinning the various pieces and gears and controlling the spotlight that + * is emitted from the Clock Tower at night. + * + * On the midnight of the Final Day, the Clock Tower opens up, and the various pieces of it + * are moved around. This actor is responsible for managing all of this movement. Additionally, + * if the moon crashes into Termina, this actor is responsible for making the pieces of the + * Clock Tower collapse. */ #include "z_obj_tokeidai.h" +#include "objects/object_obj_tokeidai/object_obj_tokeidai.h" #define FLAGS 0x00000030 #define THIS ((ObjTokeidai*)thisx) +#define GET_CURRENT_HOUR(this) ((s32)((this)->currentTime * (24.0f / 0x10000))) +#define GET_CURRENT_MINUTE(this) ((s32)((this)->currentTime * (360 * 2.0f / 0x10000)) % 30) +#define GET_CLOCK_FACE_ROTATION(currentHour) ((s16)(currentHour * (0x10000 / 24.0f))) +#define GET_OUTER_RING_OR_GEAR_ROTATION(currentMinute) ((s16)(currentMinute * (0x10000 * 12.0f / 360))) + void ObjTokeidai_Init(Actor* thisx, GlobalContext* globalCtx); void ObjTokeidai_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjTokeidai_Update(Actor* thisx, GlobalContext* globalCtx); void ObjTokeidai_Draw(Actor* thisx, GlobalContext* globalCtx); -void func_80AB319C(ObjTokeidai* this, GlobalContext* globalCtx); -void func_80AB3240(ObjTokeidai* this, GlobalContext* globalCtx); -void func_80AB32F0(ObjTokeidai* this, GlobalContext* globalCtx); -void func_80AB3370(ObjTokeidai* this, GlobalContext* globalCtx); -void func_80AB34CC(ObjTokeidai* this, GlobalContext* globalCtx); -void func_80AB3544(ObjTokeidai* this, GlobalContext* globalCtx); -void func_80AB3598(ObjTokeidai* this, GlobalContext* globalCtx); -void func_80AB363C(ObjTokeidai* this, GlobalContext* globalCtx); -void func_80AB365C(ObjTokeidai* this, GlobalContext* globalCtx); -void func_80AB3808(ObjTokeidai* this, GlobalContext* globalCtx); -void func_80AB3880(ObjTokeidai* this, GlobalContext* globalCtx); -void func_80AB38B0(ObjTokeidai* this, GlobalContext* globalCtx); -void func_80AB39BC(ObjTokeidai* this, GlobalContext* globalCtx); -void func_80AB3A7C(ObjTokeidai* this, GlobalContext* globalCtx); -void func_80AB3B34(ObjTokeidai* this, GlobalContext* globalCtx); -void func_80AB3BD8(ObjTokeidai* this, GlobalContext* globalCtx); -void func_80AB3BE8(ObjTokeidai* this, GlobalContext* globalCtx); -void func_80AB3ED0(ObjTokeidai* this, GlobalContext* globalCtx); -void func_80AB4040(ObjTokeidai* this, GlobalContext* globalCtx); -void func_80AB4080(ObjTokeidai* this, GlobalContext* globalCtx); -void func_80AB4160(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_DoNothing(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_TowerClock_OpenedIdle(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_TowerGear_OpenedIdle(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_Counterweight_OpenedIdle(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_TowerClock_Idle(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_WallClock_Idle(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_TowerGear_Idle(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_Counterweight_Idle(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_Walls_Idle(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_StaircaseIntoTower_Idle(ObjTokeidai* this, GlobalContext* globalCtx); +void ObjTokeidai_SetupTowerOpening(ObjTokeidai* this); +void ObjTokeidai_Clock_Draw(Actor* thisx, GlobalContext* globalCtx); +void ObjTokeidai_Counterweight_Draw(Actor* thisx, GlobalContext* globalCtx); +void ObjTokeidai_TowerGear_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Tokeidai_InitVars = { ACTOR_OBJ_TOKEIDAI, ACTORCAT_PROP, @@ -50,87 +58,794 @@ const ActorInit Obj_Tokeidai_InitVars = { (ActorFunc)ObjTokeidai_Draw, }; -#endif +static InitChainEntry sInitChain[] = { + ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneForward, 4000, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneScale, 3300, ICHAIN_CONTINUE), + ICHAIN_F32(uncullZoneForward, 1100, ICHAIN_STOP), +}; -extern UNK_TYPE D_0600B208; -extern UNK_TYPE D_0600BA78; -extern UNK_TYPE D_0600CF28; -extern UNK_TYPE D_0600D388; +/** + * Returns the angle necessary to show the correct side of + * the sun and moon disk based on the time of day. The actual + * angle can differ from the target angle if the disk is in + * the middle of rotating. + */ +s32 ObjTokeidai_GetTargetSunMoonDiskRotation() { + if (gSaveContext.isNight) { + return 0x8000; + } + return 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB2790.s") +void ObjTokeidai_SetupClockOrGear(ObjTokeidai* this) { + s32 currentMinute = GET_CURRENT_MINUTE(this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB27B4.s") + this->clockMinute = currentMinute; + this->outerRingOrGearRotation = GET_OUTER_RING_OR_GEAR_ROTATION(currentMinute); + this->outerRingOrGearRotationalVelocity = 0x3C; + this->outerRingOrGearRotationTimer = 0; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB2834.s") +void ObjTokeidai_Clock_Init(ObjTokeidai* this) { + s32 currentHour; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB28C8.s") + ObjTokeidai_SetupClockOrGear(this); + currentHour = GET_CURRENT_HOUR(this); + this->clockHour = currentHour; + this->clockFaceRotation = GET_CLOCK_FACE_ROTATION(currentHour); + this->clockFaceRotationalVelocity = 0; + this->clockFaceRotationTimer = 0; + this->sunMoonDiskRotationalVelocity = 0; + this->sunMoonDiskRotation = ObjTokeidai_GetTargetSunMoonDiskRotation(); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB29F8.s") +void ObjTokeidai_TowerGear_Init(ObjTokeidai* this, GlobalContext* globalCtx) { + this->actor.draw = ObjTokeidai_TowerGear_Draw; + this->opaDList = object_obj_tokeidai_DL_00BA78; + ObjTokeidai_SetupClockOrGear(this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB2BBC.s") + if (((globalCtx->sceneNum == SCENE_CLOCKTOWER) && (gSaveContext.sceneSetupIndex == 2) && + (globalCtx->csCtx.unk_12 == 0)) || + ((globalCtx->sceneNum == SCENE_00KEIKOKU) && (gSaveContext.sceneSetupIndex == 2) && + (globalCtx->csCtx.unk_12 == 0))) { + ObjTokeidai_SetupTowerOpening(this); + } else if ((CURRENT_DAY == 3 && gSaveContext.time < CLOCK_TIME(6, 0)) || CURRENT_DAY >= 4) { + this->actionFunc = ObjTokeidai_TowerGear_OpenedIdle; + this->actor.world.pos.y += this->actor.scale.y * 1900.0f; + this->actor.shape.yOffset = 1500.0f; + gSaveContext.weekEventReg[8] |= 0x40; + } else { + this->actionFunc = ObjTokeidai_TowerGear_Idle; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/ObjTokeidai_Init.s") +void ObjTokeidai_TowerClock_Init(ObjTokeidai* this, GlobalContext* globalCtx) { + this->actor.draw = ObjTokeidai_Clock_Draw; + ObjTokeidai_Clock_Init(this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/ObjTokeidai_Destroy.s") + if (((globalCtx->sceneNum == SCENE_CLOCKTOWER) && (gSaveContext.sceneSetupIndex == 2) && + (globalCtx->csCtx.unk_12 == 0)) || + ((globalCtx->sceneNum == SCENE_00KEIKOKU) && (gSaveContext.sceneSetupIndex == 2) && + (globalCtx->csCtx.unk_12 == 0))) { + ObjTokeidai_SetupTowerOpening(this); + } else if ((CURRENT_DAY == 3 && gSaveContext.time < CLOCK_TIME(6, 0)) || CURRENT_DAY >= 4) { + this->actor.world.pos.y += (this->actor.scale.y * 5191.0f) - 50.0f; + this->actor.world.pos.x += Math_SinS(this->actor.world.rot.y) * this->actor.scale.z * 1791.0f; + this->actor.world.pos.z += -Math_CosS(this->actor.world.rot.y) * this->actor.scale.z * 1791.0f; + this->clockFaceZTranslation = -0x140; + this->actor.shape.rot.x = -0x4000; + this->actor.home.pos = this->actor.world.pos; + this->actor.home.pos.y -= 1178.0f; + this->actor.home.pos.z += 13.0f; + this->actionFunc = ObjTokeidai_TowerClock_OpenedIdle; + } else { + this->actionFunc = ObjTokeidai_TowerClock_Idle; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3010.s") +void ObjTokeidai_Counterweight_Init(ObjTokeidai* this, GlobalContext* globalCtx) { + s32 type; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB319C.s") + this->actor.draw = ObjTokeidai_Counterweight_Draw; + this->opaDList = object_obj_tokeidai_DL_00B208; + this->xluDList = object_obj_tokeidai_DL_00B0C0; + if (gSaveContext.isNight) { + this->spotlightIntensity = 100; + } else { + this->spotlightIntensity = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3240.s") + if (((globalCtx->sceneNum == SCENE_CLOCKTOWER) && (gSaveContext.sceneSetupIndex == 2) && + (globalCtx->csCtx.unk_12 == 0)) || + ((globalCtx->sceneNum == SCENE_00KEIKOKU) && (gSaveContext.sceneSetupIndex == 2) && + (globalCtx->csCtx.unk_12 == 0))) { + this->spotlightIntensity = 0; + ObjTokeidai_SetupTowerOpening(this); + if (this->actor.child == NULL) { + type = OBJ_TOKEIDAI_TYPE(&this->actor); + if (type == OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_CLOCK_TOWN || + type == OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_TERMINA_FIELD) { + this->actor.child = + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_HANABI, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0); + } + } + if (this->actor.child != NULL) { + if (OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_TERMINA_FIELD) { + this->actor.child->home.rot.x = 0x384; + } else { + this->actor.child->home.rot.x = 0x12C; + } + } + } else if ((CURRENT_DAY == 3 && gSaveContext.time < CLOCK_TIME(6, 0)) || CURRENT_DAY >= 4) { + this->spotlightIntensity = 0; + this->actor.world.pos.y += this->actor.scale.y * -2160.0f; + this->actor.world.pos.x += Math_SinS(this->actor.world.rot.y) * this->actor.scale.z * 5400.0f; + this->actor.world.pos.z += -Math_CosS(this->actor.world.rot.y) * this->actor.scale.z * 5400.0f; + this->actor.shape.rot.x = -0x4000; + this->actionFunc = ObjTokeidai_Counterweight_OpenedIdle; + } else { + this->actionFunc = ObjTokeidai_Counterweight_Idle; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB32F0.s") +void ObjTokeidai_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjTokeidai* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3370.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + this->actionFunc = ObjTokeidai_DoNothing; + this->opaDList = NULL; + this->xluDList = NULL; + this->xRotation = 0; + this->yTranslation = 0; + this->clockFaceZTranslation = 0; + this->currentTime = gSaveContext.time; + this->actor.home.rot.x = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB34CC.s") + switch (OBJ_TOKEIDAI_TYPE(&this->actor)) { + case OBJ_TOKEIDAI_TYPE_TOWER_GEAR_TERMINA_FIELD: + Actor_SetScale(&this->actor, 0.15f); + ObjTokeidai_TowerGear_Init(this, globalCtx); + break; + case OBJ_TOKEIDAI_TYPE_TOWER_GEAR_CLOCK_TOWN: + ObjTokeidai_TowerGear_Init(this, globalCtx); + break; + case OBJ_TOKEIDAI_TYPE_UNUSED_WALL: + this->opaDList = object_obj_tokeidai_DL_00D388; + break; + case OBJ_TOKEIDAI_TYPE_TOWER_WALLS_TERMINA_FIELD: + Actor_SetScale(&this->actor, 1.0f); + this->opaDList = object_obj_tokeidai_DL_009A08; + this->actionFunc = ObjTokeidai_Walls_Idle; + break; + case OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_TERMINA_FIELD: + Actor_SetScale(&this->actor, 0.15f); + ObjTokeidai_TowerClock_Init(this, globalCtx); + break; + case OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_CLOCK_TOWN: + ObjTokeidai_TowerClock_Init(this, globalCtx); + break; + case OBJ_TOKEIDAI_TYPE_WALL_CLOCK: + Actor_SetScale(&this->actor, 0.02f); + this->actor.draw = ObjTokeidai_Clock_Draw; + ObjTokeidai_Clock_Init(this); + this->actionFunc = ObjTokeidai_WallClock_Idle; + break; + case OBJ_TOKEIDAI_TYPE_SMALL_WALL_CLOCK: + Actor_SetScale(&this->actor, 0.01f); + this->actor.draw = ObjTokeidai_Clock_Draw; + ObjTokeidai_Clock_Init(this); + this->actionFunc = ObjTokeidai_WallClock_Idle; + break; + case OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_TERMINA_FIELD: + Actor_SetScale(&this->actor, 0.15f); + ObjTokeidai_Counterweight_Init(this, globalCtx); + break; + case OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_CLOCK_TOWN: + ObjTokeidai_Counterweight_Init(this, globalCtx); + break; + case OBJ_TOKEIDAI_TYPE_STAIRCASE_INTO_TOWER: + this->opaDList = object_obj_tokeidai_DL_00D8E8; + this->xluDList = object_obj_tokeidai_DL_00D8E0; + this->actionFunc = ObjTokeidai_StaircaseIntoTower_Idle; + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3544.s") +void ObjTokeidai_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3598.s") +void ObjTokeidai_RotateOnMinuteChange(ObjTokeidai* this, s32 playSfx) { + s32 currentMinute = GET_CURRENT_MINUTE(this); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB363C.s") + if (currentMinute != this->clockMinute) { + if (this->outerRingOrGearRotationTimer == 8 && playSfx) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_CLOCK_TOWER_SECOND_HAND); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB365C.s") + if (this->outerRingOrGearRotationTimer > 8) { + // This actually performs the rotation to the next minute + // for the outer ring or gear. + this->outerRingOrGearRotationalVelocity += 0x3C; + this->outerRingOrGearRotation += this->outerRingOrGearRotationalVelocity; + } else { + // This makes the outer ring or gear wiggle in place for a bit + // before rotating to the next position. + if ((this->outerRingOrGearRotationTimer & 3) == 0) { + this->outerRingOrGearRotation += 0x5A; + } + if ((this->outerRingOrGearRotationTimer & 3) == 1) { + this->outerRingOrGearRotation -= 0x5A; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB36C4.s") + this->outerRingOrGearRotationTimer++; + if ((currentMinute == 15 && this->outerRingOrGearRotation < 0) || + (currentMinute != 15 && this->outerRingOrGearRotation > GET_OUTER_RING_OR_GEAR_ROTATION(currentMinute))) { + this->outerRingOrGearRotation = GET_OUTER_RING_OR_GEAR_ROTATION(currentMinute); + this->clockMinute = currentMinute; + this->outerRingOrGearRotationalVelocity = 0x5A; + this->outerRingOrGearRotationTimer = 0; + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3808.s") +void ObjTokeidai_TowerGear_Collapse(ObjTokeidai* this, GlobalContext* globalCtx) { + if ((this->actor.bgCheckFlags & 1) || this->actor.world.pos.y < 0.0f) { + this->actionFunc = ObjTokeidai_DoNothing; + } else { + this->actor.shape.rot.x += 0x50; + this->actor.shape.rot.z += 0x50; + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + Actor_UpdateBgCheckInfo(globalCtx, &this->actor, 0.0f, 0.0f, 0.0f, 4); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3880.s") +void ObjTokeidai_TowerGear_OpenedIdle(ObjTokeidai* this, GlobalContext* globalCtx) { + if (func_800EE29C(globalCtx, 0x84) && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 2) { + this->actionFunc = ObjTokeidai_TowerGear_Collapse; + this->actor.speedXZ = this->actor.scale.y * 5.0f; + this->actor.velocity.y = 0.0f; + this->actor.minVelocityY = this->actor.scale.y * -50.0f; + this->actor.gravity = this->actor.scale.y * -5.0f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB38B0.s") +/** + * This is hard to see in the final game. This, used in conjunction + * with the following function, makes the tower's clock slide off the + * tower and spin through the air when the moon crashes. + */ +void ObjTokeidai_TowerClock_Fall(ObjTokeidai* this, GlobalContext* globalCtx) { + this->actor.shape.rot.x += this->fallingClockFaceRotationalVelocity; + if (this->fallingClockFaceRotationalVelocity > 0xA0) { + this->fallingClockFaceRotationalVelocity -= 5; + } + this->actor.world.pos.z += 4.0f; + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + if (this->actor.world.pos.y < 0.0f) { + this->actionFunc = ObjTokeidai_DoNothing; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB39BC.s") +/** + * This is hard to see in the final game. This makes the + * tower's clock slide off as the moon crashes into it. + */ +void ObjTokeidai_TowerClock_SlideOff(ObjTokeidai* this, GlobalContext* globalCtx) { + f32 cos; + f32 sin; + Actor* thisx = &this->actor; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3A7C.s") + if (this->slidingClockFaceAngle < 0x4000) { + this->slidingClockFaceAngle += 0x28; + } + if (this->slidingClockFaceAngle > 0x800) { + this->aerialClockFaceSpeed += 4; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3B34.s") + if (this->aerialClockFaceSpeed < 0x80) { + thisx->shape.rot.x = this->slidingClockFaceAngle - 0x4000; + this->fallingClockFaceRotationalVelocity = 0x28; + } else { + if (thisx->shape.rot.x < -0x1000) { + thisx->shape.rot.x += this->fallingClockFaceRotationalVelocity; + if (this->fallingClockFaceRotationalVelocity < 0x1E0) { + this->fallingClockFaceRotationalVelocity += 0xA; + } + } else { + thisx->shape.rot.x += this->fallingClockFaceRotationalVelocity; + this->actionFunc = ObjTokeidai_TowerClock_Fall; + thisx->minVelocityY = -7.5f; + thisx->gravity = -0.75f; + thisx->velocity.y = -2.0f; + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3BB0.s") + sin = Math_SinS(this->slidingClockFaceAngle); + cos = Math_CosS(this->slidingClockFaceAngle); + thisx->world.pos.y = (1178.0f * cos) - (this->aerialClockFaceSpeed * sin) + thisx->home.pos.y; + thisx->world.pos.z = (1178.0f * sin) + (this->aerialClockFaceSpeed * cos) + thisx->home.pos.z; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3BD8.s") +void ObjTokeidai_TowerClock_OpenedIdle(ObjTokeidai* this, GlobalContext* globalCtx) { + if (func_800EE29C(globalCtx, 0x84) && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 1) { + this->actionFunc = ObjTokeidai_TowerClock_SlideOff; + this->slidingClockFaceAngle = 0; + this->aerialClockFaceSpeed = -0xD; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3BE8.s") +void ObjTokeidai_Counterweight_Collapse(ObjTokeidai* this, GlobalContext* globalCtx) { + if (this->actor.world.pos.y < 0.0f) { + this->actionFunc = ObjTokeidai_DoNothing; + } else { + this->xRotation += 0x64; + Actor_SetVelocityAndMoveYRotationAndGravity(&this->actor); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3C50.s") +void ObjTokeidai_Counterweight_OpenedIdle(ObjTokeidai* this, GlobalContext* globalCtx) { + if (func_800EE29C(globalCtx, 0x84) && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 3) { + this->actionFunc = ObjTokeidai_Counterweight_Collapse; + this->xRotation = 0; + this->actor.velocity.y = 0.0f; + this->actor.minVelocityY = this->actor.scale.y * -50.0f; + this->actor.gravity = this->actor.scale.y * -5.0f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3CCC.s") +/** + * This is hard to see in the final game. It makes the walls of + * the clock tower tip over as the moon crashes into it, but the + * giant moon mostly obscures it. + */ +void ObjTokeidai_Walls_Collapse(ObjTokeidai* this, GlobalContext* globalCtx) { + if (this->actor.shape.rot.x < 0x4000) { + this->actor.shape.rot.x += 0x28; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB3ED0.s") +void ObjTokeidai_Walls_Idle(ObjTokeidai* this, GlobalContext* globalCtx) { + if (func_800EE29C(globalCtx, 0x84) != 0 && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 1) { + this->actionFunc = ObjTokeidai_Walls_Collapse; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB4040.s") +void ObjTokeidai_TowerOpening_EndCutscene(ObjTokeidai* this, GlobalContext* globalCtx) { + if (func_800EE29C(globalCtx, 0x84) != 0 && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 5) { + gSaveContext.weekEventReg[8] |= 0x40; + if (((globalCtx->sceneNum == SCENE_CLOCKTOWER) && (gSaveContext.sceneSetupIndex == 2) && + (globalCtx->csCtx.unk_12 == 0)) || + ((globalCtx->sceneNum == SCENE_00KEIKOKU) && (gSaveContext.sceneSetupIndex == 2) && + (globalCtx->csCtx.unk_12 == 0))) { + func_801A3F54(false); + gSaveContext.cutscene = 0; + gSaveContext.nextCutsceneIndex = 0; + gSaveContext.respawnFlag = 2; + globalCtx->sceneLoadFlag = 0x14; + globalCtx->nextEntranceIndex = gSaveContext.respawn[1].entranceIndex; + globalCtx->unk_1887F = 2; + if (gSaveContext.respawn[1].playerParams == 0xCFF) { + gSaveContext.nextTransition = 0x15; + } else { + gSaveContext.nextTransition = 2; + } + } + this->actionFunc = ObjTokeidai_DoNothing; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB4080.s") +void ObjTokeidai_TowerOpening_FinishOpening(ObjTokeidai* this, GlobalContext* globalCtx) { + s32 type; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB4160.s") + if (this->clockFaceZTranslation > -320) { + // Recess the clock face before ending the cutscene, since the Termina + // Field version of the cutscene looks right at it. + this->clockFaceZTranslation -= 10; + } else { + type = OBJ_TOKEIDAI_TYPE(&this->actor); + if ((type == OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_CLOCK_TOWN) || + (type == OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_TERMINA_FIELD)) { + ObjTokeidai_TowerOpening_EndCutscene(this, globalCtx); + } else { + this->actionFunc = ObjTokeidai_DoNothing; + if (this->actor.child != NULL) { + this->actor.child->home.rot.x = 0; + } + } + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/ObjTokeidai_Update.s") +void ObjTokeidai_TowerOpening_Wait(ObjTokeidai* this, GlobalContext* globalCtx) { + if (this->openingWaitTimer > 0) { + this->openingWaitTimer--; + } else { + this->actionFunc = ObjTokeidai_TowerOpening_FinishOpening; + this->openingWaitTimer = 0; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/ObjTokeidai_Draw.s") +void ObjTokeidai_TowerOpening_DropCounterweight(ObjTokeidai* this, GlobalContext* globalCtx) { + this->xRotation += this->counterweightRotationalVelocity; + if (this->xRotation < 0x4000) { + this->counterweightRotationalVelocity += this->counterweightRotationalAcceleration; + return; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB4394.s") + this->counterweightRotationalAcceleration = 0x14; + this->xRotation = 0x4000; + switch (this->boundCount) { + case 0: + Audio_PlayActorSound2(&this->actor, NA_SE_EV_CLOCK_TOWER_BOUND_0); + break; + case 1: + Audio_PlayActorSound2(&this->actor, NA_SE_EV_CLOCK_TOWER_BOUND_1); + break; + case 2: + Audio_PlayActorSound2(&this->actor, NA_SE_EV_CLOCK_TOWER_BOUND_2); + break; + } + this->boundCount++; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB4664.s") + if (this->counterweightRotationalVelocity > 0x190) { + // This condition is met for the first bound, causing the counterweight + // to rebound upwards quickly. + this->counterweightRotationalVelocity = -0xC8; + } else if (this->counterweightRotationalVelocity > 0x32) { + // This condition is met for the second bound, causing the counterweight + // to rebound upwards slowly. + this->counterweightRotationalVelocity = -(this->counterweightRotationalVelocity >> 1); + } else { + // This condition is met for the third bound, causing the counterweight + // to stop moving. + this->actionFunc = ObjTokeidai_TowerOpening_Wait; + this->openingWaitTimer = 10; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tokeidai/func_80AB4894.s") +void ObjTokeidai_TowerOpening_FinishRaise(ObjTokeidai* this, GlobalContext* globalCtx) { + s32 type; + + if (this->settleTimer > 0) { + // Jiggle the parts of the tower up and down to give it the appearance + // of "settling" into place. + if (this->settleTimer & 1) { + this->yTranslation = this->settleAmount + 3400; + } else { + this->yTranslation = 3400 - this->settleAmount; + if (this->settleAmount > 0) { + this->settleAmount -= 4; + } + } + this->settleTimer--; + } else { + type = OBJ_TOKEIDAI_TYPE(&this->actor); + if ((type == OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_CLOCK_TOWN) || + (type == OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_TERMINA_FIELD)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_CLOCK_TOWER_FALL); + } + this->yTranslation = 3400; + this->actionFunc = ObjTokeidai_TowerOpening_DropCounterweight; + this->counterweightRotationalVelocity = 0; + this->counterweightRotationalAcceleration = 0xA; + this->boundCount = 0; + } +} + +void ObjTokeidai_TowerOpening_RaiseTower(ObjTokeidai* this, GlobalContext* globalCtx) { + s32 type; + + if (this->yTranslation < 3400) { + type = OBJ_TOKEIDAI_TYPE(&this->actor); + this->yTranslation += 25; + if ((type == OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_CLOCK_TOWN) || + (type == OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_TERMINA_FIELD)) { + func_800B9010(&this->actor, NA_SE_EV_CLOCK_TOWER_UP - SFX_FLAG); + } + } else { + type = OBJ_TOKEIDAI_TYPE(&this->actor); + if ((type == OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_CLOCK_TOWN) || + (type == OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_TERMINA_FIELD)) { + Audio_PlayActorSound2(&this->actor, NA_SE_EV_CLOCK_TOWER_STOP); + } + this->yTranslation = 3400; + this->actionFunc = ObjTokeidai_TowerOpening_FinishRaise; + this->settleTimer = 10; + this->settleAmount = 20; + } +} + +void ObjTokeidai_TowerOpening_Start(ObjTokeidai* this, GlobalContext* globalCtx) { + if ((func_800EE29C(globalCtx, 0x84) && globalCtx->csCtx.npcActions[func_800EE200(globalCtx, 0x84)]->unk0 == 4) || + (gSaveContext.weekEventReg[8] & 0x40)) { + this->actionFunc = ObjTokeidai_TowerOpening_RaiseTower; + } +} + +/** + * Sets up the sequence where the Clock Tower "transforms" and opens up + * on the midnight of the Final Day. + */ +void ObjTokeidai_SetupTowerOpening(ObjTokeidai* this) { + this->actionFunc = ObjTokeidai_TowerOpening_Start; + this->clockFaceRotationalVelocity = 0; + this->clockFaceRotationTimer = 0; + this->yTranslation = 0; + this->xRotation = 0; + this->clockFaceZTranslation = 0; +} + +void ObjTokeidai_DoNothing(ObjTokeidai* this, GlobalContext* globalCtx) { +} + +void ObjTokeidai_StaircaseIntoTower_Idle(ObjTokeidai* this, GlobalContext* globalCtx) { + if (((CURRENT_DAY == 3 && gSaveContext.time < CLOCK_TIME(6, 0)) || CURRENT_DAY >= 4) || + (gSaveContext.weekEventReg[8] & 0x40)) { + this->actor.draw = ObjTokeidai_Draw; + } else { + this->actor.draw = NULL; + } +} + +s32 ObjTokeidai_IsPostFirstCycleFinalHours(ObjTokeidai* this, GlobalContext* globalCtx) { + if (gSaveContext.inventory.items[SLOT_OCARINA] == ITEM_NONE) { + return false; + } + if (CURRENT_DAY == 3 && gSaveContext.time < CLOCK_TIME(6, 0)) { + ObjTokeidai_SetupTowerOpening(this); + return true; + } + return false; +} + +void ObjTokeidai_RotateOnHourChange(ObjTokeidai* this, GlobalContext* globalCtx) { + s32 currentHour = GET_CURRENT_HOUR(this); + + if (currentHour != this->clockHour) { + if (this->clockFaceRotationTimer > 12) { + // This actually performs the rotation to the next hour + // for the clock face. + this->clockFaceRotationalVelocity += 0xA; + this->clockFaceRotation += this->clockFaceRotationalVelocity; + } else { + // This makes the clock face wiggle in place for a bit + // before rotating to the next position. + if ((this->clockFaceRotationTimer & 3) == 0) { + this->clockFaceRotation += 0x3C; + } + if ((this->clockFaceRotationTimer & 3) == 1) { + this->clockFaceRotation -= 0x3C; + } + } + + this->clockFaceRotationTimer++; + if ((currentHour == 12 && this->clockFaceRotation < 0) || + (currentHour != 12 && this->clockFaceRotation > GET_CLOCK_FACE_ROTATION(currentHour))) { + this->clockFaceRotation = GET_CLOCK_FACE_ROTATION(currentHour); + this->clockHour = currentHour; + this->clockFaceRotationalVelocity = 0; + this->clockFaceRotationTimer = 0; + } + } + + // If the sun and moon disk doesn't have the target rotation (e.g., the time of day + // just changed), rotate it until it matches the target. + if (this->sunMoonDiskRotation != ObjTokeidai_GetTargetSunMoonDiskRotation()) { + if (this->clockHour == 6) { + this->sunMoonDiskRotationalVelocity += 0x222; + this->sunMoonDiskRotation += this->sunMoonDiskRotationalVelocity; + if (this->sunMoonDiskRotation > 0x10000) { + this->sunMoonDiskRotation = ObjTokeidai_GetTargetSunMoonDiskRotation(); + this->sunMoonDiskRotationalVelocity = 0; + } + } + if (this->clockHour == 18) { + this->sunMoonDiskRotationalVelocity += 0x222; + this->sunMoonDiskRotation += this->sunMoonDiskRotationalVelocity; + if (this->sunMoonDiskRotation > 0x8000) { + this->sunMoonDiskRotation = ObjTokeidai_GetTargetSunMoonDiskRotation(); + this->sunMoonDiskRotationalVelocity = 0; + } + } + } +} + +void ObjTokeidai_TowerClock_Idle(ObjTokeidai* this, GlobalContext* globalCtx) { + if (CURRENT_DAY == 3 && this->clockHour < 6 && gSaveContext.time < CLOCK_TIME(6, 0)) { + this->actor.draw = ObjTokeidai_Clock_Draw; + ObjTokeidai_SetupTowerOpening(this); + gSaveContext.weekEventReg[8] |= 0x40; + return; + } + + if (globalCtx->csCtx.state != 0) { + this->actor.home.rot.x = 1; + this->currentTime += 3; + this->actor.draw = ObjTokeidai_Clock_Draw; + } else { + if (!(globalCtx->actorCtx.unk5 & 2) && + OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_TERMINA_FIELD && + ActorCutscene_GetCurrentIndex() == -1) { + this->actor.draw = NULL; + } + this->currentTime = gSaveContext.time; + if (this->actor.home.rot.x != 0) { + ObjTokeidai_Clock_Init(this); + this->actor.home.rot.x = 0; + } + } + + if (CURRENT_DAY != 3 || gSaveContext.time >= CLOCK_TIME(6, 0)) { + ObjTokeidai_RotateOnMinuteChange(this, true); + } + ObjTokeidai_RotateOnHourChange(this, globalCtx); +} + +void ObjTokeidai_WallClock_Idle(ObjTokeidai* this, GlobalContext* globalCtx) { + this->currentTime = gSaveContext.time; + ObjTokeidai_RotateOnMinuteChange(this, true); + ObjTokeidai_RotateOnHourChange(this, globalCtx); +} + +void ObjTokeidai_TowerGear_Idle(ObjTokeidai* this, GlobalContext* globalCtx) { + if (ObjTokeidai_IsPostFirstCycleFinalHours(this, globalCtx)) { + this->actor.draw = ObjTokeidai_TowerGear_Draw; + } else { + if (globalCtx->csCtx.state != 0) { + this->actor.home.rot.x = 1; + this->currentTime += 3; + this->actor.draw = ObjTokeidai_TowerGear_Draw; + } else { + if ((globalCtx->actorCtx.unk5 & 2) == 0 && + OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_TOWER_GEAR_TERMINA_FIELD && + ActorCutscene_GetCurrentIndex() == -1) { + this->actor.draw = NULL; + } + this->currentTime = gSaveContext.time; + if (this->actor.home.rot.x != 0) { + ObjTokeidai_SetupClockOrGear(this); + this->actor.home.rot.x = 0; + } + } + ObjTokeidai_RotateOnMinuteChange(this, false); + } +} + +void ObjTokeidai_Counterweight_Idle(ObjTokeidai* this, GlobalContext* globalCtx) { + s32 type; + + if (ObjTokeidai_IsPostFirstCycleFinalHours(this, globalCtx)) { + this->spotlightIntensity = 0; + if (this->actor.child == NULL) { + type = OBJ_TOKEIDAI_TYPE(&this->actor); + if (type == OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_CLOCK_TOWN || + type == OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_TERMINA_FIELD) { + this->actor.child = + Actor_Spawn(&globalCtx->actorCtx, globalCtx, ACTOR_EN_HANABI, this->actor.world.pos.x, + this->actor.world.pos.y, this->actor.world.pos.z, 0, 0, 0, 0); + } + } + if (this->actor.child != NULL) { + if (OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_TERMINA_FIELD) { + this->actor.child->home.rot.x = 0x384; + } else { + this->actor.child->home.rot.x = 0x12C; + } + } + } else { + this->actor.shape.rot.y -= 0x40; + if (gSaveContext.isNight) { + if (this->spotlightIntensity < 100) { + this->spotlightIntensity += 4; + } + } else if (this->spotlightIntensity > 0) { + this->spotlightIntensity -= 4; + } + } +} + +void ObjTokeidai_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjTokeidai* this = THIS; + this->actionFunc(this, globalCtx); +} + +void ObjTokeidai_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjTokeidai* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (this->opaDList != NULL) { + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C28C(globalCtx->state.gfxCtx); + gSPDisplayList(POLY_OPA_DISP++, this->opaDList); + } + if (this->xluDList != NULL) { + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C2DC(globalCtx->state.gfxCtx); + gSPDisplayList(POLY_XLU_DISP++, this->xluDList); + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void ObjTokeidai_Clock_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjTokeidai* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + Matrix_InsertTranslation(0.0f, this->yTranslation, 0.0f, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, 0.0f, -1791.0f, MTXMODE_APPLY); + Matrix_InsertXRotation_s(-this->xRotation, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, 0.0f, 1791.0f, MTXMODE_APPLY); + Matrix_StatePush(); + Matrix_InsertZRotation_s(-this->outerRingOrGearRotation, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_obj_tokeidai_DL_00CF28); + Matrix_StatePop(); + Matrix_InsertTranslation(0.0f, 0.0f, this->clockFaceZTranslation, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_obj_tokeidai_DL_00BEE8); + Matrix_InsertZRotation_s(-this->clockFaceRotation * 2, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + if (OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_WALL_CLOCK || + OBJ_TOKEIDAI_TYPE(&this->actor) == OBJ_TOKEIDAI_TYPE_SMALL_WALL_CLOCK) { + gSPDisplayList(POLY_OPA_DISP++, object_obj_tokeidai_DL_00F518); + } else { + gSPDisplayList(POLY_OPA_DISP++, object_obj_tokeidai_DL_00E818); + } + Matrix_InsertTranslation(0.0f, -1112.0f, -19.6f, MTXMODE_APPLY); + Matrix_RotateY((s16)this->sunMoonDiskRotation, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, object_obj_tokeidai_DL_00C368); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void ObjTokeidai_Counterweight_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + u32 gameplayFrames = globalCtx->gameplayFrames; + ObjTokeidai* this = THIS; + + Matrix_RotateY(-this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, this->yTranslation, 0.0f, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, -5480.0f, 80.0f, MTXMODE_APPLY); + Matrix_InsertXRotation_s(-this->xRotation, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, 5480.0f, -80.0f, MTXMODE_APPLY); + Matrix_RotateY(this->actor.shape.rot.y, MTXMODE_APPLY); + + OPEN_DISPS(globalCtx->state.gfxCtx); + + gSPSegment(POLY_XLU_DISP++, 0x08, + Gfx_TwoTexScroll(globalCtx->state.gfxCtx, 0, 0, 0, 0x20, 0x40, 1, -gameplayFrames, 0, 0x20, 0x20)); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C28C(globalCtx->state.gfxCtx); + gSPDisplayList(POLY_OPA_DISP++, this->opaDList); + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C2DC(globalCtx->state.gfxCtx); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 255, 255, 235, 180, (s32)(this->spotlightIntensity * 2.55f)); + gSPDisplayList(POLY_XLU_DISP++, this->xluDList); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void ObjTokeidai_TowerGear_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjTokeidai* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + Matrix_InsertTranslation(0.0f, this->yTranslation, 0.0f, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, 0.0f, -1791.0f, MTXMODE_APPLY); + Matrix_RotateY(-this->actor.shape.rot.y, MTXMODE_APPLY); + Matrix_InsertXRotation_s(-this->xRotation, MTXMODE_APPLY); + Matrix_RotateY(thisx->shape.rot.y, MTXMODE_APPLY); + Matrix_InsertTranslation(0.0f, 0.0f, 1791.0f, MTXMODE_APPLY); + Matrix_InsertZRotation_s(this->outerRingOrGearRotation, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C28C(globalCtx->state.gfxCtx); + gSPDisplayList(POLY_OPA_DISP++, object_obj_tokeidai_DL_00BA78); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Tokeidai/z_obj_tokeidai.h b/src/overlays/actors/ovl_Obj_Tokeidai/z_obj_tokeidai.h index f550606f0..c5cf8d70c 100644 --- a/src/overlays/actors/ovl_Obj_Tokeidai/z_obj_tokeidai.h +++ b/src/overlays/actors/ovl_Obj_Tokeidai/z_obj_tokeidai.h @@ -3,14 +3,63 @@ #include "global.h" +#define OBJ_TOKEIDAI_TYPE(thisx) (((thisx)->params & 0xF000) >> 12) + +typedef enum { + /* 0 */ OBJ_TOKEIDAI_TYPE_TOWER_GEAR_CLOCK_TOWN, + /* 1 */ OBJ_TOKEIDAI_TYPE_UNUSED_WALL, + /* 2 */ OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_CLOCK_TOWN, + /* 3 */ OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_CLOCK_TOWN, + /* 4 */ OBJ_TOKEIDAI_TYPE_TOWER_GEAR_TERMINA_FIELD, + /* 5 */ OBJ_TOKEIDAI_TYPE_TOWER_CLOCK_TERMINA_FIELD, + /* 6 */ OBJ_TOKEIDAI_TYPE_COUNTERWEIGHT_TERMINA_FIELD, + /* 8 */ OBJ_TOKEIDAI_TYPE_TOWER_WALLS_TERMINA_FIELD = 8, + /* 9 */ OBJ_TOKEIDAI_TYPE_WALL_CLOCK, + /* 10 */ OBJ_TOKEIDAI_TYPE_SMALL_WALL_CLOCK, + /* 11 */ OBJ_TOKEIDAI_TYPE_STAIRCASE_INTO_TOWER, +} ObjTokeidaiType; + struct ObjTokeidai; typedef void (*ObjTokeidaiActionFunc)(struct ObjTokeidai*, GlobalContext*); typedef struct ObjTokeidai { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x30]; - /* 0x0174 */ ObjTokeidaiActionFunc actionFunc; + /* 0x000 */ Actor actor; + /* 0x144 */ Gfx* opaDList; + /* 0x148 */ Gfx* xluDList; + /* 0x14C */ s16 outerRingOrGearRotation; + /* 0x14E */ s16 outerRingOrGearRotationalVelocity; + /* 0x150 */ s16 outerRingOrGearRotationTimer; + /* 0x152 */ s16 clockFaceRotation; + /* 0x154 */ union { + s16 clockFaceRotationalVelocity; + s16 settleTimer; + s16 counterweightRotationalVelocity; + s16 openingWaitTimer; + s16 slidingClockFaceAngle; + }; + /* 0x156 */ union { + s16 clockFaceRotationTimer; + s16 settleAmount; + s16 counterweightRotationalAcceleration; + s16 aerialClockFaceSpeed; + }; + /* 0x158 */ s32 sunMoonDiskRotation; + /* 0x15C */ union { + s16 sunMoonDiskRotationalVelocity; + s16 fallingClockFaceRotationalVelocity; + }; + /* 0x15E */ s16 yTranslation; + /* 0x160 */ s16 xRotation; + /* 0x162 */ s16 clockFaceZTranslation; // amount the clock face recesses inwards once it transforms + /* 0x164 */ s16 boundCount; + /* 0x168 */ s32 clockMinute; // only 30 minutes in an hour + /* 0x16C */ union { + s32 clockHour; + s32 spotlightIntensity; + }; + /* 0x170 */ u16 currentTime; + /* 0x174 */ ObjTokeidaiActionFunc actionFunc; } ObjTokeidai; // size = 0x178 extern const ActorInit Obj_Tokeidai_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Toudai/z_obj_toudai.c b/src/overlays/actors/ovl_Obj_Toudai/z_obj_toudai.c index 5a84ec663..325bd3f3e 100644 --- a/src/overlays/actors/ovl_Obj_Toudai/z_obj_toudai.c +++ b/src/overlays/actors/ovl_Obj_Toudai/z_obj_toudai.c @@ -1,7 +1,7 @@ /* * File: z_obj_toudai.c * Overlay: ovl_Obj_Toudai - * Description: Clock Tower Spotlight + * Description: Unused early Clock Tower Spotlight */ #include "z_obj_toudai.h" diff --git a/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.c b/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.c index 6eedfd500..0ffa73331 100644 --- a/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.c +++ b/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.c @@ -1,7 +1,7 @@ /* * File: z_obj_tree.c * Overlay: ovl_Obj_Tree - * Description: Single tree (e.g. North Clock Town) + * Description: Single branching tree (e.g. North Clock Town) */ #include "z_obj_tree.h" @@ -15,7 +15,10 @@ void ObjTree_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjTree_Update(Actor* thisx, GlobalContext* globalCtx); void ObjTree_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 +void ObTree_DoNothing(ObjTree* this, GlobalContext* globalCtx); +void ObTree_SetupDoNothing(ObjTree* this); +void ObTree_Sway(ObjTree* this, GlobalContext* globalCtx); + const ActorInit Obj_Tree_InitVars = { ACTOR_OBJ_TREE, ACTORCAT_PROP, @@ -28,15 +31,27 @@ const ActorInit Obj_Tree_InitVars = { (ActorFunc)ObjTree_Draw, }; -// static ColliderCylinderInit sCylinderInit = { -static ColliderCylinderInit D_80B9A570 = { - { COLTYPE_TREE, AT_NONE, AC_ON | AC_TYPE_PLAYER, OC1_ON | OC1_TYPE_ALL, OC2_TYPE_1, COLSHAPE_CYLINDER, }, - { ELEMTYPE_UNK1, { 0x00000000, 0x00, 0x00 }, { 0x0100020A, 0x00, 0x00 }, TOUCH_NONE | TOUCH_SFX_NORMAL, BUMP_ON, OCELEM_ON, }, +static ColliderCylinderInit sCylinderInit = { + { + COLTYPE_TREE, + AT_NONE, + AC_ON | AC_TYPE_PLAYER, + OC1_ON | OC1_TYPE_ALL, + OC2_TYPE_1, + COLSHAPE_CYLINDER, + }, + { + ELEMTYPE_UNK1, + { 0x00000000, 0x00, 0x00 }, + { 0x0100020A, 0x00, 0x00 }, + TOUCH_NONE | TOUCH_SFX_NORMAL, + BUMP_ON, + OCELEM_ON, + }, { 28, 120, 0, { 0, 0, 0 } }, }; -// static DamageTable sDamageTable = { -static DamageTable D_80B9A59C = { +static DamageTable sDamageTable = { /* Deku Nut */ DMG_ENTRY(0, 0x0), /* Deku Stick */ DMG_ENTRY(0, 0xF), /* Horse trample */ DMG_ENTRY(0, 0x0), @@ -71,32 +86,115 @@ static DamageTable D_80B9A59C = { /* Powder Keg */ DMG_ENTRY(0, 0x0), }; -// sColChkInfoInit -static CollisionCheckInfoInit2 D_80B9A5BC = { 8, 0, 0, 0, MASS_HEAVY }; +static CollisionCheckInfoInit2 sColchkInfoInit = { 8, 0, 0, 0, MASS_HEAVY }; -#endif +extern Gfx D_06000680[]; +extern Gfx D_060007C8[]; +extern CollisionHeader D_06001B2C; -extern ColliderCylinderInit D_80B9A570; -extern DamageTable D_80B9A59C; -extern CollisionCheckInfoInit2 D_80B9A5BC; +void ObjTree_Init(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjTree* this = THIS; + CollisionHeader* colHeader = NULL; -extern UNK_TYPE D_06000680; -extern UNK_TYPE D_06001B2C; + if (OBJTREE_ISLARGE(&this->dyna.actor)) { + Actor_SetScale(&this->dyna.actor, 0.15f); + this->dyna.actor.uncullZoneForward = 4000.0f; + } else { + Actor_SetScale(&this->dyna.actor, 0.1f); + DynaPolyActor_Init(&this->dyna, 1); + CollisionHeader_GetVirtual(&D_06001B2C, &colHeader); + this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/ObjTree_Init.s") + Collider_InitCylinder(globalCtx, &this->collider); + Collider_SetCylinder(globalCtx, &this->collider, &this->dyna.actor, &sCylinderInit); + CollisionCheck_SetInfo2(&this->dyna.actor.colChkInfo, &sDamageTable, &sColchkInfoInit); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/ObjTree_Destroy.s") + if (OBJTREE_ISLARGE(&this->dyna.actor)) { + this->collider.dim.height = 220; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/func_80B9A20C.s") + this->swayAmplitude = 0.0f; + this->swayAngle = 0; + this->swayVelocity = 0; + ObTree_SetupDoNothing(this); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/func_80B9A220.s") +void ObjTree_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjTree* this = THIS; + s32 bgId; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/func_80B9A230.s") + if (!OBJTREE_ISLARGE(&this->dyna.actor)) { + bgId = this->dyna.bgId; + DynaPoly_DeleteBgActor(globalCtx, &globalCtx->colCtx.dyna, bgId); + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/func_80B9A27C.s") + Collider_DestroyCylinder(globalCtx, &this->collider); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/func_80B9A348.s") +void ObTree_SetupDoNothing(ObjTree* this) { + this->actionFunc = ObTree_DoNothing; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/ObjTree_Update.s") +void ObTree_DoNothing(ObjTree* this, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Tree/ObjTree_Draw.s") +void ObTree_SetupSway(ObjTree* this) { + this->timer = 0; + this->swayAmplitude = 546.0f; + this->swayVelocity = 35 * 0x10000 / 360; + Audio_PlayActorSound2(&this->dyna.actor, NA_SE_EV_TREE_SWING); + this->actionFunc = ObTree_Sway; +} + +void ObTree_Sway(ObjTree* this, GlobalContext* globalCtx) { + if (this->timer > 80) { + ObTree_SetupDoNothing(this); + return; + } + + Math_SmoothStepToF(&this->swayAmplitude, 0.0f, 0.1f, 91.0f, 18.0f); + this->swayVelocity += 1 * 0x10000 / 360; + this->swayAngle += this->swayVelocity; + this->dyna.actor.shape.rot.x = Math_SinS(this->swayAngle) * this->swayAmplitude; + this->dyna.actor.shape.rot.z = Math_CosS(this->swayAngle) * this->swayAmplitude; + this->timer++; +} + +void ObTree_UpdateCollision(ObjTree* this, GlobalContext* globalCtx) { + Collider_UpdateCylinder(&this->dyna.actor, &this->collider); + CollisionCheck_SetOC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + + if (this->dyna.actor.xzDistToPlayer < 600.0f) { + CollisionCheck_SetAC(globalCtx, &globalCtx->colChkCtx, &this->collider.base); + if (this->dyna.actor.home.rot.y == 1) { + this->dyna.actor.home.rot.y = 0; + ObTree_SetupSway(this); + } + } +} + +void ObjTree_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjTree* this = THIS; + + this->actionFunc(this, globalCtx); + ObTree_UpdateCollision(this, globalCtx); +} + +void ObjTree_Draw(Actor* thisx, GlobalContext* globalCtx) { + s16 xRot = (f32)thisx->shape.rot.x; + s16 zRot = (f32)thisx->shape.rot.z; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + func_8012C28C(globalCtx->state.gfxCtx); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, D_06000680); + + Matrix_InsertRotation(xRot, 0, zRot, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_OPA_DISP++, D_060007C8); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.h b/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.h index 5c8f08ca0..b50e3eb40 100644 --- a/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.h +++ b/src/overlays/actors/ovl_Obj_Tree/z_obj_tree.h @@ -7,11 +7,16 @@ struct ObjTree; typedef void (*ObjTreeActionFunc)(struct ObjTree*, GlobalContext*); +#define OBJTREE_ISLARGE(thisx) ((thisx)->params & 0x8000) + typedef struct ObjTree { - /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x64]; - /* 0x01A8 */ ObjTreeActionFunc actionFunc; - /* 0x01AC */ char unk_1AC[0xC]; + /* 0x000 */ DynaPolyActor dyna; + /* 0x15C */ ColliderCylinder collider; + /* 0x1A8 */ ObjTreeActionFunc actionFunc; + /* 0x1AC */ f32 swayAmplitude; + /* 0x1B0 */ s16 swayAngle; + /* 0x1B2 */ s16 swayVelocity; + /* 0x1B4 */ s16 timer; } ObjTree; // size = 0x1B8 extern const ActorInit Obj_Tree_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.h b/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.h index 31b7df583..d3a188e41 100644 --- a/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.h +++ b/src/overlays/actors/ovl_Obj_Tsubo/z_obj_tsubo.h @@ -10,7 +10,7 @@ typedef void (*ObjTsuboActionFunc)(struct ObjTsubo*, GlobalContext*); typedef struct ObjTsubo { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjTsuboActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x54]; + /* 0x0148 */ char unk_148[0x54]; } ObjTsubo; // size = 0x19C extern const ActorInit Obj_Tsubo_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Vspinyroll/z_obj_vspinyroll.c b/src/overlays/actors/ovl_Obj_Vspinyroll/z_obj_vspinyroll.c index df293030a..c830c29d9 100644 --- a/src/overlays/actors/ovl_Obj_Vspinyroll/z_obj_vspinyroll.c +++ b/src/overlays/actors/ovl_Obj_Vspinyroll/z_obj_vspinyroll.c @@ -1,7 +1,7 @@ /* * File: z_obj_vspinyroll.c * Overlay: ovl_Obj_Vspinyroll - * Description: Spiked rollers + * Description: Vertical Spiked rollers */ #include "z_obj_vspinyroll.h" diff --git a/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.c b/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.c index 496259853..6e66c9cab 100644 --- a/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.c +++ b/src/overlays/actors/ovl_Obj_Warpstone/z_obj_warpstone.c @@ -172,7 +172,7 @@ void ObjWarpstone_Draw(Actor* thisx, GlobalContext* globalCtx2) { func_8012C2DC(globalCtx->state.gfxCtx); Matrix_InsertTranslation(this->dyna.actor.world.pos.x, this->dyna.actor.world.pos.y + 34.0f, this->dyna.actor.world.pos.z, MTXMODE_NEW); - Matrix_InsertMatrix(&globalCtx->mf_187FC, MTXMODE_APPLY); + Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_APPLY); Matrix_InsertTranslation(0.0f, 0.0f, 30.0f, MTXMODE_APPLY); Matrix_Scale(this->dyna.actor.velocity.x, this->dyna.actor.velocity.x, this->dyna.actor.velocity.x, MTXMODE_APPLY); diff --git a/src/overlays/actors/ovl_Obj_Wturn/z_obj_wturn.h b/src/overlays/actors/ovl_Obj_Wturn/z_obj_wturn.h index e7e4073a3..0b0b8b375 100644 --- a/src/overlays/actors/ovl_Obj_Wturn/z_obj_wturn.h +++ b/src/overlays/actors/ovl_Obj_Wturn/z_obj_wturn.h @@ -10,7 +10,7 @@ typedef void (*ObjWturnActionFunc)(struct ObjWturn*, GlobalContext*); typedef struct ObjWturn { /* 0x0000 */ Actor actor; /* 0x0144 */ ObjWturnActionFunc actionFunc; - /* 0x0148 */ char unk_144[0x4]; + /* 0x0148 */ char unk_148[0x4]; } ObjWturn; // size = 0x14C extern const ActorInit Obj_Wturn_InitVars; diff --git a/src/overlays/actors/ovl_Obj_Y2lift/z_obj_y2lift.c b/src/overlays/actors/ovl_Obj_Y2lift/z_obj_y2lift.c index 55e14fb15..3c0fce631 100644 --- a/src/overlays/actors/ovl_Obj_Y2lift/z_obj_y2lift.c +++ b/src/overlays/actors/ovl_Obj_Y2lift/z_obj_y2lift.c @@ -1,7 +1,7 @@ /* * File: z_obj_y2lift.c * Overlay: ovl_Obj_Y2lift - * Description: + * Description: Unused elevator platform */ #include "z_obj_y2lift.h" diff --git a/src/overlays/actors/ovl_Obj_Y2shutter/z_obj_y2shutter.c b/src/overlays/actors/ovl_Obj_Y2shutter/z_obj_y2shutter.c index 6eb1cffa7..c9850690d 100644 --- a/src/overlays/actors/ovl_Obj_Y2shutter/z_obj_y2shutter.c +++ b/src/overlays/actors/ovl_Obj_Y2shutter/z_obj_y2shutter.c @@ -1,7 +1,7 @@ /* * File: z_obj_y2shutter.c * Overlay: ovl_Obj_Y2shutter - * Description: + * Description: Pirates' Fortress sliding grate */ #include "z_obj_y2shutter.h" diff --git a/src/overlays/actors/ovl_Obj_Yado/z_obj_yado.c b/src/overlays/actors/ovl_Obj_Yado/z_obj_yado.c index 73ebea007..2d8689d4f 100644 --- a/src/overlays/actors/ovl_Obj_Yado/z_obj_yado.c +++ b/src/overlays/actors/ovl_Obj_Yado/z_obj_yado.c @@ -15,7 +15,6 @@ void ObjYado_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjYado_Update(Actor* thisx, GlobalContext* globalCtx); void ObjYado_Draw(Actor* thisx, GlobalContext* globalCtx); -#if 0 const ActorInit Obj_Yado_InitVars = { ACTOR_OBJ_YADO, ACTORCAT_BG, @@ -28,22 +27,50 @@ const ActorInit Obj_Yado_InitVars = { (ActorFunc)ObjYado_Draw, }; -// static InitChainEntry sInitChain[] = { -static InitChainEntry D_80C16420[] = { +static InitChainEntry sInitChain[] = { ICHAIN_VEC3F_DIV1000(scale, 100, ICHAIN_STOP), }; -#endif +AnimatedMaterial* D_80C16470; -extern InitChainEntry D_80C16420[]; +extern Gfx D_06000320[]; +extern Gfx D_06000430[]; +extern AnimatedMaterial D_060012E8; -extern UNK_TYPE D_06000430; -extern UNK_TYPE D_060012E8; +void ObjYado_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjYado* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Yado/ObjYado_Init.s") + Actor_ProcessInitChain(&this->actor, sInitChain); + D_80C16470 = (AnimatedMaterial*)Lib_SegmentedToVirtual(&D_060012E8); + this->isNight = gSaveContext.isNight; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Yado/ObjYado_Destroy.s") +void ObjYado_Destroy(Actor* thisx, GlobalContext* globalCtx) { +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Yado/ObjYado_Update.s") +void ObjYado_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjYado* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Obj_Yado/ObjYado_Draw.s") + this->isNight = gSaveContext.isNight; +} + +void ObjYado_Draw(Actor* thisx, GlobalContext* globalCtx) { + s32 pad; + ObjYado* this = THIS; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (this->isNight) { + gSPSegment(POLY_XLU_DISP++, 0x09, Gfx_PrimColor(globalCtx->state.gfxCtx, 128, 95, 95, 70, 155)); + gSPSegment(POLY_OPA_DISP++, 0x0A, Gfx_PrimColor(globalCtx->state.gfxCtx, 128, 0, 40, 40, 255)); + } else { + gSPSegment(POLY_XLU_DISP++, 0x09, Gfx_PrimColor(globalCtx->state.gfxCtx, 128, 255, 255, 215, 110)); + gSPSegment(POLY_OPA_DISP++, 0x0A, Gfx_PrimColor(globalCtx->state.gfxCtx, 128, 255, 255, 215, 255)); + } + + AnimatedMat_Draw(globalCtx, D_80C16470); + func_800BDFC0(globalCtx, D_06000430); + func_800BE03C(globalCtx, D_06000320); + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} diff --git a/src/overlays/actors/ovl_Obj_Yado/z_obj_yado.h b/src/overlays/actors/ovl_Obj_Yado/z_obj_yado.h index ee79705a2..28ffd63dc 100644 --- a/src/overlays/actors/ovl_Obj_Yado/z_obj_yado.h +++ b/src/overlays/actors/ovl_Obj_Yado/z_obj_yado.h @@ -7,7 +7,7 @@ struct ObjYado; typedef struct ObjYado { /* 0x000 */ Actor actor; - /* 0x144 */ char unk_144[0x4]; + /* 0x144 */ u8 isNight; } ObjYado; // size = 0x148 extern const ActorInit Obj_Yado_InitVars; diff --git a/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c b/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c index 2787b2ef4..0c0a72279 100644 --- a/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c +++ b/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.c @@ -1,10 +1,11 @@ /* * File: z_object_kankyo.c * Overlay: ovl_Object_Kankyo - * Description: + * Description: Snow, rain in Skull Kid backstory cutscene, and bubbles deep in Pinnacle Rock */ #include "z_object_kankyo.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define FLAGS 0x02000030 @@ -15,12 +16,17 @@ void ObjectKankyo_Destroy(Actor* thisx, GlobalContext* globalCtx); void ObjectKankyo_Update(Actor* thisx, GlobalContext* globalCtx); void ObjectKankyo_Draw(Actor* thisx, GlobalContext* globalCtx); +void ObjectKankyo_SetupAction(ObjectKankyo* this, ObjectKankyoActionFunc actionFunc); +void func_808DC18C(ObjectKankyo* this, GlobalContext* globalCtx); void func_808DCB7C(ObjectKankyo* this, GlobalContext* globalCtx); void func_808DCBF8(ObjectKankyo* this, GlobalContext* globalCtx); +void func_808DCDB4(ObjectKankyo* this, GlobalContext* globalCtx); +void func_808DD3C8(Actor* thisx, GlobalContext* globalCtx2); +void func_808DD970(Actor* thisx, GlobalContext* globalCtx2); +void func_808DDE9C(Actor* thisx, GlobalContext* globalCtx2); -void ObjectKankyo_SetupAction(ObjectKankyo* this, ObjectKankyoActionFunc actionFunc); +static f32 D_808DE5B0; -#if 0 const ActorInit Object_Kankyo_InitVars = { ACTOR_OBJECT_KANKYO, ACTORCAT_ITEMACTION, @@ -33,42 +39,694 @@ const ActorInit Object_Kankyo_InitVars = { (ActorFunc)ObjectKankyo_Draw, }; -#endif +static u16 D_808DE340 = 0; -extern UNK_TYPE D_01000000; +void ObjectKankyo_SetupAction(ObjectKankyo* this, ObjectKankyoActionFunc actionFunc) { + this->actionFunc = actionFunc; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/ObjectKankyo_SetupAction.s") +void func_808DBE8C(ObjectKankyo* this) { + ObjectKankyo_SetupAction(this, func_808DC18C); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DBE8C.s") +void func_808DBEB0(ObjectKankyo* this, GlobalContext* globalCtx) { + s32 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DBEB0.s") + D_808DE5B0 = 0.0f; + this->unk_144 = Rand_ZeroOne() * 360.0f; + this->unk_148 = Rand_ZeroOne() * 360.0f; + if (globalCtx->envCtx.unk_F2[2] == 128) { + D_808DE5B0 = 1.0f; + this->unk_114E = 1; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DBFB0.s") + for (i = 0; i < globalCtx->envCtx.unk_F2[2]; i++) { + this->unk_14C[i].unk_10 = Rand_ZeroOne() * -200.0f; + } + } else { + this->unk_114E = 0; + } + ObjectKankyo_SetupAction(this, func_808DCB7C); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DC038.s") +void func_808DBFB0(ObjectKankyo* this, GlobalContext* globalCtx) { + D_808DE5B0 = 0.0f; + this->unk_114E = 0; + this->unk_144 = Rand_ZeroOne() * 360.0f; + this->unk_148 = Rand_ZeroOne() * 360.0f; + this->unk_114C = D_808DE340; + D_808DE340++; + ObjectKankyo_SetupAction(this, func_808DCBF8); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/ObjectKankyo_Init.s") +void func_808DC038(ObjectKankyo* this, GlobalContext* globalCtx) { + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/ObjectKankyo_Destroy.s") + this->unk_144 = Rand_ZeroOne() * 360.0f; + this->unk_148 = Rand_ZeroOne() * 360.0f; + this->unk_114C = 0; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DC18C.s") + for (i = 0; i < ARRAY_COUNT(this->unk_14C); i++) { + this->unk_14C[i].unk_1C = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DC454.s") + ObjectKankyo_SetupAction(this, func_808DCDB4); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DCB7C.s") +void ObjectKankyo_Init(Actor* thisx, GlobalContext* globalCtx) { + ObjectKankyo* this = THIS; + s16 i; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DCBF8.s") + for (i = 0; i < ARRAY_COUNT(this->unk_14C); i++) { + this->unk_14C[i].unk_1C = 0; + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DCDB4.s") + this->actor.room = -1; + switch (this->actor.params) { + case 0: + func_808DBE8C(this); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/ObjectKankyo_Update.s") + case 2: + globalCtx->envCtx.unk_F2[2] = 0x80; + func_808DBFB0(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/ObjectKankyo_Draw.s") + case 1: + case 3: + func_808DBEB0(this, globalCtx); + break; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DD3C8.s") + case 4: + func_808DC038(this, globalCtx); + break; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DD970.s") +void ObjectKankyo_Destroy(Actor* thisx, GlobalContext* globalCtx) { + ObjectKankyo* this = THIS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DDE74.s") + Actor_MarkForDeath(&this->actor); +} +void func_808DC18C(ObjectKankyo* this, GlobalContext* globalCtx) { + s32 pad; + s32 pad2; + s32 pad3; + f32 magnitude; + f32 y; + f32 z; + f32 temp_f18; + Vec3f sp30; + f32 x; + f32 sp1C; + + x = globalCtx->view.at.x - globalCtx->view.eye.x; + y = globalCtx->view.at.y - globalCtx->view.eye.y; + z = globalCtx->view.at.z - globalCtx->view.eye.z; + magnitude = sqrtf(SQ(x) + SQ(y) + SQ(z)); + + temp_f18 = x / magnitude; + x = z / magnitude; + sp1C = (y / magnitude) * 120.0f; + + this->unk_14C[0].unk_00 = globalCtx->view.eye.x + (temp_f18 * 50.0f); + this->unk_14C[0].unk_04 = globalCtx->view.eye.y + sp1C; + this->unk_14C[0].unk_08 = globalCtx->view.eye.z + (x * 50.0f); + this->unk_14C[1].unk_00 = globalCtx->view.eye.x + (temp_f18 * 220.0f); + this->unk_14C[1].unk_08 = globalCtx->view.eye.z + (x * 220.0f); + this->unk_114C = 0; + this->unk_144 = 100.0f; + + if ((this->unk_14C[0].unk_00 < -252.0f) && (this->unk_14C[0].unk_00 > -500.0f)) { + if ((this->unk_14C[0].unk_08 > 3820.0f) && (this->unk_14C[0].unk_08 < 4150.0f)) { + this->unk_114C = 1; + this->unk_144 = 400.0f; + if (x < 0.0f) { + this->unk_14C[0].unk_00 = -350.0f; + this->unk_14C[0].unk_04 = globalCtx->view.eye.y + sp1C; + this->unk_14C[0].unk_08 = 3680.0f; + this->unk_14C[1].unk_00 = -350.0f; + this->unk_14C[1].unk_08 = 3680.0f; + } else { + this->unk_14C[0].unk_00 = -350.0f; + this->unk_14C[0].unk_04 = globalCtx->view.eye.y + sp1C; + this->unk_14C[0].unk_08 = 4280.0f; + this->unk_14C[1].unk_00 = -350.0f; + this->unk_14C[1].unk_08 = 4280.0f; + } + } + } + + magnitude = globalCtx->envCtx.windSpeed / 60.0f; + magnitude = CLAMP(magnitude, 0.0f, 1.0f); + + sp30.x = globalCtx->envCtx.windDir.x * magnitude; + sp30.y = globalCtx->envCtx.windDir.y + 100.0f; + sp30.z = globalCtx->envCtx.windDir.z * magnitude; + this->unk_14C[2].unk_00 = 0x4000 - Math_Vec3f_Pitch(&gZeroVec3f, &sp30); + this->unk_14C[2].unk_04 = Math_Vec3f_Yaw(&gZeroVec3f, &sp30) + 0x8000; +} + +void func_808DC454(ObjectKankyo* this, GlobalContext* globalCtx) { + s16 i; + u32 tempI; + f32 phi_f20; + f32 spD0; + f32 spCC; + f32 spC8; + f32 spC4; + f32 spC0; + f32 spBC; + f32 temp_f0_4; + f32 temp_f22; + f32 temp_f24; + f32 temp_f28; + f32 x = globalCtx->view.at.x - globalCtx->view.eye.x; + f32 y = globalCtx->view.at.y - globalCtx->view.eye.y; + f32 z = globalCtx->view.at.z - globalCtx->view.eye.z; + f32 magnitude = sqrtf(SQ(x) + SQ(y) + SQ(z)); + f32 temp_120 = 120.0f; + f32 temp_f30; + Vec3f sp88; + s32 pad; + + spD0 = x / magnitude; + spCC = y / magnitude; + spC8 = z / magnitude; + + for (i = 0; i < globalCtx->envCtx.unk_F2[2]; i++) { + switch (this->unk_14C[i].unk_1C) { + case 0: + this->unk_14C[i].unk_00 = globalCtx->view.eye.x + (spD0 * 120.0f); + this->unk_14C[i].unk_04 = globalCtx->view.eye.y + (spCC * 120.0f); + this->unk_14C[i].unk_08 = globalCtx->view.eye.z + (spC8 * 120.0f); + this->unk_14C[i].unk_0C = (Rand_ZeroOne() - 0.5f) * (2.0f * temp_120); + + temp_f22 = (func_800DFCB4(GET_ACTIVE_CAM(globalCtx)) * 0.004f) + 60.0f; + if (temp_f22 < 20.0f) { + temp_f22 = 20.0f; + } + + if (this->unk_114E == 0) { + this->unk_14C[i].unk_10 = temp_f22; + } else { + this->unk_14C[i].unk_10 += temp_f22; + tempI = i; + if (globalCtx->envCtx.unk_F2[2] == (tempI + 1)) { + this->unk_114E = 0; + } + } + + this->unk_14C[i].unk_14 = (Rand_ZeroOne() - 0.5f) * (2.0f * temp_120); + if (globalCtx->envCtx.unk_F2[4] == 0) { + this->unk_14C[i].unk_18 = (Rand_ZeroOne() * 3.0f) + 1.0f; + } else { + this->unk_14C[i].unk_18 = (Rand_ZeroOne() * 3.0f) + 8.0f; + } + this->unk_14C[i].unk_1C++; + break; + + case 1: + temp_f24 = globalCtx->view.eye.x + (spD0 * 120.0f); + temp_f28 = globalCtx->view.eye.y + (spCC * 120.0f); + temp_f30 = globalCtx->view.eye.z + (spC8 * 120.0f); + + magnitude = sqrtf((f32)SQ(globalCtx->envCtx.windDir.x) + SQ(globalCtx->envCtx.windDir.y) + + SQ(globalCtx->envCtx.windDir.z)); + if (magnitude == 0.0f) { + magnitude = 0.001f; + } + spC4 = -globalCtx->envCtx.windDir.x / magnitude; + spC0 = -globalCtx->envCtx.windDir.y / magnitude; + spBC = -globalCtx->envCtx.windDir.z / magnitude; + + if (i == 0) { + this->unk_144 += 0.049999997f * Rand_ZeroOne(); + this->unk_148 += 0.049999997f * Rand_ZeroOne(); + } + + phi_f20 = globalCtx->envCtx.windSpeed / 120.0f; + phi_f20 = CLAMP(phi_f20, 0.0f, 1.0f); + + this->unk_14C[i].unk_0C += __sinf((this->unk_144 + (i * 100.0f)) * 0.01f) + (spC4 * 10.0f * phi_f20); + this->unk_14C[i].unk_14 += __cosf((this->unk_148 + (i * 100.0f)) * 0.01f) + (spBC * 10.0f * phi_f20); + this->unk_14C[i].unk_10 -= + this->unk_14C[i].unk_18 - (spC0 * 3.0f * (globalCtx->envCtx.windSpeed / 100.0f)); + + temp_f22 = (-func_800DFCB4(GET_ACTIVE_CAM(globalCtx)) * 0.012f) + 40.0f; + if (temp_f22 < -40.0f) { + temp_f22 = -40.0f; + } + + if (((this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C) - temp_f24) > temp_120) { + this->unk_14C[i].unk_00 = temp_f24 - temp_120; + } + + if (((this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C) - temp_f24) < -temp_120) { + this->unk_14C[i].unk_00 = temp_f24 + temp_120; + } + + sp88.x = this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C; + sp88.y = this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10; + sp88.z = this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14; + + phi_f20 = Math_Vec3f_DistXZ(&sp88, &globalCtx->view.eye) / 200.0f; + phi_f20 = CLAMP(phi_f20, 0.0f, 1.0f); + temp_f0_4 = 100.0f + phi_f20 + 60.0f; + + if (temp_f0_4 < (this->unk_14C[i].unk_04 + (this->unk_14C[i].unk_10) - temp_f28)) { + this->unk_14C[i].unk_04 = temp_f28 - temp_f0_4; + } + + if (((this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10) - temp_f28) < -temp_f0_4) { + this->unk_14C[i].unk_04 = temp_f28 + temp_f0_4; + } + + if (((this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14) - temp_f30) > temp_120) { + this->unk_14C[i].unk_08 = temp_f30 - temp_120; + } + + if (((this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14) - temp_f30) < -temp_120) { + this->unk_14C[i].unk_08 = temp_f30 + temp_120; + } + + if ((this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10) < + ((globalCtx->view.eye.y - temp_f22) - 40.0f)) { + this->unk_14C[i].unk_1C = 0; + } + break; + } + } +} + +void func_808DCB7C(ObjectKankyo* this, GlobalContext* globalCtx) { + if (globalCtx->envCtx.unk_F2[2] < globalCtx->envCtx.unk_F2[3]) { + if ((globalCtx->state.frames % 16) == 0) { + globalCtx->envCtx.unk_F2[2] += 2; + } + } else if (globalCtx->envCtx.unk_F2[3] < globalCtx->envCtx.unk_F2[2]) { + if ((globalCtx->state.frames % 16) == 0) { + globalCtx->envCtx.unk_F2[2] -= 2; + } + } + func_808DC454(this, globalCtx); +} + +void func_808DCBF8(ObjectKankyo* this, GlobalContext* globalCtx) { + f32 temp_f0; + + if ((globalCtx->envCtx.unk_F2[2] > 0) && (this->unk_114C == 0)) { + if ((globalCtx->state.frames % 16) == 0) { + globalCtx->envCtx.unk_F2[2] -= 9; + if ((s8)globalCtx->envCtx.unk_F2[2] < 0) { + globalCtx->envCtx.unk_F2[2] = 0; + } + } + } + + temp_f0 = (f32)globalCtx->envCtx.unk_F2[2] / 128; + temp_f0 = CLAMP(temp_f0, 0.0f, 1.0f); + + if (temp_f0 > 0.01f) { + D_801F4E30 = 155.0f * temp_f0; + globalCtx->envCtx.unk_EA = 10; + } else { + D_801F4E30 = 0; + globalCtx->envCtx.unk_EA = 10; + } + func_808DC454(this, globalCtx); +} + +void func_808DCDB4(ObjectKankyo* this, GlobalContext* globalCtx) { + s16 i; + f32 magnitude; + f32 temp_80; + f32 temp_120; + f32 spAC; + f32 spA8; + f32 spA4; + f32 spA0; + f32 sp9C; + f32 x; + f32 y; + f32 z; + f32 temp_f18; + f32 temp_f20; + f32 temp_f26; + f32 temp_f28; + + if (this->unk_114C < 0x80) { + this->unk_114C++; + } + + x = globalCtx->view.at.x - globalCtx->view.eye.x; + y = globalCtx->view.at.y - globalCtx->view.eye.y; + z = globalCtx->view.at.z - globalCtx->view.eye.z; + + magnitude = sqrtf(SQ(x) + SQ(y) + SQ(z)); + + spAC = x / magnitude; + spA8 = y / magnitude; + spA4 = z / magnitude; + + temp_80 = 80.0f; + temp_120 = 120.0f; + + for (i = 0; i < this->unk_114C; i++) { + switch (this->unk_14C[i].unk_1C) { + case 0: + this->unk_14C[i].unk_00 = globalCtx->view.eye.x + (spAC * 120.0f); + this->unk_14C[i].unk_04 = globalCtx->view.eye.y + (spA8 * 120.0f); + this->unk_14C[i].unk_08 = globalCtx->view.eye.z + (spA4 * 120.0f); + this->unk_14C[i].unk_0C = (Rand_ZeroOne() - 0.5f) * (temp_120 * 2.0f); + if ((i % 2) == 0) { + this->unk_14C[i].unk_10 = -100.0f; + } else { + this->unk_14C[i].unk_10 = 100.0f; + } + this->unk_14C[i].unk_14 = (Rand_ZeroOne() - 0.5f) * (temp_120 * 2.0f); + this->unk_14C[i].unk_18 = Rand_ZeroOne() + 0.2f; + this->unk_14C[i].unk_1C++; + break; + + case 1: + + temp_f26 = globalCtx->view.eye.x + (spAC * 120.0f); + temp_f28 = globalCtx->view.eye.y + (spA8 * 120.0f); + temp_f18 = globalCtx->view.eye.z + (spA4 * 120.0f); + + magnitude = sqrtf((f32)SQ(globalCtx->envCtx.windDir.x) + SQ(globalCtx->envCtx.windDir.y) + + SQ(globalCtx->envCtx.windDir.z)); + if (magnitude == 0.0f) { + magnitude = 0.001f; + } + + spA0 = -globalCtx->envCtx.windDir.x / magnitude; + sp9C = -globalCtx->envCtx.windDir.z / magnitude; + + if (i == 0) { + this->unk_144 += 0.049999997f * Rand_ZeroOne(); + this->unk_148 += 0.049999997f * Rand_ZeroOne(); + } + temp_f20 = globalCtx->envCtx.windSpeed / 120.0f; + temp_f20 = CLAMP(temp_f20, 0.0f, 1.0f); + + this->unk_14C[i].unk_0C += __sinf((this->unk_144 + i) * 0.01f) + (spA0 * 10.0f * temp_f20); + this->unk_14C[i].unk_14 += __cosf((this->unk_148 + i) * 0.01f) + (sp9C * 10.0f * temp_f20); + + if ((i % 2) == 0) { + this->unk_14C[i].unk_10 += this->unk_14C[i].unk_18; + if ((this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10) > (globalCtx->view.eye.y + 100.0f)) { + this->unk_14C[i].unk_1C = 0; + } + } else { + this->unk_14C[i].unk_10 -= this->unk_14C[i].unk_18; + if ((this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10) < (globalCtx->view.eye.y - 100.0f)) { + this->unk_14C[i].unk_1C = 0; + } + } + + if (((this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C) - temp_f26) > temp_80) { + this->unk_14C[i].unk_00 = temp_f26 - temp_80; + } + + if (((this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C) - temp_f26) < -temp_80) { + this->unk_14C[i].unk_00 = temp_f26 + temp_80; + } + + if (((this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10) - temp_f28) > temp_80) { + this->unk_14C[i].unk_04 = temp_f28 - temp_80; + } + + if (((this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10) - temp_f28) < -temp_80) { + this->unk_14C[i].unk_04 = temp_f28 + temp_80; + } + + if (((this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14) - temp_f18) > temp_80) { + this->unk_14C[i].unk_08 = temp_f18 - temp_80; + } + + if (((this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14) - temp_f18) < -temp_80) { + this->unk_14C[i].unk_08 = temp_f18 + temp_80; + } + break; + } + } +} + +void ObjectKankyo_Update(Actor* thisx, GlobalContext* globalCtx) { + ObjectKankyo* this = THIS; + + this->actionFunc(this, globalCtx); +} + +void ObjectKankyo_Draw(Actor* thisx, GlobalContext* globalCtx) { + ObjectKankyo* this = THIS; + + switch (this->actor.params) { + case 0: + func_808DDE9C(thisx, globalCtx); + break; + + case 1: + case 2: + case 3: + func_808DD3C8(thisx, globalCtx); + break; + + case 4: + func_808DD970(thisx, globalCtx); + break; + } +} + +void func_808DD3C8(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + ObjectKankyo* this = THIS; + Vec3f spC4; + Vec3f spB8; + s16 i; + u8 pad2; + u8 spB4; + f32 temp_f0; + u8 sp68; + s32 pad; + f32 temp_f2; + f32 tempf; + + if ((globalCtx->cameraPtrs[MAIN_CAM]->flags2 & 0x100) || ((u8)globalCtx->envCtx.unk_E2 == 0)) { + return; + } + + OPEN_DISPS(globalCtx->state.gfxCtx); + spB4 = false; + + if (this->actor.params == 3) { + temp_f0 = func_80173B48(&globalCtx->state) / 1.4e7f; + temp_f0 = CLAMP(temp_f0, 0.0f, 1.0f); + Math_SmoothStepToF(&D_808DE5B0, temp_f0, 0.2f, 0.1f, 0.001f); + + sp68 = globalCtx->envCtx.unk_F2[2]; + sp68 *= D_808DE5B0; + + if ((globalCtx->envCtx.unk_F2[2] >= 32) && (sp68 < 32)) { + sp68 = 32; + } + } else { + sp68 = globalCtx->envCtx.unk_F2[2]; + } + + for (i = 0; i < sp68; i++) { + spC4.x = this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C; + spC4.y = this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10; + spC4.z = this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14; + func_80169474(globalCtx, &spC4, &spB8); + + if ((spB8.x >= 0.0f) && (spB8.x < 320.0f) && (spB8.y >= 0.0f) && (spB8.y < 240.0f)) { + if (!spB4) { + spB4 = true; + + gDPPipeSync(POLY_XLU_DISP++); + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, 255); + gSPClearGeometryMode(POLY_XLU_DISP++, G_LIGHTING); + + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0); + + gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_ZB_CLD_SURF2); + gSPSetGeometryMode(POLY_XLU_DISP++, G_FOG); + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gameplay_keep_Tex_08EBE0)); + } + + Matrix_InsertTranslation(spC4.x, spC4.y, spC4.z, MTXMODE_NEW); + tempf = (i & 7) * 0.008f; + Matrix_Scale(0.05f + tempf, 0.05f + tempf, 0.05f + tempf, MTXMODE_APPLY); + temp_f2 = Math_Vec3f_DistXYZ(&spC4, &globalCtx->view.eye) / 300.0f; + temp_f2 = ((1.0f < temp_f2) ? 0.0f : (((1.0f - temp_f2) > 1.0f) ? 1.0f : 1.0f - temp_f2)); + + gDPPipeSync(POLY_XLU_DISP++); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, (u8)(160.0f * temp_f2)); + + Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_023130); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +void func_808DD970(Actor* thisx, GlobalContext* globalCtx2) { + f32 temp_f0; + f32 temp_f20; + Vec3f spBC; + Vec3f spB0; + f32 tempf; + s16 i; + f32 phi_f26; + GlobalContext* globalCtx = globalCtx2; + ObjectKankyo* this = THIS; + f32 tempA; + + if (globalCtx->sceneNum == SCENE_KYOJINNOMA) { + phi_f26 = 1.0f; + } else { + tempA = func_800E031C(GET_ACTIVE_CAM(globalCtx)); + if (tempA != BGCHECK_Y_MIN) { + tempA -= globalCtx->view.eye.y; + phi_f26 = tempA / 4000.0f; + } else { + phi_f26 = 0.0f; + } + + phi_f26 = CLAMP_MAX(phi_f26, 1.0f); + + if (!(globalCtx->cameraPtrs[MAIN_CAM]->flags2 & 0x100) || (phi_f26 == 0.0f)) { + return; + } + } + + OPEN_DISPS(globalCtx->state.gfxCtx); + + for (i = 0; i < this->unk_114C; i++) { + spBC.x = this->unk_14C[i].unk_00 + this->unk_14C[i].unk_0C; + spBC.y = this->unk_14C[i].unk_04 + this->unk_14C[i].unk_10; + spBC.z = this->unk_14C[i].unk_08 + this->unk_14C[i].unk_14; + func_80169474(globalCtx, &spBC, &spB0); + + if ((spB0.x >= 0.0f) && (spB0.x < 320.0f) && (spB0.y >= 0.0f) && (spB0.y < 240.0f)) { + Matrix_InsertTranslation(spBC.x, spBC.y, spBC.z, MTXMODE_NEW); + Matrix_Scale(0.03f, 0.03f, 0.03f, MTXMODE_APPLY); + temp_f0 = Math_Vec3f_DistXYZ(&spBC, &globalCtx->view.eye); + temp_f0 = (u8)(255.0f * phi_f26) * (1.0f - (temp_f0 / 300.0f)); + + gDPPipeSync(POLY_XLU_DISP++); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 55, temp_f0); + gDPSetEnvColor(POLY_XLU_DISP++, 55, 50, 255, temp_f0); + + Matrix_InsertMatrix(&globalCtx->billboardMtxF, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPSegment(POLY_XLU_DISP++, 0x08, Lib_SegmentedToVirtual(gameplay_keep_Tex_08EBE0)); + gSPClearGeometryMode(POLY_XLU_DISP++, G_LIGHTING); + + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 0); + + gDPSetRenderMode(POLY_XLU_DISP++, G_RM_FOG_SHADE_A, G_RM_ZB_CLD_SURF2); + gSPSetGeometryMode(POLY_XLU_DISP++, G_FOG); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_023130); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} + +f32 func_808DDE74(void) { + return Rand_ZeroOne() - 0.5f; +} + +#ifdef NON_MATCHING +// globalCtx->envCtx.unk_F2[1] needs to be laoded into s0 and then copied to s7 +void func_808DDE9C(Actor* thisx, GlobalContext* globalCtx2) { + GlobalContext* globalCtx = globalCtx2; + ObjectKankyo* this = THIS; + Player* player = GET_PLAYER(globalCtx); + s32 i; + s16 temp; + f32 temp_f12; + f32 temp_f20; + f32 temp_f22; + f32 temp_f2; + u8 phi_s5; + s32 end = globalCtx->envCtx.unk_F2[1]; + + OPEN_DISPS(globalCtx->state.gfxCtx); + + if (end != 0) { + gDPPipeSync(POLY_XLU_DISP++); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 150, 255, 255, 25); + POLY_XLU_DISP = Gfx_CallSetupDL(POLY_XLU_DISP, 20); + } + + for (i = 0; i < end; i++) { + temp_f20 = this->unk_14C[0].unk_00 + ((Rand_ZeroOne() - 0.7f) * this->unk_144); + temp_f22 = this->unk_14C[0].unk_04 + ((Rand_ZeroOne() - 0.7f) * this->unk_144); + temp_f2 = this->unk_14C[0].unk_08 + ((Rand_ZeroOne() - 0.7f) * this->unk_144); + + if ((temp_f20 < -252.0f) && (temp_f20 > -500.0f) && (temp_f2 > 3820.0f) && (temp_f2 < 4150.0f)) { + continue; + } + + Matrix_InsertTranslation(temp_f20, temp_f22, temp_f2, MTXMODE_NEW); + + gSPMatrix(POLY_XLU_DISP++, &D_01000000, G_MTX_NOPUSH | G_MTX_MUL | G_MTX_MODELVIEW); + + Matrix_RotateY((s16)this->unk_14C[2].unk_04 + (s16)(i << 5), MTXMODE_APPLY); + Matrix_InsertXRotation_s((s16)this->unk_14C[2].unk_00 + (s16)(i << 5), MTXMODE_APPLY); + + if (this->unk_114C == 0) { + Matrix_Scale(0.5f, 1.0f, 0.5f, MTXMODE_APPLY); + } else { + Matrix_Scale(2.0f, 4.0f, 2.0f, MTXMODE_APPLY); + } + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_0706E0); + } + + phi_s5 = false; + if (player->actor.floorHeight < globalCtx->view.eye.y) { + for (i = 0; i < end; i++) { + if (!phi_s5) { + func_8012C2DC(globalCtx->state.gfxCtx); + + gDPSetEnvColor(POLY_XLU_DISP++, 255, 255, 255, 255); + gDPSetPrimColor(POLY_XLU_DISP++, 0, 0, 255, 255, 255, 100); + phi_s5++; + } + + temp_f20 = this->unk_14C[1].unk_00 + (func_808DDE74() * 220.0f); + temp_f22 = player->actor.floorHeight + 2.0f; + temp_f2 = this->unk_14C[1].unk_08 + (func_808DDE74() * 220.0f); + + if ((temp_f20 < -252.0f) && (temp_f20 > -500.0f) && (temp_f2 > 3820.0f) && (temp_f2 < 4150.0f)) { + continue; + } + + Matrix_InsertTranslation(temp_f20, temp_f22, temp_f2, MTXMODE_NEW); + temp_f12 = (Rand_ZeroOne() * 0.05f) + 0.05f; + Matrix_Scale(temp_f12, temp_f12, temp_f12, MTXMODE_APPLY); + + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), + G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + gSPDisplayList(POLY_XLU_DISP++, gameplay_keep_DL_030100); + } + } + + CLOSE_DISPS(globalCtx->state.gfxCtx); +} +#else #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Object_Kankyo/func_808DDE9C.s") +#endif diff --git a/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h b/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h index f61d140d8..646863be0 100644 --- a/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h +++ b/src/overlays/actors/ovl_Object_Kankyo/z_object_kankyo.h @@ -7,9 +7,24 @@ struct ObjectKankyo; typedef void (*ObjectKankyoActionFunc)(struct ObjectKankyo*, GlobalContext*); +typedef struct { + /* 0x00 */ f32 unk_00; + /* 0x04 */ f32 unk_04; + /* 0x08 */ f32 unk_08; + /* 0x0C */ f32 unk_0C; + /* 0x10 */ f32 unk_10; + /* 0x14 */ f32 unk_14; + /* 0x18 */ f32 unk_18; + /* 0x1C */ u8 unk_1C; +} ObjectKankyoStruct; // size = 0x20 + typedef struct ObjectKankyo { /* 0x0000 */ Actor actor; - /* 0x0144 */ char unk_144[0x100C]; + /* 0x0144 */ f32 unk_144; + /* 0x0148 */ f32 unk_148; + /* 0x014C */ ObjectKankyoStruct unk_14C[128]; + /* 0x114C */ u16 unk_114C; + /* 0x114E */ u8 unk_114E; /* 0x1150 */ ObjectKankyoActionFunc actionFunc; } ObjectKankyo; // size = 0x1154 diff --git a/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.c b/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.c index bd9b0c4e4..4b1e1d8ba 100644 --- a/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.c +++ b/src/overlays/actors/ovl_Oceff_Spot/z_oceff_spot.c @@ -1,7 +1,7 @@ /* * File: z_oceff_spot.c * Overlay: ovl_Oceff_Spot - * Description: + * Description: Sun's Song Ocarina Effect */ #include "z_oceff_spot.h" diff --git a/src/overlays/actors/ovl_Oceff_Storm/z_oceff_storm.c b/src/overlays/actors/ovl_Oceff_Storm/z_oceff_storm.c index 14860ee61..781e50605 100644 --- a/src/overlays/actors/ovl_Oceff_Storm/z_oceff_storm.c +++ b/src/overlays/actors/ovl_Oceff_Storm/z_oceff_storm.c @@ -1,7 +1,7 @@ /* * File: z_oceff_storm.c * Overlay: ovl_Oceff_Storm - * Description: + * Description: Song of Storms Ocarina Effect */ #include "z_oceff_storm.h" diff --git a/src/overlays/actors/ovl_Oceff_Wipe/z_oceff_wipe.c b/src/overlays/actors/ovl_Oceff_Wipe/z_oceff_wipe.c index 087dd5ecf..b5dd2f290 100644 --- a/src/overlays/actors/ovl_Oceff_Wipe/z_oceff_wipe.c +++ b/src/overlays/actors/ovl_Oceff_Wipe/z_oceff_wipe.c @@ -1,7 +1,7 @@ /* * File: z_oceff_wipe.c * Overlay: ovl_Oceff_Wipe - * Description: + * Description: Song of Time Ocarina Effect */ #include "z_oceff_wipe.h" diff --git a/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.c b/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.c index 1caac073e..aee5dd446 100644 --- a/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.c +++ b/src/overlays/actors/ovl_Oceff_Wipe2/z_oceff_wipe2.c @@ -1,7 +1,7 @@ /* * File: z_oceff_wipe2.c * Overlay: ovl_Oceff_Wipe2 - * Description: + * Description: Epona's Song Ocarina Effect */ #include "z_oceff_wipe2.h" diff --git a/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.c b/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.c index cf0fabe94..0ef0a25e8 100644 --- a/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.c +++ b/src/overlays/actors/ovl_Oceff_Wipe3/z_oceff_wipe3.c @@ -1,7 +1,7 @@ /* * File: z_oceff_wipe3.c * Overlay: ovl_Oceff_Wipe3 - * Description: + * Description: Unused OoT Saria's Song Ocarina Effect */ #include "z_oceff_wipe3.h" diff --git a/src/overlays/actors/ovl_Oceff_Wipe4/z_oceff_wipe4.c b/src/overlays/actors/ovl_Oceff_Wipe4/z_oceff_wipe4.c index 99e9e2048..b9a89614b 100644 --- a/src/overlays/actors/ovl_Oceff_Wipe4/z_oceff_wipe4.c +++ b/src/overlays/actors/ovl_Oceff_Wipe4/z_oceff_wipe4.c @@ -1,7 +1,7 @@ /* * File: z_oceff_wipe4.c * Overlay: ovl_Oceff_Wipe4 - * Description: + * Description: Scarecrow's Song Ocarina Effect */ #include "z_oceff_wipe4.h" diff --git a/src/overlays/actors/ovl_Oceff_Wipe5/z_oceff_wipe5.c b/src/overlays/actors/ovl_Oceff_Wipe5/z_oceff_wipe5.c index 637d91cc7..8cac4317d 100644 --- a/src/overlays/actors/ovl_Oceff_Wipe5/z_oceff_wipe5.c +++ b/src/overlays/actors/ovl_Oceff_Wipe5/z_oceff_wipe5.c @@ -1,7 +1,7 @@ /* * File: z_oceff_wipe5.c * Overlay: ovl_Oceff_Wipe5 - * Description: + * Description: Sonata/Lullaby/Bossa Nova/Elegy/Oath Ocarina Effect */ #include "z_oceff_wipe5.h" diff --git a/src/overlays/actors/ovl_Oceff_Wipe6/z_oceff_wipe6.c b/src/overlays/actors/ovl_Oceff_Wipe6/z_oceff_wipe6.c index 365475ac2..c14a59e9f 100644 --- a/src/overlays/actors/ovl_Oceff_Wipe6/z_oceff_wipe6.c +++ b/src/overlays/actors/ovl_Oceff_Wipe6/z_oceff_wipe6.c @@ -1,7 +1,7 @@ /* * File: z_oceff_wipe6.c * Overlay: ovl_Oceff_Wipe6 - * Description: + * Description: Song of Soaring Ocarina Effect */ #include "z_oceff_wipe6.h" diff --git a/src/overlays/actors/ovl_Oceff_Wipe7/z_oceff_wipe7.c b/src/overlays/actors/ovl_Oceff_Wipe7/z_oceff_wipe7.c index 1adf9d44c..f03130343 100644 --- a/src/overlays/actors/ovl_Oceff_Wipe7/z_oceff_wipe7.c +++ b/src/overlays/actors/ovl_Oceff_Wipe7/z_oceff_wipe7.c @@ -1,7 +1,7 @@ /* * File: z_oceff_wipe7.c * Overlay: ovl_Oceff_Wipe7 - * Description: + * Description: Song of Healing Ocarina Effect */ #include "z_oceff_wipe7.h" diff --git a/src/overlays/actors/ovl_Player_Actor/overlay.cfg b/src/overlays/actors/ovl_Player_Actor/overlay.cfg deleted file mode 100644 index 6dea57e3f..000000000 --- a/src/overlays/actors/ovl_Player_Actor/overlay.cfg +++ /dev/null @@ -1,2 +0,0 @@ -ovl_Player_Actor -z_player.c diff --git a/src/overlays/actors/ovl_Player_Actor/z_player.c b/src/overlays/actors/ovl_Player_Actor/z_player.c deleted file mode 100644 index 2d5b3d59a..000000000 --- a/src/overlays/actors/ovl_Player_Actor/z_player.c +++ /dev/null @@ -1,1297 +0,0 @@ -/* - * File: z_player.c - * Overlay: ovl_Player_Actor - * Description: Player - */ - -#include "global.h" - -#define THIS ((Player*)thisx) - -extern UNK_TYPE D_06008860; -extern UNK_TYPE D_0600BDD8; -extern UNK_TYPE D_060178D0; - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082DA90.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082DABC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082DAD4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082DAFC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082DB18.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082DB3C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082DB60.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082DB90.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082DBC0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082DC28.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082DC38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082DC64.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082DCA0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082DD2C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082DE14.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082DE50.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082DE88.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082DF2C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082DF48.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082DF8C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E00C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E078.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E094.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E0CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E0F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E12C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E188.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E1BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E1F0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E224.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E438.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E4A4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E514.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E55C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E5A8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E5EC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E634.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E67C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E6D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E6F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E784.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E794.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E820.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E920.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082E9C8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082EA10.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082EA38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082EA60.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082EA80.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082EAC8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082EAF0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082EB18.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082EB38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082EC9C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082ECCC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082ECE0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082ED20.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082ED94.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082EEA4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082EEE0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082EF20.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082EF54.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082EF9C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082EFE4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082F02C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082F09C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082F0E4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082F164.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082F1AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082F43C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082F470.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082F524.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082F594.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082F5A4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082F5C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082F5FC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082F62C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082F7F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082F8A0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082F8BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082F938.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082FA5C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082FB68.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082FBE8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082FC24.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082FC60.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082FC78.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082FCC4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082FD0C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082FDC4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8082FE0C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808302CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808304BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808305BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808306F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808308DC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808309CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80830A58.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80830AE8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80830B38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80830B88.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80830CE8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80830D40.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80830DF0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80830E30.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80830F9C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80830FD4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80831010.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80831094.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80831124.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80831194.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083133C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808313A8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808313F0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80831454.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80831494.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083172C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80831760.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808317C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80831814.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808318C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80831944.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80831990.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80831F34.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80832090.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083213C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083216C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808323C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80832444.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083249C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808324EC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80832558.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80832578.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80832660.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80832754.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80832888.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80832CAC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80832F24.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80832F78.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80833058.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808331FC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808332A0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808333CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808334D4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808335B0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808335F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80833728.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083375C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80833864.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80833998.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808339B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808339D4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80833A64.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80833AA0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80833B18.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808340AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808340D4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80834104.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80834140.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808341F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808344C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80834534.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083456C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808345A8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808345C8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80834600.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80834CD0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80834D50.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80834DB8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80834DFC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80835324.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808353DC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80835428.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808354A4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808355D8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083562C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80835BC8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80835BF8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80835C64.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80835CD8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80835D2C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80835D58.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80835DF8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80835EAC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083604C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80836258.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808365DC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80836888.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083692C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80836988.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808369F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80836A5C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80836A98.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80836AD8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80836B3C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80836C70.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80836D8C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80836DC0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80836EA0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80836F10.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808370D4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80837134.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808373A4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808373F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80837730.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083784C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808378FC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083798C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808379C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80837B60.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80837BD0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80837BF8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80837C20.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80837C78.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80837CEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80837DEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808381A0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808381F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083827C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083868C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80838760.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808387A0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80838830.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808388B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808389BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80838A20.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80838A90.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808391D8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80839518.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808395F0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808396B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80839770.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80839800.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80839860.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80839978.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80839A10.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80839A84.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80839B18.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80839CD8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80839E3C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80839E74.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80839ED0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80839F98.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083A04C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083A0CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083A114.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083A274.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083A4A4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083A548.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083A580.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083A658.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083A6C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083A794.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083A844.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083A878.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083A98C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083AD04.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083AD8C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083ADB8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083ADF0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083AE38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083AECC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083AF30.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083AF8C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083B030.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083B090.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083B0E4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083B1A0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083B23C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083B29C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083B2E4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083B32C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083B3B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083B73C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083B798.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083B850.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083B8D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083B930.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083BB4C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083BF54.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083C62C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083C6E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083C85C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083C8E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083CB04.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083CB58.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083CBC4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083CCB4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083CF68.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083D168.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083D23C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083D6DC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083D738.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083D78C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083D860.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083DCC4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083DD1C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083DEE4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083DF38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083DFC4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083E14C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083E234.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083E28C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083E2F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083E354.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083E404.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083E514.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083E758.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083E7F8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083E8E0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083E958.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083E9C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083EA44.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083EBD0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083EE60.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083F144.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083F190.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083F230.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083F27C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083F358.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083F57C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083F828.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083F8A8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083FBC4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083FCF0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083FD80.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083FE38.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083FE90.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083FEF4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083FF30.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8083FFEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80840094.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808400CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808401F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80840770.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80840980.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808409A8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80840A30.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80840CD4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80840DEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80840E24.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80840E5C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80840EC0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80840F34.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80840F90.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808411D4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808412A0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808412BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80841358.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80841408.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808414E0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80841528.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808415A0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808415E4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80841624.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80841744.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084182C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80841A50.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80841AC4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80842510.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808425B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808426F0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808430E0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80843178.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80843EC0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808442D8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808445C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808446F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80844784.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80844D80.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80844EF8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808460B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808463C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80846460.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80846528.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808470D4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80847190.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084748C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808475B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808477D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80847880.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80847994.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808479F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80847A50.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80847A94.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80847BF0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80847E2C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80847ED4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80847F1C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80847FF8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80848048.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80848094.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808481CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80848250.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80848294.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808482E0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808484CC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808484F0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80848570.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80848640.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80848780.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808487B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80848808.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084894C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80848A0C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80848AB0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80848B6C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80848BF4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80848E4C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80849054.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808490B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808491B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084923C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808492C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084933C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80849570.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80849620.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808496AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808497A0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80849A9C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80849DD0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80849FE0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084A26C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084A5C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084A794.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084A884.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084A8E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084AB4C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084AC84.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084AEEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084AF9C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084B0EC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084B288.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084B3B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084B4A8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084B5C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084BAA4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084BBF0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084BC64.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084BE40.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084BF28.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084BFDC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084C124.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084C16C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084C6EC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084C94C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084CA24.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084CB58.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084CCEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084CE84.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084D18C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084D4EC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084D770.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084D820.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084E034.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084E25C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084E334.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084E434.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084E4E4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084E58C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084E65C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084E724.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084E980.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084ED9C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084EE50.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084EF9C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084F1B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084F3DC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084F4E8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084FC0C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084FD7C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084FE48.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8084FE7C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808505D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80850734.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80850854.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808508C8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80850B18.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80850BA8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80850BF8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80850D20.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80850D68.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808513EC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80851588.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808516B4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808519FC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80851B58.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80851BD4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80851C40.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80851D30.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80851EAC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80851EC8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80851F18.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808521E0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80852290.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085255C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808525C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085269C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80852B28.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80852C04.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80852FD4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808530E0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80853194.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808534C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80853754.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80853850.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80853A5C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80853CC0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80853D68.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80854010.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808540A0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80854118.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085421C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085437C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085439C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80854430.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80854614.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808546D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80854800.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808548B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80854C70.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80854CD0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80854EFC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808550D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80855218.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808553F4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80855818.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80855A7C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80855AF4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80855B9C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80855C28.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80855E08.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80855F9C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80856000.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80856074.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80856110.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808561B0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808566C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085687C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80856888.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80856918.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808573A4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80857640.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808576BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808577E0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80857950.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80857A44.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80857AEC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80857BE8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80858C84.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80858CC8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80858D48.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80858DB4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80858DDC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80858DFC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80858E40.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80858E60.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80858E80.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80858EA0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80858EC0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80858EFC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80858F1C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80858F3C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80858F5C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80858F7C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80858F9C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80858FBC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80858FE8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859028.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859168.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808591BC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859210.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859248.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085929C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859300.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859414.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808594D0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808595B8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085968C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859708.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085978C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859890.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859990.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_808599DC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859A10.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859A44.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859AD0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859AF8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859B28.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859B54.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859BA8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859C60.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859CA0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859CE0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859CFC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859D44.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859D70.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859EBC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859F4C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859FCC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_80859FF4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085A04C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085A120.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085A144.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085A19C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085A1D4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085A24C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085A2AC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085A330.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085A364.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085A40C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085A4A4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085A530.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085A5DC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085A66C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085A6C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085A710.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085A768.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085A7C0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085A8C4.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085A940.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085AA10.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085AA60.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085AA84.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085AACC.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085AB58.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085ABA8.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085AC9C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085AD5C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085ADA0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085B08C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085B134.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085B170.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085B1F0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085B28C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085B384.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085B3E0.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085B460.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085B74C.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085B820.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085B854.s") - -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Player_Actor/func_8085B930.s") diff --git a/src/overlays/actors/ovl_TG_Sw/z_tg_sw.c b/src/overlays/actors/ovl_TG_Sw/z_tg_sw.c index d1a6afb3e..9dcf3ab15 100644 --- a/src/overlays/actors/ovl_TG_Sw/z_tg_sw.c +++ b/src/overlays/actors/ovl_TG_Sw/z_tg_sw.c @@ -56,7 +56,7 @@ void TGSw_ActionExecuteOneShot(TGSw* this, GlobalContext* globalCtx) { if (1) {} do { - actor = func_ActorCategoryIterateById(globalCtx, actor, ACTORCAT_ENEMY, ACTOR_EN_SW); + actor = SubS_FindActor(globalCtx, actor, ACTORCAT_ENEMY, ACTOR_EN_SW); if (actor == NULL) { break; } @@ -71,7 +71,7 @@ void TGSw_ActionExecuteOneShot(TGSw* this, GlobalContext* globalCtx) { actor = NULL; do { - actor = func_ActorCategoryIterateById(globalCtx, actor, ACTORCAT_NPC, ACTOR_EN_SW); + actor = SubS_FindActor(globalCtx, actor, ACTORCAT_NPC, ACTOR_EN_SW); if (actor == NULL) { break; diff --git a/src/overlays/actors/ovl_player_actor/overlay.cfg b/src/overlays/actors/ovl_player_actor/overlay.cfg new file mode 100644 index 000000000..2d4849235 --- /dev/null +++ b/src/overlays/actors/ovl_player_actor/overlay.cfg @@ -0,0 +1,2 @@ +ovl_player_actor +z_player.c diff --git a/src/overlays/actors/ovl_player_actor/z_player.c b/src/overlays/actors/ovl_player_actor/z_player.c new file mode 100644 index 000000000..6a5fa0423 --- /dev/null +++ b/src/overlays/actors/ovl_player_actor/z_player.c @@ -0,0 +1,1297 @@ +/* + * File: z_player.c + * Overlay: ovl_player_actor + * Description: Player + */ + +#include "global.h" + +#define THIS ((Player*)thisx) + +extern UNK_TYPE D_06008860; +extern UNK_TYPE D_0600BDD8; +extern UNK_TYPE D_060178D0; + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082DA90.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082DABC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082DAD4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082DAFC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082DB18.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082DB3C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082DB60.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082DB90.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082DBC0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082DC28.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082DC38.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082DC64.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082DCA0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082DD2C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082DE14.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082DE50.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082DE88.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082DF2C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082DF48.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082DF8C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E00C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E078.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E094.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E0CC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E0F4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E12C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E188.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E1BC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E1F0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E224.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E438.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E4A4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E514.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E55C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E5A8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E5EC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E634.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E67C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E6D0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E6F8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E784.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E794.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E820.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E920.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082E9C8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082EA10.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082EA38.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082EA60.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082EA80.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082EAC8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082EAF0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082EB18.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082EB38.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082EC9C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082ECCC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082ECE0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082ED20.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082ED94.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082EEA4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082EEE0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082EF20.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082EF54.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082EF9C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082EFE4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082F02C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082F09C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082F0E4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082F164.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082F1AC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082F43C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082F470.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082F524.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082F594.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082F5A4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082F5C0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082F5FC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082F62C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082F7F4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082F8A0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082F8BC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082F938.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082FA5C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082FB68.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082FBE8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082FC24.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082FC60.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082FC78.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082FCC4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082FD0C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082FDC4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8082FE0C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808302CC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808304BC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808305BC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808306F8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808308DC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808309CC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80830A58.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80830AE8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80830B38.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80830B88.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80830CE8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80830D40.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80830DF0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80830E30.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80830F9C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80830FD4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80831010.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80831094.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80831124.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80831194.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083133C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808313A8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808313F0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80831454.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80831494.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083172C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80831760.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808317C4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80831814.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808318C0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80831944.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80831990.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80831F34.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80832090.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083213C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083216C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808323C0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80832444.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083249C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808324EC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80832558.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80832578.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80832660.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80832754.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80832888.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80832CAC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80832F24.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80832F78.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80833058.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808331FC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808332A0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808333CC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808334D4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808335B0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808335F4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80833728.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083375C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80833864.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80833998.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808339B4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808339D4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80833A64.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80833AA0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80833B18.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808340AC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808340D4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80834104.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80834140.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808341F4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808344C0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80834534.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083456C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808345A8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808345C8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80834600.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80834CD0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80834D50.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80834DB8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80834DFC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80835324.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808353DC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80835428.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808354A4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808355D8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083562C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80835BC8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80835BF8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80835C64.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80835CD8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80835D2C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80835D58.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80835DF8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80835EAC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083604C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80836258.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808365DC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80836888.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083692C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80836988.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808369F4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80836A5C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80836A98.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80836AD8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80836B3C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80836C70.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80836D8C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80836DC0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80836EA0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80836F10.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808370D4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80837134.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808373A4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808373F8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80837730.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083784C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808378FC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083798C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808379C0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80837B60.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80837BD0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80837BF8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80837C20.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80837C78.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80837CEC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80837DEC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808381A0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808381F8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083827C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083868C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80838760.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808387A0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80838830.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808388B8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808389BC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80838A20.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80838A90.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808391D8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80839518.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808395F0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808396B8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80839770.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80839800.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80839860.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80839978.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80839A10.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80839A84.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80839B18.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80839CD8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80839E3C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80839E74.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80839ED0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80839F98.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083A04C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083A0CC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083A114.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083A274.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083A4A4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083A548.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083A580.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083A658.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083A6C0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083A794.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083A844.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083A878.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083A98C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083AD04.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083AD8C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083ADB8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083ADF0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083AE38.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083AECC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083AF30.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083AF8C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083B030.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083B090.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083B0E4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083B1A0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083B23C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083B29C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083B2E4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083B32C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083B3B4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083B73C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083B798.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083B850.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083B8D0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083B930.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083BB4C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083BF54.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083C62C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083C6E8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083C85C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083C8E8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083CB04.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083CB58.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083CBC4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083CCB4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083CF68.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083D168.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083D23C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083D6DC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083D738.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083D78C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083D860.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083DCC4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083DD1C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083DEE4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083DF38.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083DFC4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083E14C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083E234.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083E28C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083E2F4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083E354.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083E404.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083E514.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083E758.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083E7F8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083E8E0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083E958.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083E9C4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083EA44.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083EBD0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083EE60.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083F144.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083F190.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083F230.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083F27C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083F358.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083F57C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083F828.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083F8A8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083FBC4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083FCF0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083FD80.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083FE38.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083FE90.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083FEF4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083FF30.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8083FFEC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80840094.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808400CC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808401F4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80840770.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80840980.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808409A8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80840A30.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80840CD4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80840DEC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80840E24.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80840E5C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80840EC0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80840F34.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80840F90.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808411D4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808412A0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808412BC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80841358.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80841408.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808414E0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80841528.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808415A0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808415E4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80841624.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80841744.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084182C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80841A50.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80841AC4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80842510.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808425B4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808426F0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808430E0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80843178.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80843EC0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808442D8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808445C4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808446F4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80844784.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80844D80.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80844EF8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808460B8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808463C0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80846460.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80846528.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808470D4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80847190.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084748C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808475B4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808477D0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80847880.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80847994.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808479F4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80847A50.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80847A94.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80847BF0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80847E2C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80847ED4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80847F1C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80847FF8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80848048.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80848094.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808481CC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80848250.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80848294.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808482E0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808484CC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808484F0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80848570.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80848640.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80848780.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808487B8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80848808.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084894C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80848A0C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80848AB0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80848B6C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80848BF4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80848E4C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80849054.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808490B4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808491B4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084923C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808492C4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084933C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80849570.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80849620.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808496AC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808497A0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80849A9C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80849DD0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80849FE0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084A26C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084A5C0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084A794.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084A884.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084A8E8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084AB4C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084AC84.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084AEEC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084AF9C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084B0EC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084B288.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084B3B8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084B4A8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084B5C0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084BAA4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084BBF0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084BC64.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084BE40.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084BF28.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084BFDC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084C124.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084C16C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084C6EC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084C94C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084CA24.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084CB58.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084CCEC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084CE84.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084D18C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084D4EC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084D770.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084D820.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084E034.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084E25C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084E334.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084E434.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084E4E4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084E58C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084E65C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084E724.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084E980.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084ED9C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084EE50.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084EF9C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084F1B8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084F3DC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084F4E8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084FC0C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084FD7C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084FE48.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8084FE7C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808505D0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80850734.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80850854.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808508C8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80850B18.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80850BA8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80850BF8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80850D20.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80850D68.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808513EC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80851588.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808516B4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808519FC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80851B58.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80851BD4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80851C40.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80851D30.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80851EAC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80851EC8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80851F18.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808521E0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80852290.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085255C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808525C4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085269C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80852B28.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80852C04.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80852FD4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808530E0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80853194.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808534C0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80853754.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80853850.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80853A5C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80853CC0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80853D68.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80854010.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808540A0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80854118.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085421C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085437C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085439C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80854430.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80854614.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808546D0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80854800.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808548B8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80854C70.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80854CD0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80854EFC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808550D0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80855218.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808553F4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80855818.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80855A7C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80855AF4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80855B9C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80855C28.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80855E08.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80855F9C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80856000.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80856074.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80856110.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808561B0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808566C0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085687C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80856888.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80856918.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808573A4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80857640.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808576BC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808577E0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80857950.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80857A44.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80857AEC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80857BE8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80858C84.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80858CC8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80858D48.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80858DB4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80858DDC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80858DFC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80858E40.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80858E60.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80858E80.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80858EA0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80858EC0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80858EFC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80858F1C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80858F3C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80858F5C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80858F7C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80858F9C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80858FBC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80858FE8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859028.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859168.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808591BC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859210.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859248.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085929C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859300.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859414.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808594D0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808595B8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085968C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859708.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085978C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859890.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859990.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_808599DC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859A10.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859A44.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859AD0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859AF8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859B28.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859B54.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859BA8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859C60.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859CA0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859CE0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859CFC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859D44.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859D70.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859EBC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859F4C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859FCC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_80859FF4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085A04C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085A120.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085A144.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085A19C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085A1D4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085A24C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085A2AC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085A330.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085A364.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085A40C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085A4A4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085A530.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085A5DC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085A66C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085A6C0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085A710.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085A768.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085A7C0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085A8C4.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085A940.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085AA10.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085AA60.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085AA84.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085AACC.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085AB58.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085ABA8.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085AC9C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085AD5C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085ADA0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085B08C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085B134.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085B170.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085B1F0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085B28C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085B384.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085B3E0.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085B460.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085B74C.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085B820.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085B854.s") + +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_player_actor/func_8085B930.s") diff --git a/src/overlays/effects/ovl_Effect_Ss_Dead_Dd/z_eff_ss_dead_dd.c b/src/overlays/effects/ovl_Effect_Ss_Dead_Dd/z_eff_ss_dead_dd.c index 39f9e51d5..0d26eec89 100644 --- a/src/overlays/effects/ovl_Effect_Ss_Dead_Dd/z_eff_ss_dead_dd.c +++ b/src/overlays/effects/ovl_Effect_Ss_Dead_Dd/z_eff_ss_dead_dd.c @@ -20,8 +20,6 @@ const EffectSsInit Effect_Ss_Dead_Dd_InitVars = { #endif -extern UNK_TYPE D_01000000; - #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Dead_Dd/EffectSsDeadDd_Init.s") #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Dead_Dd/EffectSsDeadDd_Draw.s") diff --git a/src/overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.c b/src/overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.c index e4b3e791d..fe070b28d 100644 --- a/src/overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.c +++ b/src/overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.c @@ -8,50 +8,350 @@ #define PARAMS ((EffectSsKakeraInitParams*)initParamsx) -s32 EffectSsKakera_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); +u32 EffectSsKakera_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); void EffectSsKakera_Update(GlobalContext* globalCtx, u32 index, EffectSs* this); void EffectSsKakera_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this); -#if 0 +void func_8097E130(EffectSs* this, GlobalContext* globalCtx); + const EffectSsInit Effect_Ss_Kakera_InitVars = { EFFECT_SS_KAKERA, EffectSsKakera_Init, }; +KakeraColorStruct D_8097EAD8[] = { + { 0, { 255, 255, 255 } }, + { 0, { 235, 170, 130 } }, + { 1, { 210, 190, 170 } }, +}; +f32 D_8097EAE4[] = { 1.0f, 100.0f, 40.0f, 5.0f, 100.0f, 40.0f, 5.0f, 100.0f, 40.0f, 5.0f }; -#endif +u32 EffectSsKakera_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx) { + EffectSsKakeraInitParams* params = PARAMS; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/EffectSsKakera_Init.s") + this->pos = params->pos; + this->velocity = params->velocity; + this->life = params->life; + this->priority = 101; + if (params->dList != NULL) { + this->gfx = params->dList; + switch (params->objId) { + case GAMEPLAY_KEEP: + case GAMEPLAY_FIELD_KEEP: + case GAMEPLAY_DANGEON_KEEP: + this->regs[10] = KAKERA_OBJECT_DEFAULT; + break; + default: + this->regs[10] = params->objId; + func_8097E130(this, globalCtx); + break; + } + } else { + __assert("../z_eff_kakera.c", 193); + } + this->draw = EffectSsKakera_Draw; + this->update = EffectSsKakera_Update; + this->vec = params->unk_18; + this->regs[0] = params->unk_2C; + this->regs[1] = params->gravity; + this->regs[2] = Rand_ZeroOne() * 0x8000; + this->regs[3] = Rand_ZeroOne() * 0x8000; + this->regs[4] = params->unk_26; + this->regs[5] = params->unk_28; + this->regs[6] = params->unk_2A; + this->regs[7] = params->scale; + this->regs[8] = params->unk_30; + this->regs[9] = params->unk_32; + this->regs[12] = params->colorIdx; + return 1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097DE30.s") +f32 func_8097DE30(f32 center, f32 range) { + return (2.0f * (Rand_ZeroOne() * range) - range) + center; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/EffectSsKakera_Draw.s") +void EffectSsKakera_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this) { + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; + s16 pad; + f32 scale = this->regs[7] / 256.0f; + s32 colorIndex = this->regs[12]; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E130.s") + OPEN_DISPS(gfxCtx); + if (this->regs[10] != KAKERA_OBJECT_DEFAULT) { + if ((((this->regs[4] >> 7) & 1) << 7) == 0x80) { + gSPSegment(POLY_XLU_DISP++, 0x06, globalCtx->objectCtx.status[this->regs[11]].segment); + } else { + gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[this->regs[11]].segment); + } + } -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E19C.s") + Matrix_InsertTranslation(this->pos.x, this->pos.y, this->pos.z, MTXMODE_NEW); + Matrix_RotateY(this->regs[3], MTXMODE_APPLY); + Matrix_InsertXRotation_s(this->regs[2], MTXMODE_APPLY); + Matrix_Scale(scale, scale, scale, MTXMODE_APPLY); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E34C.s") + if ((((this->regs[4] >> 7) & 1) << 7) == 0x80) { + gSPMatrix(POLY_XLU_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C2DC(globalCtx->state.gfxCtx); + if (colorIndex >= 0) { + gDPSetPrimColor(POLY_XLU_DISP++, 0, D_8097EAD8[colorIndex].lod, D_8097EAD8[colorIndex].color.r, + D_8097EAD8[colorIndex].color.g, D_8097EAD8[colorIndex].color.b, 255); + } + gSPDisplayList(POLY_XLU_DISP++, this->gfx); + } else { + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C28C(globalCtx->state.gfxCtx); + if (colorIndex >= 0) { + gDPSetPrimColor(POLY_OPA_DISP++, 0, D_8097EAD8[colorIndex].lod, D_8097EAD8[colorIndex].color.r, + D_8097EAD8[colorIndex].color.g, D_8097EAD8[colorIndex].color.b, 255); + } + gSPDisplayList(POLY_OPA_DISP++, this->gfx); + } + CLOSE_DISPS(gfxCtx); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E368.s") +void func_8097E130(EffectSs* this, GlobalContext* globalCtx) { + this->regs[11] = Object_GetIndex(&globalCtx->objectCtx, this->regs[10]); + if ((this->regs[11] < 0) || (!Object_IsLoaded(&globalCtx->objectCtx, this->regs[11]))) { + this->life = 0; + this->draw = NULL; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E384.s") +void func_8097E19C(EffectSs* this) { + f32 range; + f32 temp_f12; + f32 temp_f16; + f32 temp_f2; + f32 temp_f18; + f32 temp_f0; + f32 temp_f20; + f32 temp_f2_2; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E3C0.s") + temp_f18 = this->regs[5] / 1024.0f; + temp_f20 = this->regs[6] / 1024.0f; + range = (this->regs[9] / 1024.0f) * 4.0f; + temp_f2 = this->velocity.x - func_8097DE30(0.0f, range); + temp_f16 = this->velocity.y - func_8097DE30(0.0f, range); + temp_f12 = this->velocity.z - func_8097DE30(0.0f, range); + temp_f0 = temp_f2 * temp_f18; + temp_f2_2 = SQ(temp_f2) * temp_f20; + if (temp_f2 > 0.0f) { + this->velocity.x -= (temp_f0 + temp_f2_2); + } else { + this->velocity.x -= (temp_f0 - temp_f2_2); + } + temp_f0 = temp_f16 * temp_f18; + temp_f2_2 = SQ(temp_f16) * temp_f20; + if (temp_f16 > 0.0f) { + this->velocity.y -= (temp_f0 + temp_f2_2); + } else { + this->velocity.y -= (temp_f0 - temp_f2_2); + } + if (temp_f12 > 0.0f) { + this->velocity.z -= (temp_f0 + temp_f2_2); + } else { + this->velocity.z -= (temp_f0 - temp_f2_2); + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E400.s") +void func_8097E34C(EffectSs* this) { + this->accel.x = this->accel.y = this->accel.z = 0.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E420.s") +f32 func_8097E368(f32 arg0, s32 arg1) { + return 1.0f; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E4B0.s") +f32 func_8097E384(f32 arg0, s32 index) { + if (D_8097EAE4[index] < arg0) { + return D_8097EAE4[index] / arg0; + } else { + return 1.0f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E4F0.s") +f32 func_8097E3C0(f32 arg0, s32 index) { + f32 square = SQ(arg0); -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E584.s") + if (D_8097EAE4[index] < square) { + return D_8097EAE4[index] / square; + } else { + return 1.0f; + } +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E660.s") +f32 func_8097E400(f32 arg0, s32 index) { + return func_8097E3C0(arg0, index); +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E698.s") +s32 func_8097E420(EffectSs* this, Vec3f* diff, f32 distance) { + static f32 D_8097EB0C[] = { 0.05f, 1.0f }; + f32 phi_f0; + s32 index = this->regs[0] & 3; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/func_8097E7E0.s") + if (index != 0) { + if (distance > 1.0f) { + phi_f0 = 1.0f / distance; + } else { + phi_f0 = 1.0f; + } + this->accel.x += D_8097EB0C[index - 1] * diff->z * phi_f0; + this->accel.z -= D_8097EB0C[index - 1] * diff->x * phi_f0; + } + return 1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Kakera/EffectSsKakera_Update.s") +s32 func_8097E4B0(EffectSs* this, Vec3f* diff, f32 distance) { + static f32 D_8097EB14[] = { 4.0f, 0.1f, 0.3f, 0.9f, -0.1f, -0.3f, -0.9f }; + s32 index = (this->regs[0] >> 2) & 7; + + if (index != 0) { + this->accel.y += D_8097EB14[index]; + } + return 1; +} + +s32 func_8097E4F0(EffectSs* this, Vec3f* diff, f32 distance) { + static f32 D_8097EB30[] = { 0.1f, 1.0f, 6.0f }; + f32 phi_f0; + s32 index = (this->regs[0] >> 5) & 3; + + if (index != 0) { + if (distance > 1.0f) { + phi_f0 = 1.0f / distance; + } else { + phi_f0 = 1.0f; + } + this->accel.x -= diff->x * D_8097EB30[index - 1] * phi_f0; + this->accel.z -= diff->z * D_8097EB30[index - 1] * phi_f0; + } + return 1; +} + +s32 func_8097E584(EffectSs* this, Vec3f* diff, f32 distance) { + static f32 (*D_8097EB3C[])(f32, + s32) = { func_8097E368, func_8097E384, func_8097E384, func_8097E384, func_8097E3C0, + func_8097E3C0, func_8097E3C0, func_8097E400, func_8097E400, func_8097E400 }; + f32 center; + f32 rand; + s32 index; + + index = (this->regs[0] >> 7) & 0xF; + center = D_8097EB3C[index](distance, index); + rand = func_8097DE30(center, (this->regs[9] * center) / 1024.0f); + this->accel.x *= rand; + this->accel.y *= rand; + this->accel.z *= rand; + this->accel.x += rand * 0.01f; + this->accel.y += rand * 0.01f; + this->accel.z += rand * 0.01f; + return 1; +} + +s32 func_8097E660(EffectSs* this, Vec3f* diff, f32 distance) { + this->accel.y += this->regs[1] / 256.0f; + return 1; +} + +s32 func_8097E698(EffectSs* this) { + Vec3f diff; + f32 distance; + + func_8097E34C(this); + diff.x = this->pos.x - this->vec.x; + diff.y = this->pos.y - this->vec.y; + diff.z = this->pos.z - this->vec.z; + distance = sqrtf(SQXYZ(diff)); + if (distance > 1000.0f) { + return false; + } + if (this->regs[0] != 0) { + if (func_8097E420(this, &diff, distance) == 0) { + return false; + } + if (func_8097E4B0(this, &diff, distance) == 0) { + return false; + } + if (func_8097E4F0(this, &diff, distance) == 0) { + return false; + } + if (func_8097E584(this, &diff, distance) == 0) { + return false; + } + } + if (func_8097E660(this, &diff, distance) == 0) { + return false; + } else { + return true; + } +} + +void func_8097E7E0(EffectSs* this, GlobalContext* globalCtx) { + static f32 D_8097EB64[] = { 10.0f, 20.0f, 40.0f }; + Player* player = GET_PLAYER(globalCtx); + + if (this->regs[8] == 0) { + if ((((this->regs[4] >> 4) & 1) << 4) == (1 << 4)) { + if (this->pos.y <= (player->actor.floorHeight - ((this->regs[4] >> 2) & 3))) { + this->regs[9] = 0; + this->regs[0] = 0; + this->regs[4] &= ~0x60; + this->accel.x = this->accel.y = this->accel.z = 0.0f; + this->velocity.x = this->velocity.y = this->velocity.z = 0.0f; + this->regs[5] = this->regs[9]; + this->regs[1] = this->regs[9]; + } + } else { + if (this->pos.y <= ((player->actor.floorHeight - ((this->regs[4] >> 2) & 3)) - 600.0f)) { + this->life = 0; + } + } + } else { + switch (this->regs[4] & 3) { + case 0: + this->regs[8] = 0; + break; + case 1: + if ((this->velocity.y < 0.0f) && + (BgCheck_SphVsFirstPoly(&globalCtx->colCtx, &this->pos, D_8097EB64[(this->regs[4] >> 2) & 3]))) { + this->velocity.x *= func_8097DE30(0.9f, 0.2f); + this->velocity.y *= -0.8f; + this->velocity.z *= func_8097DE30(0.9f, 0.2f); + if (this->regs[8] > 0) { + this->regs[8]--; + } + } + break; + case 2: + if (BgCheck_SphVsFirstPoly(&globalCtx->colCtx, &this->pos, D_8097EB64[(this->regs[4] >> 2) & 3])) { + this->regs[8] = 0; + } + break; + } + } +} + +void EffectSsKakera_Update(GlobalContext* globalCtx, u32 index, EffectSs* this) { + switch (((this->regs[4] >> 5) & 3) << 5) { + case 0x20: + this->regs[2] += 0x47B; + this->regs[3] += 0x139; + break; + case 0x40: + this->regs[2] += 0x1A7C; + this->regs[3] += 0x47B; + break; + case 0x60: + this->regs[2] += 0x3F27; + this->regs[3] += 0xCA1; + break; + } + func_8097E19C(this); + if (!func_8097E698(this)) { + this->life = 0; + } + func_8097E7E0(this, globalCtx); + if (this->regs[10] != KAKERA_OBJECT_DEFAULT) { + func_8097E130(this, globalCtx); + } +} diff --git a/src/overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h b/src/overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h index 12135eb7b..d55a683cd 100644 --- a/src/overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h +++ b/src/overlays/effects/ovl_Effect_Ss_Kakera/z_eff_ss_kakera.h @@ -11,6 +11,11 @@ typedef enum { /* 1 */ KAKERA_COLOR_BROWN } KakeraColorIndex; +typedef struct { + /* 0x0 */ u8 lod; + /* 0x1 */ Color_RGB8 color; +} KakeraColorStruct; // size = 0x4 + typedef struct { /* 0x00 */ Vec3f pos; /* 0x0C */ Vec3f velocity; @@ -29,6 +34,5 @@ typedef struct { /* 0x3C */ Gfx* dList; } EffectSsKakeraInitParams; // size = 0x40 -extern const EffectSsInit Effect_Ss_Kakera_InitVars; #endif diff --git a/src/overlays/effects/ovl_Effect_Ss_Stick/z_eff_ss_stick.c b/src/overlays/effects/ovl_Effect_Ss_Stick/z_eff_ss_stick.c index 2b4feda09..c49059262 100644 --- a/src/overlays/effects/ovl_Effect_Ss_Stick/z_eff_ss_stick.c +++ b/src/overlays/effects/ovl_Effect_Ss_Stick/z_eff_ss_stick.c @@ -1,27 +1,57 @@ /* * File: z_eff_ss_stick.c * Overlay: ovl_Effect_Ss_Stick - * Description: + * Description: Breaking Deku Stick Fragment */ #include "z_eff_ss_stick.h" +#include "objects/gameplay_keep/gameplay_keep.h" #define PARAMS ((EffectSsStickInitParams*)initParamsx) -s32 EffectSsStick_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); +u32 EffectSsStick_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx); void EffectSsStick_Update(GlobalContext* globalCtx, u32 index, EffectSs* this); void EffectSsStick_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this); -#if 0 const EffectSsInit Effect_Ss_Stick_InitVars = { EFFECT_SS_STICK, EffectSsStick_Init, }; -#endif +u32 EffectSsStick_Init(GlobalContext* globalCtx, u32 index, EffectSs* this, void* initParamsx) { + EffectSsStickInitParams* params = PARAMS; + Vec3f pos; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Stick/EffectSsStick_Init.s") + this->regs[0] = Object_GetIndex(&globalCtx->objectCtx, GAMEPLAY_KEEP); + pos = params->pos; + this->pos = pos; + this->vec = pos; + this->regs[1] = params->yaw; + this->velocity.x = Math_SinS(params->yaw) * 6.0f; + this->velocity.z = Math_CosS(params->yaw) * 6.0f; + this->life = 20; + this->draw = EffectSsStick_Draw; + this->update = EffectSsStick_Update; + this->velocity.y = 26.0f; + this->accel.y = -4.0f; + return 1; +} -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Stick/EffectSsStick_Draw.s") +void EffectSsStick_Draw(GlobalContext* globalCtx, u32 index, EffectSs* this) { + s32 pad; + GraphicsContext* gfxCtx = globalCtx->state.gfxCtx; -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_Effect_Ss_Stick/EffectSsStick_Update.s") + OPEN_DISPS(gfxCtx); + Matrix_InsertTranslation(this->pos.x, this->pos.y, this->pos.z, MTXMODE_NEW); + Matrix_Scale(0.01f, 0.0025f, 0.01f, MTXMODE_APPLY); + Matrix_InsertRotation(0, this->regs[1], 0, MTXMODE_APPLY); + gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW); + func_8012C28C(gfxCtx); + gSPSegment(POLY_OPA_DISP++, 0x06, globalCtx->objectCtx.status[this->regs[0]].segment); + gSPSegment(POLY_OPA_DISP++, 0x0C, D_801C0850); + gSPDisplayList(POLY_OPA_DISP++, gameplay_keep_DL_0032B0); + CLOSE_DISPS(gfxCtx); +} + +void EffectSsStick_Update(GlobalContext* globalCtx, u32 index, EffectSs* this) { +} diff --git a/src/overlays/effects/ovl_Effect_Ss_Stick/z_eff_ss_stick.h b/src/overlays/effects/ovl_Effect_Ss_Stick/z_eff_ss_stick.h index ec43b41bf..d44a6a468 100644 --- a/src/overlays/effects/ovl_Effect_Ss_Stick/z_eff_ss_stick.h +++ b/src/overlays/effects/ovl_Effect_Ss_Stick/z_eff_ss_stick.h @@ -8,6 +8,4 @@ typedef struct { /* 0x0C */ s16 yaw; } EffectSsStickInitParams; // size = 0x10 -extern const EffectSsInit Effect_Ss_Stick_InitVars; - #endif diff --git a/src/overlays/gamestates/ovl_daytelop/z_daytelop.c b/src/overlays/gamestates/ovl_daytelop/z_daytelop.c index 9069a6aca..1637e1978 100644 --- a/src/overlays/gamestates/ovl_daytelop/z_daytelop.c +++ b/src/overlays/gamestates/ovl_daytelop/z_daytelop.c @@ -5,8 +5,8 @@ */ #include "z_daytelop.h" -#include "static/daytelop_static/daytelop_static.h" -#include "static/icon_item_gameover_static/icon_item_gameover_static.h" +#include "misc/daytelop_static/daytelop_static.h" +#include "interface/icon_item_gameover_static/icon_item_gameover_static.h" // unused UNK_TYPE D_808158E0[] = { diff --git a/src/overlays/gamestates/ovl_title/z_title.c b/src/overlays/gamestates/ovl_title/z_title.c index 62a85c863..a98b8e24a 100644 --- a/src/overlays/gamestates/ovl_title/z_title.c +++ b/src/overlays/gamestates/ovl_title/z_title.c @@ -6,7 +6,7 @@ #include "z_title.h" #include "overlays/gamestates/ovl_opening/z_opening.h" -#include "static/nintendo_rogo_static/nintendo_rogo_static.h" +#include "misc/nintendo_rogo_static/nintendo_rogo_static.h" void Title_UpdateCounters(TitleContext* this) { if ((this->coverAlpha == 0) && (this->visibleDuration != 0)) { diff --git a/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c b/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c index e2fdb18c4..5573ecb11 100644 --- a/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c +++ b/src/overlays/kaleido_scope/ovl_kaleido_scope/z_kaleido_scope_NES.c @@ -60,10 +60,10 @@ extern UNK_TYPE D_0C006C00; #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_kaleido_scope/func_80827E08.s") -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_kaleido_scope/func_808283D8.s") +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_kaleido_scope/KaleidoScope_Draw.s") #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_kaleido_scope/func_808286D8.s") #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_kaleido_scope/func_80828788.s") -#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_kaleido_scope/func_8082895C.s") +#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_kaleido_scope/KaleidoScope_Update.s") diff --git a/tools/ZAPD/.gitrepo b/tools/ZAPD/.gitrepo index 94da913d0..ccd6c7d64 100644 --- a/tools/ZAPD/.gitrepo +++ b/tools/ZAPD/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/zeldaret/ZAPD.git branch = master - commit = 4f7b8393ec8a3abd59649c2ba669e951fb61f3d2 - parent = 346df1bbc8ca21673fe63d884b6734c23a4d9f4b + commit = fd5a7f434171a33b1b3eb2a3e112fdcee6d9262d + parent = 844c24e39c96b7a3f3a40035058bda6c91ed4bbf method = merge cmdver = 0.4.3 diff --git a/tools/ZAPD/ExporterTest/ExporterTest.vcxproj b/tools/ZAPD/ExporterTest/ExporterTest.vcxproj index a709a3509..839d45102 100644 --- a/tools/ZAPD/ExporterTest/ExporterTest.vcxproj +++ b/tools/ZAPD/ExporterTest/ExporterTest.vcxproj @@ -79,7 +79,7 @@ true - $(SolutionDir)\ZAPD\;$(SolutionDir)ZAPDUtils;$(SolutionDir)lib\tinyxml2;$(SolutionDir)lib\libgfxd;$(SolutionDir)lib\elfio;$(SolutionDir)lib\stb;$(ProjectDir);$(IncludePath) + $(ProjectDir)..\ZAPD\;$(ProjectDir)..\ZAPDUtils;$(ProjectDir)..\lib\tinyxml2;$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\lib\elfio;$(ProjectDir)..\lib\stb;$(ProjectDir);$(IncludePath) false @@ -120,6 +120,7 @@ true stdcpp17 stdc11 + MultiThreadedDebug Console @@ -156,4 +157,4 @@ - + \ No newline at end of file diff --git a/tools/ZAPD/ExporterTest/Main.cpp b/tools/ZAPD/ExporterTest/Main.cpp index 4f683a1ba..07fdbeece 100644 --- a/tools/ZAPD/ExporterTest/Main.cpp +++ b/tools/ZAPD/ExporterTest/Main.cpp @@ -1,7 +1,7 @@ -#include -#include -#include -#include +#include "CollisionExporter.h" +#include "Globals.h" +#include "RoomExporter.h" +#include "TextureExporter.h" enum class ExporterFileMode { diff --git a/tools/ZAPD/ExporterTest/Makefile b/tools/ZAPD/ExporterTest/Makefile index a2bfa9a81..42033b7c0 100644 --- a/tools/ZAPD/ExporterTest/Makefile +++ b/tools/ZAPD/ExporterTest/Makefile @@ -1,7 +1,7 @@ # Only used for standalone compilation, usually inherits these from the main makefile CXXFLAGS ?= -Wall -Wextra -O2 -g -std=c++17 -SRC_DIRS := $(shell find -type d -not -path "*build*") +SRC_DIRS := $(shell find . -type d -not -path "*build*") CPP_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.cpp)) H_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.h)) diff --git a/tools/ZAPD/ExporterTest/RoomExporter.cpp b/tools/ZAPD/ExporterTest/RoomExporter.cpp index c4a6844fb..6c5552d8f 100644 --- a/tools/ZAPD/ExporterTest/RoomExporter.cpp +++ b/tools/ZAPD/ExporterTest/RoomExporter.cpp @@ -1,24 +1,24 @@ #include "RoomExporter.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include "CollisionExporter.h" +#include "Utils/BinaryWriter.h" +#include "Utils/File.h" +#include "Utils/MemoryStream.h" +#include "ZRoom/Commands/SetCameraSettings.h" +#include "ZRoom/Commands/SetCollisionHeader.h" +#include "ZRoom/Commands/SetCsCamera.h" +#include "ZRoom/Commands/SetEchoSettings.h" +#include "ZRoom/Commands/SetEntranceList.h" +#include "ZRoom/Commands/SetLightingSettings.h" +#include "ZRoom/Commands/SetMesh.h" +#include "ZRoom/Commands/SetRoomBehavior.h" +#include "ZRoom/Commands/SetRoomList.h" +#include "ZRoom/Commands/SetSkyboxModifier.h" +#include "ZRoom/Commands/SetSkyboxSettings.h" +#include "ZRoom/Commands/SetSoundSettings.h" +#include "ZRoom/Commands/SetSpecialObjects.h" +#include "ZRoom/Commands/SetStartPositionList.h" +#include "ZRoom/Commands/SetTimeSettings.h" +#include "ZRoom/Commands/SetWind.h" void ExporterExample_Room::Save(ZResource* res, fs::path outPath, BinaryWriter* writer) { diff --git a/tools/ZAPD/ExporterTest/TextureExporter.h b/tools/ZAPD/ExporterTest/TextureExporter.h index ffe6001dc..41c4e79be 100644 --- a/tools/ZAPD/ExporterTest/TextureExporter.h +++ b/tools/ZAPD/ExporterTest/TextureExporter.h @@ -1,6 +1,6 @@ #pragma once -#include +#include "Utils/BinaryWriter.h" #include "ZResource.h" #include "ZTexture.h" diff --git a/tools/ZAPD/Jenkinsfile b/tools/ZAPD/Jenkinsfile index 051e5f998..ec9b56ac5 100644 --- a/tools/ZAPD/Jenkinsfile +++ b/tools/ZAPD/Jenkinsfile @@ -7,7 +7,7 @@ pipeline { // Non-parallel ZAPD stage stage('Build ZAPD') { steps { - sh 'make -j' + sh 'make -j WERROR=1' } } @@ -61,7 +61,7 @@ pipeline { sh 'cp ../ZAPD.out tools/ZAPD/' sh 'python3 tools/fixbaserom.py' sh 'python3 tools/extract_baserom.py' - sh 'python3 extract_assets.py -t 4' + sh 'python3 extract_assets.py -t$(nproc)' } } } @@ -82,7 +82,7 @@ pipeline { steps { dir('mm') { sh 'make -j disasm' - sh 'make -j all' + sh 'make -j all' } } } diff --git a/tools/ZAPD/Makefile b/tools/ZAPD/Makefile index 737b85ecf..2b47a8039 100644 --- a/tools/ZAPD/Makefile +++ b/tools/ZAPD/Makefile @@ -6,6 +6,7 @@ DEPRECATION_ON ?= 1 DEBUG ?= 0 COPYCHECK_ARGS ?= LLD ?= 0 +WERROR ?= 0 # Use clang++ if available, else use g++ ifeq ($(shell command -v clang++ >/dev/null 2>&1; echo $$?),0) @@ -23,14 +24,16 @@ ifneq ($(DEBUG),0) CXXFLAGS += -g3 -DDEVELOPMENT -D_DEBUG COPYCHECK_ARGS += --devel DEPRECATION_ON = 0 -else +endif + +ifneq ($(WERROR),0) CXXFLAGS += -Werror endif ifeq ($(OPTIMIZATION_ON),0) OPTFLAGS := -O0 else - OPTFLAGS := -O2 -march=native -mtune=native + OPTFLAGS := -O2 endif ifneq ($(ASAN),0) @@ -53,10 +56,23 @@ ifneq ($(LLD),0) endif UNAME := $(shell uname) +UNAMEM := $(shell uname -m) ifneq ($(UNAME), Darwin) - LDFLAGS += -Wl,-export-dynamic -lstdc++fs + LDFLAGS += -Wl,-export-dynamic -lstdc++fs + EXPORTERS := -Wl,--whole-archive ExporterTest/ExporterTest.a -Wl,--no-whole-archive +else + EXPORTERS := -Wl,-force_load ExporterTest/ExporterTest.a + ifeq ($(UNAMEM),arm64) + ifeq ($(shell brew list libpng > /dev/null 2>&1; echo $$?),0) + LDFLAGS += -L $(shell brew --prefix)/lib + INC += -I $(shell brew --prefix)/include + else + $(error Please install libpng via Homebrew) + endif + endif endif + ZAPD_SRC_DIRS := $(shell find ZAPD -type d) SRC_DIRS = $(ZAPD_SRC_DIRS) lib/tinyxml2 @@ -115,4 +131,4 @@ ZAPDUtils: # Linking ZAPD.out: $(O_FILES) lib/libgfxd/libgfxd.a ExporterTest ZAPDUtils - $(CXX) $(CXXFLAGS) $(O_FILES) lib/libgfxd/libgfxd.a ZAPDUtils/ZAPDUtils.a -Wl,--whole-archive ExporterTest/ExporterTest.a -Wl,--no-whole-archive $(LDFLAGS) $(OUTPUT_OPTION) + $(CXX) $(CXXFLAGS) $(O_FILES) lib/libgfxd/libgfxd.a ZAPDUtils/ZAPDUtils.a $(EXPORTERS) $(LDFLAGS) $(OUTPUT_OPTION) diff --git a/tools/ZAPD/README.md b/tools/ZAPD/README.md index e2764b627..448aea033 100644 --- a/tools/ZAPD/README.md +++ b/tools/ZAPD/README.md @@ -16,6 +16,14 @@ In a Debian/Ubuntu based environment, those could be installed with the followin sudo apt install libpng-dev ``` +On a Mac, you will need to install libpng with Homebrew or MacPorts; we currently only support Homebrew. You can run + +```bash +brew install libpng +``` + +to install it via Homebrew. + ### Building #### Linux / *nix @@ -109,11 +117,52 @@ ZAPD also accepts the following list of extra parameters: - Could be useful for looking at raw data or testing. - Can be used only in `e` or `bsf` modes. - `-tm MODE`: Test Mode (enables certain experimental features). To enable it, set `MODE` to `1`. -- `-wno` / `--warn-no-offsets` : Enable warnings for nodes that dont have offsets specified. Takes priority over `-eno`/ `--error-no-offsets`. -- `-eno` / `--error-no-offsets` : Enable errors for nodes that dont have offsets specified. - `-se` / `--set-exporter` : Sets which exporter to use. -- `--gcc-compat` : Enables GCC compatible mode. Slower. +- `--gcc-compat` : Enables GCC compatibly mode. Slower. +- `-us` / `--unaccounted-static` : Mark unaccounted data as `static` - `-s` / `--static` : Mark every asset as `static`. - This behaviour can be overridden per asset using `Static=` in the respective XML node. +- `-W...`: warning flags, see below Additionally, you can pass the flag `--version` to see the current ZAPD version. If that flag is passed, ZAPD will ignore any other parameter passed. + +### Warning flags + +ZAPD contains a variety of warning types, with similar syntax to GCC or Clang's compiler warnings. Warnings can have three levels: + +- Off (does not display anything) +- Warn (print a warning but continue processing) +- Err (behave like an error, i.e. print and throw an exception to crash ZAPD when occurs) + +Each warning type uses one of these by default, but can be modified with flags, similarly to GCC or Clang: + +- `-Wfoo` enables warnings of type `foo` +- `-Wno-foo` disables warnings of type `foo` +- `-Werror=foo` escalates `foo` to behave like an error +- `-Weverything` enables all warnings (they may be turned off using `-Wno-` flags afterwards) +- `-Werror` escalates all enabled warnings to errors + +All warning types currently implemented, with their default levels: + +| Warning type | Default level | Description | +| --------------------------- | ------------- | ------------------------------------------------------------------------ | +| `-Wdeprecated` | Warn | Deprecated features | +| `-Whardcoded-pointer` | Warn | ZAPD lacks the info to make a symbol, so must output a hardcoded pointer | +| `-Wintersection` | Warn | Two assets intersect | +| `-Winvalid-attribute-value` | Err | Attribute declared in XML is wrong | +| `-Winvalid-extracted-data` | Err | Extracted data does not have correct form | +| `-Winvalid-jpeg` | Err | JPEG file does not conform to the game's format requirements | +| `-Winvalid-png` | Err | Issues arising when processing PNG data | +| `-Winvalid-xml` | Err | XML has syntax errors | +| `-Wmissing-attribute` | Warn | Required attribute missing in XML tag | +| `-Wmissing-offsets` | Warn | Offset attribute missing in XML tag | +| `-Wmissing-segment` | Warn | Segment not given in File tag in XML | +| `-Wnot-implemented` | Warn | ZAPD does not currently support this feature | +| `-Wunaccounted` | Off | Large blocks of unaccounted | +| `-Wunknown-attribute` | Warn | Unknown attribute in XML entry tag | + +There are also errors that do not have a type, and cannot be disabled. + +For example, here we have invoked ZAPD in the usual way to extract using a (rather badly-written) XML, but escalating `-Wintersection` to an error: + +![ZAPD warnings example](docs/zapd_warning_example.png?raw=true) diff --git a/tools/ZAPD/ZAPD/Declaration.cpp b/tools/ZAPD/ZAPD/Declaration.cpp index d2a86ffcc..be06b0bea 100644 --- a/tools/ZAPD/ZAPD/Declaration.cpp +++ b/tools/ZAPD/ZAPD/Declaration.cpp @@ -92,20 +92,20 @@ std::string Declaration::GetNormalDeclarationStr() const if (isArray) { - if (arrayItemCntStr != "") + if (arrayItemCntStr != "" && (IsStatic() || forceArrayCnt)) { output += StringHelper::Sprintf("%s %s[%s];\n", varType.c_str(), varName.c_str(), arrayItemCntStr.c_str()); } - else if (arrayItemCnt == 0) - { - output += StringHelper::Sprintf("%s %s[] = {\n", varType.c_str(), varName.c_str()); - } - else + else if (arrayItemCnt != 0 && (IsStatic() || forceArrayCnt)) { output += StringHelper::Sprintf("%s %s[%i] = {\n", varType.c_str(), varName.c_str(), arrayItemCnt); } + else + { + output += StringHelper::Sprintf("%s %s[] = {\n", varType.c_str(), varName.c_str()); + } output += text + "\n"; } @@ -145,16 +145,16 @@ std::string Declaration::GetExternalDeclarationStr() const output += "static "; } - if (arrayItemCntStr != "") + if (arrayItemCntStr != "" && (IsStatic() || forceArrayCnt)) + output += StringHelper::Sprintf("%s %s[%s] = ", varType.c_str(), varName.c_str(), + arrayItemCntStr.c_str()); + else if (arrayItemCnt != 0 && (IsStatic() || forceArrayCnt)) output += - StringHelper::Sprintf("%s %s[%s] = {\n#include \"%s\"\n};", varType.c_str(), - varName.c_str(), arrayItemCntStr.c_str(), includePath.c_str()); - else if (arrayItemCnt != 0) - output += StringHelper::Sprintf("%s %s[%i] = {\n#include \"%s\"\n};", varType.c_str(), - varName.c_str(), arrayItemCnt, includePath.c_str()); + StringHelper::Sprintf("%s %s[%i] = ", varType.c_str(), varName.c_str(), arrayItemCnt); else - output += StringHelper::Sprintf("%s %s[] = {\n#include \"%s\"\n};", varType.c_str(), - varName.c_str(), includePath.c_str()); + output += StringHelper::Sprintf("%s %s[] = ", varType.c_str(), varName.c_str()); + + output += StringHelper::Sprintf("{\n#include \"%s\"\n};", includePath.c_str()); if (rightText != "") output += " " + rightText + ""; @@ -178,14 +178,16 @@ std::string Declaration::GetExternStr() const if (isArray) { - if (arrayItemCntStr != "") + if (arrayItemCntStr != "" && (IsStatic() || forceArrayCnt)) { return StringHelper::Sprintf("extern %s %s[%s];\n", varType.c_str(), varName.c_str(), arrayItemCntStr.c_str()); } - else if (arrayItemCnt != 0) + else if (arrayItemCnt != 0 && (IsStatic() || forceArrayCnt)) + { return StringHelper::Sprintf("extern %s %s[%i];\n", varType.c_str(), varName.c_str(), arrayItemCnt); + } else return StringHelper::Sprintf("extern %s %s[];\n", varType.c_str(), varName.c_str()); } diff --git a/tools/ZAPD/ZAPD/Declaration.h b/tools/ZAPD/ZAPD/Declaration.h index 138524a4c..4a743b50f 100644 --- a/tools/ZAPD/ZAPD/Declaration.h +++ b/tools/ZAPD/ZAPD/Declaration.h @@ -12,8 +12,7 @@ typedef uint32_t offset_t; enum class DeclarationAlignment { Align4, - Align8, - Align16 + Align8 }; enum class StaticConfig @@ -38,10 +37,12 @@ public: std::string varType; std::string varName; std::string includePath; + bool isExternal = false; bool isArray = false; + bool forceArrayCnt = false; size_t arrayItemCnt = 0; - std::string arrayItemCntStr; + std::string arrayItemCntStr = ""; std::vector references; bool isUnaccounted = false; bool isPlaceholder = false; diff --git a/tools/ZAPD/ZAPD/GameConfig.cpp b/tools/ZAPD/ZAPD/GameConfig.cpp index f197493a4..ae29ba28f 100644 --- a/tools/ZAPD/ZAPD/GameConfig.cpp +++ b/tools/ZAPD/ZAPD/GameConfig.cpp @@ -25,7 +25,7 @@ GameConfig::~GameConfig() void GameConfig::ReadTexturePool(const fs::path& texturePoolXmlPath) { tinyxml2::XMLDocument doc; - tinyxml2::XMLError eResult = doc.LoadFile(texturePoolXmlPath.c_str()); + tinyxml2::XMLError eResult = doc.LoadFile(texturePoolXmlPath.string().c_str()); if (eResult != tinyxml2::XML_SUCCESS) { @@ -155,7 +155,7 @@ void GameConfig::ReadConfigFile(const fs::path& argConfigFilePath) {"ExternalFile", &GameConfig::ConfigFunc_ExternalFile}, }; - configFilePath = argConfigFilePath; + configFilePath = argConfigFilePath.string(); tinyxml2::XMLDocument doc; tinyxml2::XMLError eResult = doc.LoadFile(configFilePath.c_str()); diff --git a/tools/ZAPD/ZAPD/Globals.cpp b/tools/ZAPD/ZAPD/Globals.cpp index 036e4a5cb..a10705e9a 100644 --- a/tools/ZAPD/ZAPD/Globals.cpp +++ b/tools/ZAPD/ZAPD/Globals.cpp @@ -3,8 +3,9 @@ #include #include -#include -#include +#include "Utils/File.h" +#include "Utils/Path.h" +#include "WarningHandler.h" #include "tinyxml2.h" Globals* Globals::Instance; @@ -151,8 +152,8 @@ bool Globals::GetSegmentedPtrName(segptr_t segAddress, ZFile* currentFile, } } - const auto& symbolFromMap = Globals::Instance->symbolMap.find(segAddress); - if (symbolFromMap != Globals::Instance->symbolMap.end()) + const auto& symbolFromMap = Globals::Instance->cfg.symbolMap.find(segAddress); + if (symbolFromMap != Globals::Instance->cfg.symbolMap.end()) { declName = "&" + symbolFromMap->second; return true; diff --git a/tools/ZAPD/ZAPD/Globals.h b/tools/ZAPD/ZAPD/Globals.h index 265f1af24..1ae753e20 100644 --- a/tools/ZAPD/ZAPD/Globals.h +++ b/tools/ZAPD/ZAPD/Globals.h @@ -20,6 +20,7 @@ typedef bool (*ExporterSetFuncBool)(ZFileMode fileMode); typedef void (*ExporterSetFuncVoid)(int argc, char* argv[], int& i); typedef void (*ExporterSetFuncVoid2)(const std::string& buildMode, ZFileMode& fileMode); typedef void (*ExporterSetFuncVoid3)(); +typedef void (*ExporterSetResSave)(ZResource* res, BinaryWriter& writer); class ExporterSet { @@ -34,6 +35,7 @@ public: ExporterSetFunc endFileFunc = nullptr; ExporterSetFuncVoid3 beginXMLFunc = nullptr; ExporterSetFuncVoid3 endXMLFunc = nullptr; + ExporterSetResSave resSaveFunc = nullptr; }; class Globals @@ -53,17 +55,14 @@ public: TextureType texType; ZGame game; GameConfig cfg; - bool warnUnaccounted = false; - bool warnNoOffset = false; - bool errorNoOffset = false; bool verboseUnaccounted = false; bool gccCompat = false; bool forceStatic = false; + bool forceUnaccountedStatic = false; std::vector files; std::vector externalFiles; std::vector segments; - std::map symbolMap; std::string currentExporter; static std::map& GetExporterMap(); diff --git a/tools/ZAPD/ZAPD/ImageBackend.cpp b/tools/ZAPD/ZAPD/ImageBackend.cpp index 137e326c3..8accb6b4e 100644 --- a/tools/ZAPD/ZAPD/ImageBackend.cpp +++ b/tools/ZAPD/ZAPD/ImageBackend.cpp @@ -6,6 +6,7 @@ #include #include "Utils/StringHelper.h" +#include "WarningHandler.h" /* ImageBackend */ @@ -20,19 +21,28 @@ void ImageBackend::ReadPng(const char* filename) FILE* fp = fopen(filename, "rb"); if (fp == nullptr) - throw std::runtime_error(StringHelper::Sprintf( - "ImageBackend::ReadPng: Error.\n\t Couldn't open file '%s'.", filename)); + { + std::string errorHeader = StringHelper::Sprintf("could not open file '%s'", filename); + HANDLE_ERROR(WarningType::InvalidPNG, errorHeader, ""); + } png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - if (!png) - throw std::runtime_error("ImageBackend::ReadPng: Error.\n\t Couldn't create png struct."); + if (png == nullptr) + { + HANDLE_ERROR(WarningType::InvalidPNG, "could not create png struct", ""); + } png_infop info = png_create_info_struct(png); - if (!info) - throw std::runtime_error("ImageBackend::ReadPng: Error.\n\t Couldn't create png info."); + if (info == nullptr) + { + HANDLE_ERROR(WarningType::InvalidPNG, "could not create png info", ""); + } if (setjmp(png_jmpbuf(png))) - throw std::runtime_error("ImageBackend::ReadPng: Error.\n\t setjmp(png_jmpbuf(png))."); + { + // TODO: better warning explanation + HANDLE_ERROR(WarningType::InvalidPNG, "setjmp(png_jmpbuf(png))", ""); + } png_init_io(png, fp); @@ -145,20 +155,30 @@ void ImageBackend::WritePng(const char* filename) assert(hasImageData); FILE* fp = fopen(filename, "wb"); - if (!fp) - throw std::runtime_error(StringHelper::Sprintf( - "ImageBackend::WritePng: Error.\n\t Couldn't open file '%s' in write mode.", filename)); + if (fp == nullptr) + { + std::string errorHeader = + StringHelper::Sprintf("could not open file '%s' in write mode", filename); + HANDLE_ERROR(WarningType::InvalidPNG, errorHeader, ""); + } png_structp png = png_create_write_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); - if (!png) - throw std::runtime_error("ImageBackend::WritePng: Error.\n\t Couldn't create png struct."); + if (png == nullptr) + { + HANDLE_ERROR(WarningType::InvalidPNG, "could not create png struct", ""); + } png_infop info = png_create_info_struct(png); - if (!info) - throw std::runtime_error("ImageBackend::WritePng: Error.\n\t Couldn't create png info."); + if (info == nullptr) + { + HANDLE_ERROR(WarningType::InvalidPNG, "could not create png info", ""); + } if (setjmp(png_jmpbuf(png))) - throw std::runtime_error("ImageBackend::WritePng: Error.\n\t setjmp(png_jmpbuf(png))."); + { + // TODO: better warning description + HANDLE_ERROR(WarningType::InvalidPNG, "setjmp(png_jmpbuf(png))", ""); + } png_init_io(png, fp); @@ -441,7 +461,7 @@ double ImageBackend::GetBytesPerPixel() const return 1 * bitDepth / 8; default: - throw std::invalid_argument("ImageBackend::GetBytesPerPixel():\n\t Invalid color type."); + HANDLE_ERROR(WarningType::InvalidPNG, "invalid color type", ""); } } diff --git a/tools/ZAPD/ZAPD/Main.cpp b/tools/ZAPD/ZAPD/Main.cpp index 298ca0262..048338fb7 100644 --- a/tools/ZAPD/ZAPD/Main.cpp +++ b/tools/ZAPD/ZAPD/Main.cpp @@ -1,8 +1,9 @@ -#include -#include -#include #include "Globals.h" #include "Overlays/ZOverlay.h" +#include "Utils/Directory.h" +#include "Utils/File.h" +#include "Utils/Path.h" +#include "WarningHandler.h" #include "ZAnimation.h" #include "ZBackground.h" #include "ZBlob.h" @@ -12,10 +13,10 @@ #if !defined(_MSC_VER) && !defined(__CYGWIN__) #include #include +#include #include // for __cxa_demangle #include // for dladdr #include -#include #include #endif @@ -47,6 +48,7 @@ void ErrorHandler(int sig) const char* crashEasterEgg[] = { "\tYou've met with a terrible fate, haven't you?", "\tSEA BEARS FOAM. SLEEP BEARS DREAMS. \n\tBOTH END IN THE SAME WAY: CRASSSH!", + "\tZAPD has fallen and cannot get up.", }; srand(time(nullptr)); @@ -97,6 +99,9 @@ int main(int argc, char* argv[]) return 1; } + Globals* g = new Globals(); + WarningHandler::Init(argc, argv); + for (int i = 1; i < argc; i++) { if (!strcmp(argv[i], "--version")) @@ -109,12 +114,12 @@ int main(int argc, char* argv[]) printf("Congratulations!\n"); printf("You just found the (unimplemented and undocumented) ZAPD's help message.\n"); printf("Feel free to implement it if you want :D\n"); + + WarningHandler::PrintHelp(); return 0; } } - Globals* g = new Globals; - // Parse other "commands" for (int32_t i = 2; i < argc; i++) { @@ -186,26 +191,15 @@ int main(int argc, char* argv[]) signal(SIGSEGV, ErrorHandler); signal(SIGABRT, ErrorHandler); #else - fprintf(stderr, - "Warning: Tried to set error handler, but this build lacks support for one.\n"); + HANDLE_WARNING(WarningType::Always, + "tried to set error handler, but this ZAPD build lacks support for one", + ""); #endif } else if (arg == "-v") // Verbose { Globals::Instance->verbosity = static_cast(strtol(argv[++i], NULL, 16)); } - else if (arg == "-wu" || arg == "--warn-unaccounted") // Warn unaccounted - { - Globals::Instance->warnUnaccounted = true; - } - else if (arg == "-wno" || arg == "--warn-no-offset") - { - Globals::Instance->warnNoOffset = true; - } - else if (arg == "-eno" || arg == "--error-no-offset") - { - Globals::Instance->errorNoOffset = true; - } else if (arg == "-vu" || arg == "--verbose-unaccounted") // Verbose unaccounted { Globals::Instance->verboseUnaccounted = true; @@ -222,6 +216,10 @@ int main(int argc, char* argv[]) { Globals::Instance->forceStatic = true; } + else if (arg == "-us" || arg == "--unaccounted-static") + { + Globals::Instance->forceUnaccountedStatic = true; + } } // Parse File Mode @@ -262,6 +260,11 @@ int main(int argc, char* argv[]) if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) printf("ZAPD: Zelda Asset Processor For Decomp: %s\n", gBuildHash); + if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG) + { + WarningHandler::PrintWarningsDebugInfo(); + } + // TODO: switch if (fileMode == ZFileMode::Extract || fileMode == ZFileMode::BuildSourceFile) { @@ -334,7 +337,9 @@ bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path if (eResult != tinyxml2::XML_SUCCESS) { - fprintf(stderr, "Invalid xml file: '%s'\n", xmlFilePath.c_str()); + // TODO: use XMLDocument::ErrorIDToName to get more specific error messages here + HANDLE_ERROR(WarningType::InvalidXML, + StringHelper::Sprintf("invalid XML file: '%s'", xmlFilePath.c_str()), ""); return false; } @@ -342,7 +347,9 @@ bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path if (root == nullptr) { - fprintf(stderr, "Missing Root tag in xml file: '%s'\n", xmlFilePath.c_str()); + HANDLE_WARNING( + WarningType::InvalidXML, + StringHelper::Sprintf("missing Root tag in xml file: '%s'", xmlFilePath.c_str()), ""); return false; } @@ -392,10 +399,11 @@ bool Parse(const fs::path& xmlFilePath, const fs::path& basePath, const fs::path } else { - throw std::runtime_error(StringHelper::Sprintf( - "Parse: Fatal error in '%s'.\n\t A resource was found outside of " - "a File element: '%s'\n", - xmlFilePath.c_str(), child->Name())); + std::string errorHeader = + StringHelper::Sprintf("when parsing file '%s'", xmlFilePath.c_str()); + std::string errorBody = StringHelper::Sprintf( + "Found a resource outside a File element: '%s'", child->Name()); + HANDLE_ERROR(WarningType::InvalidXML, errorHeader, errorBody); } } diff --git a/tools/ZAPD/ZAPD/NuGet/libpng.static.txt b/tools/ZAPD/ZAPD/NuGet/libpng.static.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tools/ZAPD/ZAPD/OtherStructs/SkinLimbStructs.cpp b/tools/ZAPD/ZAPD/OtherStructs/SkinLimbStructs.cpp index 9d16de438..087986199 100644 --- a/tools/ZAPD/ZAPD/OtherStructs/SkinLimbStructs.cpp +++ b/tools/ZAPD/ZAPD/OtherStructs/SkinLimbStructs.cpp @@ -263,7 +263,7 @@ void Struct_800A5E28::DeclareReferences(const std::string& prefix) ZResource::DeclareReferences(varPrefix); - if (unk_4 != 0 && GETSEGNUM(unk_4) == parent->segment) + if (unk_4 != SEGMENTED_NULL && GETSEGNUM(unk_4) == parent->segment) { const auto& res = unk_4_arr.at(0); std::string unk_4_Str = res.GetDefaultName(varPrefix); @@ -293,7 +293,7 @@ void Struct_800A5E28::DeclareReferences(const std::string& prefix) decl->text = entryStr; } - if (unk_8 != 0 && GETSEGNUM(unk_8) == parent->segment) + if (unk_8 != SEGMENTED_NULL && GETSEGNUM(unk_8) == parent->segment) { uint32_t unk_8_Offset = Seg2Filespace(unk_8, parent->baseAddress); @@ -306,6 +306,8 @@ void Struct_800A5E28::DeclareReferences(const std::string& prefix) std::string dListStr = StringHelper::Sprintf("%sSkinLimbDL_%06X", varPrefix.c_str(), unk_8_Offset); unk_8_dlist->SetName(dListStr); + unk_8_dlist->DeclareVar(varPrefix, ""); + unk_8_dlist->DeclareReferences(varPrefix); parent->AddResource(unk_8_dlist); } } diff --git a/tools/ZAPD/ZAPD/Overlays/ZOverlay.cpp b/tools/ZAPD/ZAPD/Overlays/ZOverlay.cpp index a842a7e7d..113c4ef33 100644 --- a/tools/ZAPD/ZAPD/Overlays/ZOverlay.cpp +++ b/tools/ZAPD/ZAPD/Overlays/ZOverlay.cpp @@ -1,13 +1,13 @@ #include "ZOverlay.h" -#include +#include #include - -#include -#include -#include -#include #include "Globals.h" +#include "Utils/Directory.h" +#include "Utils/File.h" +#include "Utils/Path.h" +#include "Utils/StringHelper.h" +#include "WarningHandler.h" using namespace ELFIO; @@ -90,7 +90,8 @@ ZOverlay* ZOverlay::FromBuild(fs::path buildPath, fs::path cfgFolderPath) std::vector readers; for (size_t i = 1; i < cfgLines.size(); i++) { - std::string elfPath = buildPath / (cfgLines[i].substr(0, cfgLines[i].size() - 2) + ".o"); + std::string elfPath = + (buildPath / (cfgLines[i].substr(0, cfgLines[i].size() - 2) + ".o")).string(); elfio* reader = new elfio(); if (!reader->load(elfPath)) @@ -128,7 +129,9 @@ ZOverlay* ZOverlay::FromBuild(fs::path buildPath, fs::path cfgFolderPath) SectionType sectionType = GetSectionTypeFromStr(pSec->get_name()); if (sectionType == SectionType::ERROR) - fprintf(stderr, "WARNING: One of the section types returned ERROR\n"); + { + HANDLE_WARNING(WarningType::Always, "one of the section types returned ERROR", ""); + } relocation_section_accessor relocs(*curReader, pSec); for (Elf_Xword j = 0; j < relocs.get_entries_num(); j++) diff --git a/tools/ZAPD/ZAPD/WarningHandler.cpp b/tools/ZAPD/ZAPD/WarningHandler.cpp new file mode 100644 index 000000000..29f8352a7 --- /dev/null +++ b/tools/ZAPD/ZAPD/WarningHandler.cpp @@ -0,0 +1,443 @@ +/** + * ZAPD Warning- and Error-handling system + * ======================================= + * + * This provides a common standard way to write ZAPD warnings/errors, which should be used for all + * such. It will pretty-print them in a uniform way, with styles defined in the header. + * + * Warnings/errors should be constructed using the macros given in the header; there are now plenty + * of examples in the codebase of how to do this. Their purposes are noted above each category in + * the header. Each warning has a type, one of the ones in warningStringToInitMap, or + * WarningType::Always, which is used for warnings that cannot be disabled and do not display a + * type. + * + * Currently there are three levels of alert a warning can have: + * - Off (does not display anything) + * - Warn (print a warning but continue processing) + * - Err (behave like an error, i.e. print and throw an exception to crash ZAPD when occurs) + * + * Flag use: + * - -Wfoo enables warnings of type foo + * - -Wno-foo disables warnings of type foo + * - -Werror=foo escalates foo to behave like an error + * - -Weverything enables all warnings + * - -Werror escalates all enabled warnings to errors + * + * Errors do not have types, and will always throw an exception; they cannot be disabled. + * + * Format + * === + * Each printed warning/error contains the same three sections: + * - Preamble: automatically generated; the content varies depending on category. It will print the + * file and function that the warning is from, and information about the files being processed + * or extracted. + * - Header: begins with 'warning: ' or 'error:', should contain essential information about the + * warning/error, ends with the warning type if applicable. Printed with emphasis to make it + * stand out. Does not start with a capital letter or end with a '.' + * - Body (optional): indented, should contain further diagnostic information useful for identifying + * and fixing the warning/error. Can be a sentence with captialisation and '.' on the end. + * + * Please think of what the end user will find most useful when writing the header and body, and try + * to keep it brief without sacrificing important information! Also remember that if the user is + * only looking at stderr, they will normally have no other context. + * + * Warning vs error + * === + * The principle that we have operated on so far is + * - issue a warning if ZAPD will still be able to produce a valid, compilable C file that will + * match + * - if this cannot happen, use an error. + * but at the end of the day, it is up to the programmer's discretion what it should be possible to + * disable. + * + * Documentation + * === + * Remember that all warnings also need to be documented in the README.md. The help is generated + * automatically. + */ +#include "WarningHandler.h" + +#include +#include "Globals.h" +#include "Utils/StringHelper.h" + +typedef struct +{ + WarningType type; + WarningLevel defaultLevel; + std::string description; +} WarningInfoInit; + +typedef struct +{ + WarningLevel level; + std::string name; + std::string description; +} WarningInfo; + +/** + * Master list of all default warning types and features + * + * To add a warning type, fill in a new row of this map. Think carefully about what its default + * level should be, and try and make the description both brief and informative: it is used in the + * help message, so again, think about what the end user needs to know. + */ +// clang-format off +static const std::unordered_map warningStringToInitMap = { + {"deprecated", {WarningType::Deprecated, +#ifdef DEPRECATION_ON + WarningLevel::Warn, +#else + WarningLevel::Off, +#endif + "Deprecated features"}}, + {"unaccounted", {WarningType::Unaccounted, WarningLevel::Off, "Large blocks of unaccounted"}}, + {"missing-offsets", {WarningType::MissingOffsets, WarningLevel::Warn, "Offset attribute missing in XML tag"}}, + {"intersection", {WarningType::Intersection, WarningLevel::Warn, "Two assets intersect"}}, + {"missing-attribute", {WarningType::MissingAttribute, WarningLevel::Warn, "Required attribute missing in XML tag"}}, + {"invalid-attribute-value", {WarningType::InvalidAttributeValue, WarningLevel::Err, "Attribute declared in XML is wrong"}}, + {"unknown-attribute", {WarningType::UnknownAttribute, WarningLevel::Warn, "Unknown attribute in XML entry tag"}}, + {"invalid-xml", {WarningType::InvalidXML, WarningLevel::Err, "XML has syntax errors"}}, + {"invalid-jpeg", {WarningType::InvalidJPEG, WarningLevel::Err, "JPEG file does not conform to the game's format requirements"}}, + {"invalid-png", {WarningType::InvalidPNG, WarningLevel::Err, "Issues arising when processing PNG data"}}, + {"invalid-extracted-data", {WarningType::InvalidExtractedData, WarningLevel::Err, "Extracted data does not have correct form"}}, + {"missing-segment", {WarningType::MissingSegment, WarningLevel::Warn, "Segment not given in File tag in XML"}}, + {"hardcoded-pointer", {WarningType::HardcodedPointer, WarningLevel::Warn, "ZAPD lacks the info to make a symbol, so must output a hardcoded pointer"}}, + {"not-implemented", {WarningType::NotImplemented, WarningLevel::Warn, "ZAPD does not currently support this feature"}}, +}; + +/** + * Map constructed at runtime to contain the warning features as set by the user using -W flags. + */ +static std::unordered_map warningTypeToInfoMap; + +void WarningHandler::ConstructTypeToInfoMap() { + for (auto& entry : warningStringToInitMap) { + warningTypeToInfoMap[entry.second.type] = {entry.second.defaultLevel, entry.first, entry.second.description}; + } + warningTypeToInfoMap[WarningType::Always] = {WarningLevel::Warn, "always", "you shouldn't be reading this"}; + assert(warningTypeToInfoMap.size() == static_cast(WarningType::Max)); +} + +/** + * Initialises the main warning type map and reads flags passed to set each warning type's level. + */ +void WarningHandler::Init(int argc, char* argv[]) { + ConstructTypeToInfoMap(); + + bool werror = false; + for (int i = 1; i < argc; i++) { + // If it doesn't start with "-W" skip it. + if (argv[i][0] != '-' || argv[i][1] != 'W' || argv[i][2] == '\0') { + continue; + } + + WarningLevel warningTypeOn = WarningLevel::Warn; + size_t startingIndex = 2; + + // "-Wno-" + if (argv[i][2] == 'n' && argv[i][3] == 'o' && argv[i][4] == '-' && argv[i][5] != '\0') { + warningTypeOn = WarningLevel::Off; + startingIndex = 5; + } + + // Read starting after the "-W" or "-Wno-" + std::string_view currentArgv = &argv[i][startingIndex]; + + if (currentArgv == "error") { + werror = warningTypeOn != WarningLevel::Off; + } else if (currentArgv == "everything") { + for (auto& it: warningTypeToInfoMap) { + if (it.second.level <= WarningLevel::Warn) { + it.second.level = warningTypeOn; + } + } + } else { + // "-Werror=" / "-Wno-error=" parser + if (currentArgv.rfind("error=", 0) == 0) { + // Read starting after the "error=" part + currentArgv = &argv[i][startingIndex + 6]; + warningTypeOn = warningTypeOn != WarningLevel::Off ? WarningLevel::Err : WarningLevel::Warn; + } + + auto it = warningStringToInitMap.find(std::string(currentArgv)); + if (it != warningStringToInitMap.end()) { + warningTypeToInfoMap[it->second.type].level = warningTypeOn; + } + else { + HANDLE_WARNING(WarningType::Always, StringHelper::Sprintf("unknown warning flag '%s'", argv[i]), ""); + } + } + } + + if (werror) { + for (auto& it: warningTypeToInfoMap) { + if (it.second.level >= WarningLevel::Warn) { + it.second.level = WarningLevel::Err; + } + } + } +} + +bool WarningHandler::IsWarningEnabled(WarningType warnType) { + assert(static_cast(warnType) >= 0 && warnType < WarningType::Max); + + return warningTypeToInfoMap.at(warnType).level != WarningLevel::Off; +} + +bool WarningHandler::WasElevatedToError(WarningType warnType) { + assert(static_cast(warnType) >= 0 && warnType < WarningType::Max); + + if (!IsWarningEnabled(warnType)) { + return false; + } + + return warningTypeToInfoMap.at(warnType).level >= WarningLevel::Err; +} + +/** + * Print file/line/function info for debugging + */ +void WarningHandler::FunctionPreamble(const char* filename, int32_t line, const char* function) { + if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG) { + fprintf(stderr, "%s:%i: in function %s:\n", filename, line, function); + } +} + +/** + * Print the information about the file(s) being processed (XML for extraction, png etc. for building) + */ +void WarningHandler::ProcessedFilePreamble() { + if (Globals::Instance->inputPath != "") { + fprintf(stderr, "When processing file %s: ", Globals::Instance->inputPath.c_str()); + } +} + +/** + * Print information about the binary file being extracted + */ +void WarningHandler::ExtractedFilePreamble(const ZFile *parent, const ZResource* res, const uint32_t offset) { + fprintf(stderr, "in input binary file %s, ", parent->GetName().c_str()); + if (res != nullptr) { + fprintf(stderr, "resource '%s' at ", res->GetName().c_str()); + } + fprintf(stderr, "offset 0x%06X: \n\t", offset); +} + +/** + * Construct the rest of the message, after warning:/error. The message is filled in one character at a time, with indents added after newlines + */ +std::string WarningHandler::ConstructMessage(std::string message, const std::string& header, const std::string& body) { + message.reserve(message.size() + header.size() + body.size() + 10 * (sizeof(HANG_INDT) - 1)); + message += StringHelper::Sprintf(HILITE("%s"), header.c_str()); + message += "\n"; + + if (body == "") { + return message; + } + + message += HANG_INDT; + for (const char* ptr = body.c_str(); *ptr != '\0'; ptr++) { + message += *ptr; + if (*ptr == '\n') { + message += HANG_INDT; + } + } + message += "\n"; + + return message; +} + +/* Error module functions */ + +void WarningHandler::PrintErrorAndThrow(const std::string& header, const std::string& body) { + std::string errorMsg = ERR_FMT("error: "); + throw std::runtime_error(ConstructMessage(errorMsg, header, body)); +} + +/* Error types, to be used via the macros */ + +void WarningHandler::ErrorType(WarningType warnType, const std::string& header, const std::string& body) { + std::string headerMsg = header; + + for (const auto& iter: warningStringToInitMap) { + if (iter.second.type == warnType) { + headerMsg += StringHelper::Sprintf(" [%s]", iter.first.c_str()); + } + } + + PrintErrorAndThrow(headerMsg, body); +} + +void WarningHandler::Error_Plain(const char* filename, int32_t line, const char* function, WarningType warnType, const std::string& header, const std::string& body) { + FunctionPreamble(filename, line, function); + + ErrorType(warnType, header, body); +} + +void WarningHandler::Error_Process(const char* filename, int32_t line, const char* function, WarningType warnType, const std::string& header, const std::string& body) { + FunctionPreamble(filename, line, function); + ProcessedFilePreamble(); + + ErrorType(warnType, header, body); +} + +void WarningHandler::Error_Resource(const char* filename, int32_t line, const char* function, WarningType warnType, const ZFile *parent, const ZResource* res, const uint32_t offset, const std::string& header, const std::string& body) { + assert(parent != nullptr); + + FunctionPreamble(filename, line, function); + ProcessedFilePreamble(); + ExtractedFilePreamble(parent, res, offset); + + ErrorType(warnType, header, body); +} + +/* Warning module functions */ + +void WarningHandler::PrintWarningBody(const std::string& header, const std::string& body) { + std::string errorMsg = WARN_FMT("warning: "); + fprintf(stderr, "%s", ConstructMessage(errorMsg, header, body).c_str()); +} + +void WarningHandler::WarningTypeAndChooseEscalate(WarningType warnType, const std::string& header, const std::string& body) { + std::string headerMsg = header; + + for (const auto& iter: warningStringToInitMap) { + if (iter.second.type == warnType) { + headerMsg += StringHelper::Sprintf(" [-W%s]", iter.first.c_str()); + } + } + + if (WasElevatedToError(warnType)) { + PrintErrorAndThrow(headerMsg, body); + } else { + PrintWarningBody(headerMsg, body); + } +} + + +/* Warning types, to be used via the macros */ + +void WarningHandler::Warning_Plain(const char* filename, int32_t line, const char* function, WarningType warnType, const std::string& header, const std::string& body) { + if (!IsWarningEnabled(warnType)) { + return; + } + + FunctionPreamble(filename, line, function); + + WarningTypeAndChooseEscalate(warnType, header, body); +} + +void WarningHandler::Warning_Process(const char* filename, int32_t line, const char* function, WarningType warnType, const std::string& header, const std::string& body) { + if (!IsWarningEnabled(warnType)) { + return; + } + + FunctionPreamble(filename, line, function); + ProcessedFilePreamble(); + + WarningTypeAndChooseEscalate(warnType, header, body); +} + +void WarningHandler::Warning_Resource(const char* filename, int32_t line, const char* function, WarningType warnType, const ZFile *parent, const ZResource* res, const uint32_t offset, const std::string& header, const std::string& body) { + assert(parent != nullptr); + + if (!IsWarningEnabled(warnType)) { + return; + } + + FunctionPreamble(filename, line, function); + ProcessedFilePreamble(); + ExtractedFilePreamble(parent, res, offset); + + WarningTypeAndChooseEscalate(warnType, header, body); +} + + +/* Help-related functions */ + +#include + +/** + * Print each warning name, default status, and description using the init map + */ +void WarningHandler::PrintHelp() { + std::set sortedKeys; + WarningInfoInit warningInfo; + uint32_t columnWidth = 25; + std::string dt; + + // Sort keys through the magic of `set`, to print in alphabetical order + for (auto& it : warningStringToInitMap) { + sortedKeys.insert(it.first); + } + + printf("\nWarning types ( * means enabled by default)\n"); + for (auto& key : sortedKeys) { + warningInfo = warningStringToInitMap.at(key); + if (warningInfo.defaultLevel <= WarningLevel::Warn) { + dt = "-W"; + dt += key; + if (warningInfo.defaultLevel == WarningLevel::Warn) { + dt += " *"; + } + printf(HELP_DT_INDT "%-*s", columnWidth, dt.c_str()); + + if (dt.length() + 2 > columnWidth) { + printf("\n" HELP_DT_INDT "%-*s", columnWidth, ""); + } + printf("%s\n", warningInfo.description.c_str()); + } + } + + printf("\nDefault errors\n"); + for (auto& key : sortedKeys) { + if (warningInfo.defaultLevel > WarningLevel::Warn) { + dt = "-W"; + dt += key; + printf(HELP_DT_INDT "%-*s", columnWidth, dt.c_str()); + + if (dt.length() + 2 > columnWidth) { + printf("\n" HELP_DT_INDT "%*s", columnWidth, ""); + } + printf("%s\n", warningInfo.description.c_str()); + } + } + + printf("\n"); + printf("Other\n" HELP_DT_INDT "-Weverything will enable all existing warnings.\n" HELP_DT_INDT "-Werror will promote all warnings to errors.\n"); + + printf("\n"); + printf("Warnings can be disabled using -Wno-... instead of -W...; -Weverything will override any -Wno-... flags passed before it.\n"); +} + +/** + * Print which warnings are currently enabled + */ +void WarningHandler::PrintWarningsDebugInfo() +{ + std::string dt; + + printf("Warnings status:\n"); + for (auto& it: warningTypeToInfoMap) { + dt = it.second.name; + dt += ": "; + + printf(HELP_DT_INDT "%-25s", dt.c_str()); + switch (it.second.level) + { + case WarningLevel::Off: + printf(VT_FGCOL(LIGHTGRAY) "Off" VT_RST); + break; + case WarningLevel::Warn: + printf(VT_FGCOL(YELLOW) "Warn" VT_RST); + break; + case WarningLevel::Err: + printf(VT_FGCOL(RED) "Err" VT_RST); + break; + + } + printf("\n"); + } + printf("\n"); +} diff --git a/tools/ZAPD/ZAPD/WarningHandler.h b/tools/ZAPD/ZAPD/WarningHandler.h new file mode 100644 index 000000000..bb0360a81 --- /dev/null +++ b/tools/ZAPD/ZAPD/WarningHandler.h @@ -0,0 +1,145 @@ +#pragma once + +#include +#include +#include +#include + +#include "Utils/vt.h" +#include "ZFile.h" + +#ifdef _MSC_VER +#define __PRETTY_FUNCTION__ __FUNCSIG__ +#elif not defined(__GNUC__) +#define __PRETTY_FUNCTION__ __func__ +#endif + +// ======================================= +/* Formatting macros */ + +// TODO: move this somewhere else so it can be used by other help +#define HELP_DT_INDT " " + +/* Macros for formatting warnings/errors */ +#define VT_HILITE VT_BOLD_FGCOL(WHITE) +#define VT_WARN VT_BOLD_FGCOL(PURPLE) +#define VT_ERR VT_BOLD_FGCOL(RED) + +#define HILITE(string) (VT_HILITE string VT_RST) +#define WARN_FMT(string) (VT_WARN string VT_RST) +#define ERR_FMT(string) (VT_ERR string VT_RST) + +// Maybe make WARN_LF instead +// Currently 8 spaces +#define WARN_INDT " " +// Currently 16 spaces +#define HANG_INDT " " + +// ======================================= +/* Warning and error macros */ +// TODO: better names + +// General-purpose, plain style (only prints function,file,line in the preamble) +#define HANDLE_ERROR(warningType, header, body) \ + WarningHandler::Error_Plain(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, header, body) +#define HANDLE_WARNING(warningType, header, body) \ + WarningHandler::Warning_Plain(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, header, \ + body) + +// For processing XMLs or textures/blobs (preamble contains function,file,line; processed file) +#define HANDLE_ERROR_PROCESS(warningType, header, body) \ + WarningHandler::Error_Process(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, header, \ + body) +#define HANDLE_WARNING_PROCESS(warningType, header, body) \ + WarningHandler::Warning_Process(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, header, \ + body) + +// For ZResource-related stuff (preamble contains function,file,line; processed file; extracted file +// and offset) +#define HANDLE_ERROR_RESOURCE(warningType, parent, resource, offset, header, body) \ + WarningHandler::Error_Resource(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, parent, \ + resource, offset, header, body) +#define HANDLE_WARNING_RESOURCE(warningType, parent, resource, offset, header, body) \ + WarningHandler::Warning_Resource(__FILE__, __LINE__, __PRETTY_FUNCTION__, warningType, parent, \ + resource, offset, header, body) + +// ======================================= + +enum class WarningType +{ + Always, // Warnings of this type are always printed, cannot be disabled. + Deprecated, + Unaccounted, + MissingOffsets, + Intersection, + MissingAttribute, + InvalidAttributeValue, + UnknownAttribute, + InvalidXML, + InvalidJPEG, + InvalidPNG, + InvalidExtractedData, + MissingSegment, + HardcodedPointer, + NotImplemented, + Max, +}; + +enum class WarningLevel +{ + Off, + Warn, + Err, +}; + +class WarningHandler +{ +public: + static void ConstructTypeToInfoMap(); + + static void Init(int argc, char* argv[]); + + static bool IsWarningEnabled(WarningType warnType); + static bool WasElevatedToError(WarningType warnType); + + static void FunctionPreamble(const char* filename, int32_t line, const char* function); + static void ProcessedFilePreamble(); + static void ExtractedFilePreamble(const ZFile* parent, const ZResource* res, + const uint32_t offset); + static std::string ConstructMessage(std::string message, const std::string& header, + const std::string& body); + + [[noreturn]] static void PrintErrorAndThrow(const std::string& header, const std::string& body); + static void PrintWarningBody(const std::string& header, const std::string& body); + + [[noreturn]] static void ErrorType(WarningType warnType, const std::string& header, + const std::string& body); + [[noreturn]] static void Error_Plain(const char* filename, int32_t line, const char* function, + WarningType warnType, const std::string& header, + const std::string& body); + [[noreturn]] static void Error_Process(const char* filename, int32_t line, const char* function, + WarningType warnType, const std::string& header, + const std::string& body); + [[noreturn]] static void Error_Resource(const char* filename, int32_t line, + const char* function, WarningType warnType, + const ZFile* parent, const ZResource* res, + const uint32_t offset, const std::string& header, + const std::string& body); + + static void WarningTypeAndChooseEscalate(WarningType warnType, const std::string& header, + const std::string& body); + + static void Warning_Plain(const char* filename, int32_t line, const char* function, + WarningType warnType, const std::string& header, + const std::string& body); + static void Warning_Process(const char* filename, int32_t line, const char* function, + WarningType warnType, const std::string& header, + const std::string& body); + static void Warning_Resource(const char* filename, int32_t line, const char* function, + WarningType warnType, const ZFile* parent, const ZResource* res, + const uint32_t offset, const std::string& header, + const std::string& body); + + static void PrintHelp(); + static void PrintWarningsDebugInfo(); +}; diff --git a/tools/ZAPD/ZAPD/ZAPD.vcxproj b/tools/ZAPD/ZAPD/ZAPD.vcxproj index c74d28cbe..431abb73b 100644 --- a/tools/ZAPD/ZAPD/ZAPD.vcxproj +++ b/tools/ZAPD/ZAPD/ZAPD.vcxproj @@ -1,5 +1,6 @@ + Debug @@ -71,8 +72,8 @@ - $(SolutionDir)lib\libgfxd;$(SolutionDir)x64\Debug;$(SolutionDir)packages\libpng.1.6.28.1\build\native\lib\x64\v140\dynamic\Debug;$(LibraryPath) - $(SolutionDir)ZAPDUtils;$(SolutionDir)lib\tinyxml2;$(SolutionDir)lib\libgfxd;$(SolutionDir)lib\elfio;$(SolutionDir)lib\stb;$(ProjectDir);$(IncludePath) + $(OutDir);$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\packages\libpng-v142.1.6.37.2\build\native\lib\x64\v142\Debug\;$(LibraryPath) + $(ProjectDir)..\ZAPDUtils;$(ProjectDir)..\lib\tinyxml2;$(ProjectDir)..\lib\libgfxd;$(ProjectDir)..\lib\elfio;$(ProjectDir)..\lib\stb;$(ProjectDir);$(IncludePath) $(IncludePath) @@ -105,13 +106,16 @@ _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) EnableFastChecks stdc11 + MultiThreadedDebug true - libpng16.lib;ZAPDUtils.lib;/WHOLEARCHIVE:ExporterExample.lib;%(AdditionalDependencies) + ZAPDUtils.lib;/WHOLEARCHIVE:ExporterExample.lib;%(AdditionalDependencies) + false cd .. +mkdir build\ZAPD python3 ZAPD/genbuildinfo.py @@ -146,6 +150,7 @@ python3 ZAPD/genbuildinfo.py + @@ -153,19 +158,22 @@ python3 ZAPD/genbuildinfo.py - + + + + @@ -213,6 +221,7 @@ python3 ZAPD/genbuildinfo.py + @@ -237,10 +246,13 @@ python3 ZAPD/genbuildinfo.py + + + @@ -253,6 +265,7 @@ python3 ZAPD/genbuildinfo.py + @@ -294,6 +307,7 @@ python3 ZAPD/genbuildinfo.py + @@ -301,24 +315,29 @@ python3 ZAPD/genbuildinfo.py true + + - - + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - + + + + \ No newline at end of file diff --git a/tools/ZAPD/ZAPD/ZAPD.vcxproj.filters b/tools/ZAPD/ZAPD/ZAPD.vcxproj.filters index 2d3050ed4..b8a7daaac 100644 --- a/tools/ZAPD/ZAPD/ZAPD.vcxproj.filters +++ b/tools/ZAPD/ZAPD/ZAPD.vcxproj.filters @@ -49,6 +49,15 @@ {85600275-99fe-491d-8189-bcc3dc1a8903} + + {ba9990b0-1082-48bb-874c-6108534b5455} + + + {ce9d91b0-ba20-4296-bc2d-8630965bb392} + + + {730beb67-6d59-4849-9d9b-702c4a565fc0} + @@ -135,9 +144,6 @@ Source Files\Z64\ZRoom\Commands - - Source Files\Libraries - Source Files\Z64 @@ -258,6 +264,24 @@ Source Files\Z64 + + Source Files + + + Source Files\Z64 + + + Source Files\Z64 + + + Source Files + + + Source Files\Z64 + + + Source Files + @@ -497,11 +521,32 @@ Header Files\Z64 + + Header Files + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files\Z64 + + + Header Files + Resource Files + + any\any + + + NuGet + diff --git a/tools/ZAPD/ZAPD/ZAnimation.cpp b/tools/ZAPD/ZAPD/ZAnimation.cpp index 9242f657a..4d9266b09 100644 --- a/tools/ZAPD/ZAPD/ZAnimation.cpp +++ b/tools/ZAPD/ZAPD/ZAnimation.cpp @@ -6,6 +6,7 @@ #include "Utils/BitConverter.h" #include "Utils/File.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZFile.h" REGISTER_ZFILENODE(Animation, ZNormalAnimation); @@ -103,7 +104,7 @@ void ZNormalAnimation::DeclareReferences(const std::string& prefix) valuesStr += "\n "; } - parent->AddDeclarationArray(rotationValuesOffset, DeclarationAlignment::Align16, + parent->AddDeclarationArray(rotationValuesOffset, DeclarationAlignment::Align4, rotationValues.size() * 2, "s16", StringHelper::Sprintf("%sFrameData", defaultPrefix.c_str()), rotationValues.size(), valuesStr); @@ -117,7 +118,7 @@ void ZNormalAnimation::DeclareReferences(const std::string& prefix) indicesStr += "\n"; } - parent->AddDeclarationArray(rotationIndicesOffset, DeclarationAlignment::Align16, + parent->AddDeclarationArray(rotationIndicesOffset, DeclarationAlignment::Align4, rotationIndices.size() * 6, "JointIndex", StringHelper::Sprintf("%sJointIndices", defaultPrefix.c_str()), rotationIndices.size(), indicesStr); @@ -218,11 +219,9 @@ void ZCurveAnimation::ParseXML(tinyxml2::XMLElement* reader) std::string skelOffsetXml = registeredAttributes.at("SkelOffset").value; if (skelOffsetXml == "") { - throw std::runtime_error( - StringHelper::Sprintf("ZCurveAnimation::ParseXML: Fatal error in '%s'.\n" - "\t Missing 'SkelOffset' attribute in ZCurveAnimation.\n" - "\t You need to provide the offset of the curve skeleton.", - name.c_str())); + HANDLE_ERROR_RESOURCE(WarningType::MissingAttribute, parent, this, rawDataIndex, + "missing 'SkelOffset' attribute in ", + "You need to provide the offset of the curve skeleton."); } skelOffset = StringHelper::StrToL(skelOffsetXml, 0); } @@ -386,7 +385,7 @@ size_t ZCurveAnimation::GetRawDataSize() const DeclarationAlignment ZCurveAnimation::GetDeclarationAlignment() const { - return DeclarationAlignment::Align16; + return DeclarationAlignment::Align4; } std::string ZCurveAnimation::GetSourceTypeName() const diff --git a/tools/ZAPD/ZAPD/ZAnimation.h b/tools/ZAPD/ZAPD/ZAnimation.h index e5b69d3ef..2c04b4ff8 100644 --- a/tools/ZAPD/ZAPD/ZAnimation.h +++ b/tools/ZAPD/ZAPD/ZAnimation.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include "Vec3s.h" diff --git a/tools/ZAPD/ZAPD/ZArray.cpp b/tools/ZAPD/ZAPD/ZArray.cpp index b1ba3a669..ebfb13ee7 100644 --- a/tools/ZAPD/ZAPD/ZArray.cpp +++ b/tools/ZAPD/ZAPD/ZArray.cpp @@ -4,6 +4,7 @@ #include "Globals.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZFile.h" REGISTER_ZFILENODE(Array, ZArray); @@ -25,13 +26,18 @@ void ZArray::ParseXML(tinyxml2::XMLElement* reader) ZResource::ParseXML(reader); arrayCnt = reader->IntAttribute("Count", 0); - // TODO: do a better check. - assert(arrayCnt > 0); + if (arrayCnt <= 0) + { + HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + "invalid value found for 'Count' attribute", ""); + } tinyxml2::XMLElement* child = reader->FirstChildElement(); if (child == nullptr) - throw std::runtime_error( - StringHelper::Sprintf("Error! Array needs at least one sub-element.\n")); + { + HANDLE_ERROR_RESOURCE(WarningType::InvalidXML, parent, this, rawDataIndex, + " needs one sub-element", ""); + } childName = child->Name(); @@ -42,9 +48,10 @@ void ZArray::ParseXML(tinyxml2::XMLElement* reader) ZResource* res = nodeMap->at(childName)(parent); if (!res->DoesSupportArray()) { - throw std::runtime_error(StringHelper::Sprintf( - "Error! Resource %s does not support being wrapped in an array!\n", - childName.c_str())); + std::string errorHeader = StringHelper::Sprintf( + "resource <%s> does not support being wrapped in an ", childName.c_str()); + HANDLE_ERROR_RESOURCE(WarningType::InvalidXML, parent, this, rawDataIndex, errorHeader, + ""); } res->parent = parent; res->SetInnerNode(true); @@ -87,7 +94,7 @@ Declaration* ZArray::DeclareVar(const std::string& prefix, const std::string& bo std::string ZArray::GetBodySourceCode() const { - std::string output; + std::string output = ""; for (size_t i = 0; i < arrayCnt; i++) { diff --git a/tools/ZAPD/ZAPD/ZArray.h b/tools/ZAPD/ZAPD/ZArray.h index 46a04d732..b78a8edfd 100644 --- a/tools/ZAPD/ZAPD/ZArray.h +++ b/tools/ZAPD/ZAPD/ZArray.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include "ZResource.h" diff --git a/tools/ZAPD/ZAPD/ZBackground.cpp b/tools/ZAPD/ZAPD/ZBackground.cpp index 4125f239f..0ed1eb747 100644 --- a/tools/ZAPD/ZAPD/ZBackground.cpp +++ b/tools/ZAPD/ZAPD/ZBackground.cpp @@ -5,6 +5,7 @@ #include "Utils/File.h" #include "Utils/Path.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZFile.h" REGISTER_ZFILENODE(Background, ZBackground); @@ -63,52 +64,46 @@ void ZBackground::CheckValidJpeg(const std::string& filepath) uint32_t jpegMarker = BitConverter::ToUInt32BE(data, 0); if (jpegMarker != JPEG_MARKER) { - fprintf(stderr, - "ZBackground::CheckValidJpeg: Warning.\n" - "\t Missing jpeg marker at the beginning of file: '%s'.\n" - "\t The game will skip this jpeg.\n", - filename.c_str()); + HANDLE_WARNING_PROCESS( + WarningType::InvalidJPEG, + StringHelper::Sprintf("missing jpeg marker at beginning of file: '%s'", + filename.c_str()), + "The game will skip this jpeg."); } if (data.at(6) != 'J' || data.at(7) != 'F' || data.at(8) != 'I' || data.at(9) != 'F' || data.at(10) != '\0') { std::string jfifIdentifier(data.begin() + 6, data.begin() + 6 + 5); - fprintf(stderr, - "ZBackground::CheckValidJpeg: Warning.\n" - "\t Missing 'JFIF' identifier. File: '%s'.\n" - "\t This image may be corrupted or not be a jpeg iamge.\n" - "\t The identifier found was '%s'.\n", - filename.c_str(), jfifIdentifier.c_str()); + HANDLE_WARNING_PROCESS( + WarningType::InvalidJPEG, "missing 'JFIF' identifier", + StringHelper::Sprintf( + "This image may be corrupted, or not a jpeg. The identifier found was: '%s'", + jfifIdentifier.c_str())); } uint8_t majorVersion = data.at(11); uint8_t minorVersion = data.at(12); if (majorVersion != 0x01 || minorVersion != 0x01) { - fprintf(stderr, - "ZBackground::CheckValidJpeg: Warning.\n" - "\t Wrong JFIF version '%i.%02i'. File: '%s'.\n" - "\t The expected version is '1.01'. The game may not be able to decode this image " - "properly.\n", - majorVersion, minorVersion, filename.c_str()); + HANDLE_WARNING_PROCESS( + WarningType::InvalidJPEG, + StringHelper::Sprintf("wrong JFIF version '%i.%02i'", majorVersion, minorVersion), + "The expected version is '1.01'. The game may be unable to decode this image " + "correctly."); } if (BitConverter::ToUInt16BE(data, 20) != MARKER_DQT) { // This may happen when creating a custom image with Exif, XMP, thumbnail, progressive, etc. // enabled. - fprintf(stderr, - "ZBackground::CheckValidJpeg: Warning.\n" - "\t There seems to be extra data before the image data in file: '%s'.\n" - "\t The game may not be able to decode this image properly.\n", - filename.c_str()); + HANDLE_WARNING_PROCESS(WarningType::InvalidJPEG, + "there seems to be extra data before the image data in this file", + "The game may not be able to decode this image correctly."); } if (data.size() > GetRawDataSize()) { - fprintf(stderr, - "ZBackground::CheckValidJpeg: Warning.\n" - "\t The image is bigger than the screen buffer. File: '%s'.\n" - "\t Image size: %zu bytes.\n" - "\t Screen buffer size: %zu bytes.\n", - filename.c_str(), data.size(), GetRawDataSize()); + HANDLE_WARNING_PROCESS( + WarningType::InvalidJPEG, "the image is bigger than the screen buffer", + StringHelper::Sprintf("Image size: %zu bytes\nScreen buffer size: %zu bytes", + data.size(), GetRawDataSize())); } } @@ -138,6 +133,7 @@ Declaration* ZBackground::DeclareVar(const std::string& prefix, Declaration* decl = parent->AddDeclarationIncludeArray(rawDataIndex, incStr, GetRawDataSize(), GetSourceTypeName(), auxName, 0); decl->arrayItemCntStr = "SCREEN_WIDTH * SCREEN_HEIGHT / 4"; + decl->forceArrayCnt = true; decl->staticConf = staticConf; return decl; } diff --git a/tools/ZAPD/ZAPD/ZBlob.cpp b/tools/ZAPD/ZAPD/ZBlob.cpp index c1f078820..6812bfaee 100644 --- a/tools/ZAPD/ZAPD/ZBlob.cpp +++ b/tools/ZAPD/ZAPD/ZBlob.cpp @@ -83,11 +83,6 @@ std::string ZBlob::GetBodySourceCode() const return sourceOutput; } -std::string ZBlob::GetSourceOutputHeader([[maybe_unused]] const std::string& prefix) -{ - return StringHelper::Sprintf("extern u8 %s[];\n", name.c_str()); -} - void ZBlob::Save(const fs::path& outFolder) { File::WriteAllBytes((outFolder / (name + ".bin")).string(), blobData); diff --git a/tools/ZAPD/ZAPD/ZBlob.h b/tools/ZAPD/ZAPD/ZBlob.h index 86623b511..d7a7feff1 100644 --- a/tools/ZAPD/ZAPD/ZBlob.h +++ b/tools/ZAPD/ZAPD/ZBlob.h @@ -16,7 +16,6 @@ public: Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override; std::string GetBodySourceCode() const override; - std::string GetSourceOutputHeader(const std::string& prefix) override; void Save(const fs::path& outFolder) override; bool IsExternalResource() const override; diff --git a/tools/ZAPD/ZAPD/ZCollision.cpp b/tools/ZAPD/ZAPD/ZCollision.cpp index f9c0bf7d6..1dfa46b1d 100644 --- a/tools/ZAPD/ZAPD/ZCollision.cpp +++ b/tools/ZAPD/ZAPD/ZCollision.cpp @@ -88,7 +88,7 @@ void ZCollisionHeader::ParseRawData() void ZCollisionHeader::DeclareReferences(const std::string& prefix) { - std::string declaration; + std::string declaration = ""; std::string auxName = name; if (name == "") @@ -174,7 +174,7 @@ void ZCollisionHeader::DeclareReferences(const std::string& prefix) std::string ZCollisionHeader::GetBodySourceCode() const { - std::string declaration; + std::string declaration = ""; declaration += "\n"; diff --git a/tools/ZAPD/ZAPD/ZCutscene.cpp b/tools/ZAPD/ZAPD/ZCutscene.cpp index 237481079..ba8fe8963 100644 --- a/tools/ZAPD/ZAPD/ZCutscene.cpp +++ b/tools/ZAPD/ZAPD/ZCutscene.cpp @@ -2,6 +2,7 @@ #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZResource.h" REGISTER_ZFILENODE(Cutscene, ZCutscene); @@ -87,7 +88,7 @@ CutsceneCommandSceneTransFX::~CutsceneCommandSceneTransFX() std::string ZCutscene::GetBodySourceCode() const { - std::string output; + std::string output = ""; uint32_t curPtr = 0; output += StringHelper::Sprintf(" CS_BEGIN_CUTSCENE(%i, %i),\n", commands.size(), endFrame); @@ -225,8 +226,9 @@ void ZCutscene::ParseRawData() cmd = new CutsceneCommandEnd(rawData, currentPtr); break; case CutsceneCommands::Error: - fprintf(stderr, "Cutscene command error %d %s %d\n", (int32_t)cmdID, __FILE__, - __LINE__); + HANDLE_WARNING_RESOURCE(WarningType::NotImplemented, parent, this, rawDataIndex, + StringHelper::Sprintf("cutscene command error %d", cmdID), + ""); break; } @@ -404,7 +406,9 @@ CutsceneCommands ZCutscene::GetCommandFromID(int32_t id) return CutsceneCommands::Unknown; } - fprintf(stderr, "WARNING: Could not identify cutscene command ID 0x%04X\n", id); + HANDLE_WARNING_RESOURCE( + WarningType::NotImplemented, parent, this, rawDataIndex, + StringHelper::Sprintf("could not identify cutscene command. ID 0x%04X", id), ""); return CutsceneCommands::Error; } diff --git a/tools/ZAPD/ZAPD/ZCutscene.h b/tools/ZAPD/ZAPD/ZCutscene.h index cbb6a78b0..8e901e307 100644 --- a/tools/ZAPD/ZAPD/ZCutscene.h +++ b/tools/ZAPD/ZAPD/ZCutscene.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include "ZFile.h" diff --git a/tools/ZAPD/ZAPD/ZCutsceneMM.h b/tools/ZAPD/ZAPD/ZCutsceneMM.h index 41b7de37f..44b108d6c 100644 --- a/tools/ZAPD/ZAPD/ZCutsceneMM.h +++ b/tools/ZAPD/ZAPD/ZCutsceneMM.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include "ZCutscene.h" diff --git a/tools/ZAPD/ZAPD/ZDisplayList.cpp b/tools/ZAPD/ZAPD/ZDisplayList.cpp index 63c568422..5e9b1b205 100644 --- a/tools/ZAPD/ZAPD/ZDisplayList.cpp +++ b/tools/ZAPD/ZAPD/ZDisplayList.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "Globals.h" @@ -11,6 +12,7 @@ #include "Utils/File.h" #include "Utils/Path.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "gfxd.h" REGISTER_ZFILENODE(DList, ZDisplayList); @@ -25,8 +27,8 @@ ZDisplayList::ZDisplayList(ZFile* nParent) : ZResource(nParent) lastTexSizTest = F3DZEXTexSizes::G_IM_SIZ_16b; lastTexLoaded = false; lastTexIsPalette = false; - name = ""; dListType = Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX; + RegisterOptionalAttribute("Ucode"); } ZDisplayList::~ZDisplayList() @@ -42,13 +44,29 @@ void ZDisplayList::ExtractFromXML(tinyxml2::XMLElement* reader, uint32_t nRawDat { rawDataIndex = nRawDataIndex; ParseXML(reader); + // TODO add error handling here + bool ucodeSet = registeredAttributes.at("Ucode").wasSet; + std::string ucodeValue = registeredAttributes.at("Ucode").value; + if ((Globals::Instance->game == ZGame::OOT_SW97) || (ucodeValue == "f3dex")) + { + dListType = DListType::F3DEX; + } + else if (!ucodeSet || ucodeValue == "f3dex2") + { + dListType = DListType::F3DZEX; + } + else + { + HANDLE_ERROR_RESOURCE( + WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + StringHelper::Sprintf("Invalid ucode type in node: %s\n", reader->Name()), ""); + } // Don't parse raw data of external files if (parent->GetMode() != ZFileMode::ExternalFile) { - int32_t rawDataSize = ZDisplayList::GetDListLength( - parent->GetRawData(), rawDataIndex, - Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX); + int32_t rawDataSize = + ZDisplayList::GetDListLength(parent->GetRawData(), rawDataIndex, dListType); numInstructions = rawDataSize / 8; ParseRawData(); } @@ -105,7 +123,7 @@ void ZDisplayList::ParseF3DZEX(F3DZEXOpcode opcode, uint64_t data, int32_t i, switch (opcode) { case F3DZEXOpcode::G_NOOP: - sprintf(line, "gsDPNoOpTag(0x%08lX),", data & 0xFFFFFFFF); + sprintf(line, "gsDPNoOpTag(0x%08" PRIX64 "),", data & 0xFFFFFFFF); break; case F3DZEXOpcode::G_DL: Opcode_G_DL(data, prefix, line); @@ -220,7 +238,7 @@ void ZDisplayList::ParseF3DZEX(F3DZEXOpcode opcode, uint64_t data, int32_t i, break; case F3DZEXOpcode::G_POPMTX: { - sprintf(line, "gsSPPopMatrix(%li),", data); + sprintf(line, "gsSPPopMatrix(%" PRIi64 "),", data); } break; case F3DZEXOpcode::G_LOADTLUT: @@ -297,7 +315,7 @@ void ZDisplayList::ParseF3DEX(F3DEXOpcode opcode, uint64_t data, const std::stri switch (opcode) { case F3DEXOpcode::G_NOOP: - sprintf(line, "gsDPNoOpTag(0x%08lX),", data & 0xFFFFFFFF); + sprintf(line, "gsDPNoOpTag(0x%08" PRIX64 "),", data & 0xFFFFFFFF); break; case F3DEXOpcode::G_VTX: Opcode_G_VTX(data, line); @@ -445,11 +463,12 @@ int32_t ZDisplayList::GetDListLength(const std::vector& rawData, uint32 { if (ptr >= rawDataSize) { - throw std::runtime_error(StringHelper::Sprintf( - "%s: Fatal error.\n" - "\t End of file found when trying to find the end of the " - "DisplayList at offset: '0x%X'.\n", - "Raw data size: 0x%zX.\n", __PRETTY_FUNCTION__, rawDataIndex, rawDataSize)); + std::string errorHeader = + StringHelper::Sprintf("reached end of file when trying to find the end of the " + "DisplayList starting at offset 0x%X", + rawDataIndex); + std::string errorBody = StringHelper::Sprintf("Raw data size: 0x%zX.", rawDataSize); + HANDLE_ERROR_PROCESS(WarningType::Always, errorHeader, errorBody); } uint8_t opcode = rawData.at(ptr); @@ -686,20 +705,22 @@ void ZDisplayList::Opcode_G_DL(uint64_t data, const std::string& prefix, char* l if (pp != 0) { if (!Globals::Instance->HasSegment(segNum)) - sprintf(line, "gsSPBranchList(0x%08lX),", data & 0xFFFFFFFF); + sprintf(line, "gsSPBranchList(0x%08" PRIX64 "),", data & 0xFFFFFFFF); else if (dListDecl != nullptr) sprintf(line, "gsSPBranchList(%s),", dListDecl->varName.c_str()); else - sprintf(line, "gsSPBranchList(%sDlist0x%06lX),", prefix.c_str(), GETSEGOFFSET(data)); + sprintf(line, "gsSPBranchList(%sDlist0x%06" PRIX64 "),", prefix.c_str(), + GETSEGOFFSET(data)); } else { if (!Globals::Instance->HasSegment(segNum)) - sprintf(line, "gsSPDisplayList(0x%08lX),", data & 0xFFFFFFFF); + sprintf(line, "gsSPDisplayList(0x%08" PRIX64 "),", data & 0xFFFFFFFF); else if (dListDecl != nullptr) sprintf(line, "gsSPDisplayList(%s),", dListDecl->varName.c_str()); else - sprintf(line, "gsSPDisplayList(%sDlist0x%06lX),", prefix.c_str(), GETSEGOFFSET(data)); + sprintf(line, "gsSPDisplayList(%sDlist0x%06" PRIX64 "),", prefix.c_str(), + GETSEGOFFSET(data)); } // if (segNum == 8 || segNum == 9 || segNum == 10 || segNum == 11 || segNum == 12 || segNum == @@ -707,9 +728,9 @@ void ZDisplayList::Opcode_G_DL(uint64_t data, const std::string& prefix, char* l if (!Globals::Instance->HasSegment(segNum)) { if (pp != 0) - sprintf(line, "gsSPBranchList(0x%08lX),", data & 0xFFFFFFFF); + sprintf(line, "gsSPBranchList(0x%08" PRIX64 "),", data & 0xFFFFFFFF); else - sprintf(line, "gsSPDisplayList(0x%08lX),", data & 0xFFFFFFFF); + sprintf(line, "gsSPDisplayList(0x%08" PRIX64 "),", data & 0xFFFFFFFF); } else { @@ -829,7 +850,7 @@ void ZDisplayList::Opcode_G_VTX(uint64_t data, char* line) { segptr_t segmented = data & 0xFFFFFFFF; references.push_back(segmented); - parent->AddDeclaration(segmented, DeclarationAlignment::Align16, 16, "Vtx", + parent->AddDeclaration(segmented, DeclarationAlignment::Align8, 16, "Vtx", StringHelper::Sprintf("0x%08X", segmented), ""); return; } @@ -941,7 +962,7 @@ void ZDisplayList::Opcode_G_SETTIMG(uint64_t data, const std::string& prefix, ch sprintf(texStr, "%sTex_%06X", prefix.c_str(), texAddress); else { - sprintf(texStr, "0x%08lX", data & 0xFFFFFFFF); + sprintf(texStr, "0x%08" PRIX64, data & 0xFFFFFFFF); } sprintf(line, "gsDPSetTextureImage(%s, %s, %i, %s),", fmtTbl[fmt], sizTbl[siz], www + 1, @@ -1522,11 +1543,6 @@ void ZDisplayList::Opcode_G_ENDDL([[maybe_unused]] const std::string& prefix, ch TextureGenCheck(); } -std::string ZDisplayList::GetSourceOutputHeader([[maybe_unused]] const std::string& prefix) -{ - return ""; -} - static int32_t GfxdCallback_FormatSingleEntry() { ZDisplayList* self = static_cast(gfxd_udata_get()); @@ -1737,7 +1753,7 @@ static int32_t GfxdCallback_Matrix(uint32_t seg) return 1; } -std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix) +void ZDisplayList::DeclareReferences(const std::string& prefix) { std::string sourceOutput; @@ -1775,15 +1791,13 @@ std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix) // Generate Vertex Declarations for (auto& item : vertices) { - std::string declaration; + std::string declaration = ""; offset_t curAddr = item.first; auto& firstVtx = item.second.at(0); for (auto vtx : item.second) - { declaration += StringHelper::Sprintf("\t%s,\n", vtx.GetBodySourceCode().c_str()); - } Declaration* decl = parent->AddDeclarationArray( curAddr, firstVtx.GetDeclarationAlignment(), @@ -1863,11 +1877,6 @@ std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix) } } } - - if (parent != nullptr) - return ""; - - return sourceOutput; } std::string ZDisplayList::ProcessLegacy(const std::string& prefix) @@ -1899,10 +1908,10 @@ std::string ZDisplayList::ProcessLegacy(const std::string& prefix) } auto end = std::chrono::steady_clock::now(); - auto diff = std::chrono::duration_cast(end - start).count(); + int64_t diff = std::chrono::duration_cast(end - start).count(); if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG && diff > 5) - printf("F3DOP: 0x%02X, TIME: %lims\n", opcode, diff); + printf("F3DOP: 0x%02X, TIME: %" PRIi64 "ms\n", opcode, diff); sourceOutput += line; @@ -1983,7 +1992,7 @@ bool ZDisplayList::TextureGenCheck(int32_t texWidth, int32_t texHeight, uint32_t } else { - // Try to find a non-external file (ie, one we are actually extracting) + // Try to find a non-external file (i.e., one we are actually extracting) // which has the same segment number we are looking for. for (auto& otherFile : Globals::Instance->cfg.segmentRefFiles[segmentNumber]) { diff --git a/tools/ZAPD/ZAPD/ZDisplayList.h b/tools/ZAPD/ZAPD/ZDisplayList.h index d53866675..96808315d 100644 --- a/tools/ZAPD/ZAPD/ZDisplayList.h +++ b/tools/ZAPD/ZAPD/ZDisplayList.h @@ -363,8 +363,7 @@ public: size_t GetRawDataSize() const override; DeclarationAlignment GetDeclarationAlignment() const override; - std::string GetSourceOutputHeader(const std::string& prefix) override; - std::string GetSourceOutputCode(const std::string& prefix) override; + void DeclareReferences(const std::string& prefix) override; std::string ProcessLegacy(const std::string& prefix); std::string ProcessGfxDis(const std::string& prefix); diff --git a/tools/ZAPD/ZAPD/ZFile.cpp b/tools/ZAPD/ZAPD/ZFile.cpp index 7cbfeba88..22a6a4505 100644 --- a/tools/ZAPD/ZAPD/ZFile.cpp +++ b/tools/ZAPD/ZAPD/ZFile.cpp @@ -8,11 +8,13 @@ #include "Globals.h" #include "OutputFormatter.h" #include "Utils/BinaryWriter.h" +#include "Utils/BitConverter.h" #include "Utils/Directory.h" #include "Utils/File.h" #include "Utils/MemoryStream.h" #include "Utils/Path.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZAnimation.h" #include "ZArray.h" #include "ZBackground.h" @@ -73,19 +75,13 @@ ZFile::ZFile(ZFileMode nMode, tinyxml2::XMLElement* reader, const fs::path& nBas ZFile::~ZFile() { for (ZResource* res : resources) - { delete res; - } for (auto d : declarations) - { delete d.second; - } for (auto sym : symbolResources) - { delete sym.second; - } } void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) @@ -114,8 +110,11 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) else if (std::string_view(gameStr) == "OOT") Globals::Instance->game = ZGame::OOT_RETAIL; else - throw std::runtime_error( - StringHelper::Sprintf("Error: Game type %s not supported.", gameStr)); + { + std::string errorHeader = + StringHelper::Sprintf("'Game' type '%s' is not supported.", gameStr); + HANDLE_ERROR_PROCESS(WarningType::InvalidAttributeValue, errorHeader, ""); + } } if (reader->Attribute("BaseAddress") != nullptr) @@ -128,16 +127,22 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) rangeEnd = StringHelper::StrToL(reader->Attribute("RangeEnd"), 16); if (rangeStart > rangeEnd) - throw std::runtime_error("Error: RangeStart must be before than RangeEnd."); + HANDLE_ERROR_PROCESS( + WarningType::Always, + StringHelper::Sprintf("'RangeStart' 0x%06X must be before 'RangeEnd' 0x%06X", + rangeStart, rangeEnd), + ""); const char* segmentXml = reader->Attribute("Segment"); if (segmentXml != nullptr) { if (!StringHelper::HasOnlyDigits(segmentXml)) { - throw std::runtime_error(StringHelper::Sprintf( - "error: Invalid segment value '%s': must be a decimal between 0 and 15 inclusive", - segmentXml)); + HANDLE_ERROR_PROCESS(WarningType::Always, + StringHelper::Sprintf("error: Invalid segment value '%s': must be " + "a decimal between 0 and 15 inclusive", + segmentXml), + ""); } segment = StringHelper::StrToL(segmentXml, 10); @@ -146,16 +151,19 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) if (segment == 128) { #ifdef DEPRECATION_ON - fprintf(stderr, "warning: segment 128 is deprecated.\n\tRemove " - "'Segment=\"128\"' from the xml to use virtual addresses\n"); + HANDLE_WARNING_PROCESS( + WarningType::Always, "warning: segment 128 is deprecated.", + "Remove 'Segment=\"128\"' from the xml to use virtual addresses\n"); #endif } else { - throw std::runtime_error( + HANDLE_ERROR_PROCESS( + WarningType::Always, StringHelper::Sprintf("error: invalid segment value '%s': must be a decimal " "number between 0 and 15 inclusive", - segmentXml)); + segmentXml), + ""); } } } @@ -176,18 +184,16 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) if (mode == ZFileMode::Extract || mode == ZFileMode::ExternalFile) { if (!File::Exists((basePath / name).string())) - throw std::runtime_error( - StringHelper::Sprintf("Error! File %s does not exist.", (basePath / name).c_str())); + { + std::string errorHeader = StringHelper::Sprintf("binary file '%s' does not exist.", + (basePath / name).c_str()); + HANDLE_ERROR_PROCESS(WarningType::Always, errorHeader, ""); + } rawData = File::ReadAllBytes((basePath / name).string()); - /* - * TODO: In OoT repo ovl_Boss_Sst has a wrong RangeEnd (0xAD40 instead of 0xAD70), - * so uncommenting the following produces wrong behavior. - * If somebody fixes that in OoT repo, uncomment this. I'm too tired of fixing XMLs. - */ - // if (reader->Attribute("RangeEnd") == nullptr) - // rangeEnd = rawData.size(); + if (reader->Attribute("RangeEnd") == nullptr) + rangeEnd = rawData.size(); } std::unordered_set nameSet; @@ -211,20 +217,17 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) if (offsetSet.find(offsetXml) != offsetSet.end()) { - throw std::runtime_error(StringHelper::Sprintf( - "ZFile::ParseXML: Error in '%s'.\n\t Repeated 'Offset' attribute: %s \n", - name.c_str(), offsetXml)); + std::string errorHeader = + StringHelper::Sprintf("repeated 'Offset' attribute: %s", offsetXml); + HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, ""); } offsetSet.insert(offsetXml); } - else if (Globals::Instance->warnNoOffset) + else { - fprintf(stderr, "Warning No offset specified for: %s", nameXml); - } - else if (Globals::Instance->errorNoOffset) - { - throw std::runtime_error( - StringHelper::Sprintf("Error no offset specified for %s", nameXml)); + HANDLE_WARNING_RESOURCE(WarningType::MissingOffsets, this, nullptr, rawDataIndex, + StringHelper::Sprintf("no offset specified for %s.", nameXml), + ""); } if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) @@ -234,9 +237,9 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) { if (outNameSet.find(outNameXml) != outNameSet.end()) { - throw std::runtime_error(StringHelper::Sprintf( - "ZFile::ParseXML: Error in '%s'.\n\t Repeated 'OutName' attribute: %s \n", - name.c_str(), outNameXml)); + std::string errorHeader = + StringHelper::Sprintf("repeated 'OutName' attribute: %s", outNameXml); + HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, ""); } outNameSet.insert(outNameXml); } @@ -244,9 +247,9 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) { if (nameSet.find(nameXml) != nameSet.end()) { - throw std::runtime_error(StringHelper::Sprintf( - "ZFile::ParseXML: Error in '%s'.\n\t Repeated 'Name' attribute: %s \n", - name.c_str(), nameXml)); + std::string errorHeader = + StringHelper::Sprintf("repeated 'Name' attribute: %s", nameXml); + HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, ""); } nameSet.insert(nameXml); } @@ -279,16 +282,14 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename) } else if (std::string_view(child->Name()) == "File") { - throw std::runtime_error(StringHelper::Sprintf( - "ZFile::ParseXML: Error in '%s'.\n\t Can't declare a File inside a File.\n", - name.c_str())); + std::string errorHeader = "Can't declare a inside a "; + HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, ""); } else { - throw std::runtime_error( - StringHelper::Sprintf("ZFile::ParseXML: Error in '%s'.\n\t Unknown element found " - "inside a File element: '%s'.\n", - name.c_str(), nodeName.c_str())); + std::string errorHeader = StringHelper::Sprintf( + "Unknown element found inside a element: %s", nodeName.c_str()); + HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, ""); } } } @@ -307,7 +308,7 @@ void ZFile::BuildSourceFile() return; if (!Directory::Exists(outputPath)) - Directory::CreateDirectory(outputPath); + Directory::CreateDirectory(outputPath.string()); GenerateSourceFiles(); } @@ -317,6 +318,11 @@ std::string ZFile::GetName() const return name; } +std::string ZFile::GetOutName() const +{ + return outName.string(); +} + ZFileMode ZFile::GetMode() const { return mode; @@ -338,10 +344,10 @@ void ZFile::ExtractResources() return; if (!Directory::Exists(outputPath)) - Directory::CreateDirectory(outputPath); + Directory::CreateDirectory(outputPath.string()); if (!Directory::Exists(GetSourceOutputFolderPath())) - Directory::CreateDirectory(GetSourceOutputFolderPath()); + Directory::CreateDirectory(GetSourceOutputFolderPath().string()); for (size_t i = 0; i < resources.size(); i++) resources[i]->ParseRawDataLate(); @@ -351,8 +357,8 @@ void ZFile::ExtractResources() if (Globals::Instance->genSourceFile) GenerateSourceFiles(); - MemoryStream* memStream = new MemoryStream(); - BinaryWriter writer = BinaryWriter(memStream); + auto memStreamFile = std::shared_ptr(new MemoryStream()); + BinaryWriter writerFile = BinaryWriter(memStreamFile); ExporterSet* exporterSet = Globals::Instance->GetExporterSet(); @@ -361,6 +367,9 @@ void ZFile::ExtractResources() for (ZResource* res : resources) { + auto memStreamRes = std::shared_ptr(new MemoryStream()); + BinaryWriter writerRes = BinaryWriter(memStreamRes); + if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO) printf("Saving resource %s\n", res->GetName().c_str()); @@ -369,18 +378,24 @@ void ZFile::ExtractResources() // Check if we have an exporter "registered" for this resource type ZResourceExporter* exporter = Globals::Instance->GetExporter(res->GetResourceType()); if (exporter != nullptr) - exporter->Save(res, Globals::Instance->outputPath.string(), &writer); + { + // exporter->Save(res, Globals::Instance->outputPath.string(), &writerFile); + exporter->Save(res, Globals::Instance->outputPath.string(), &writerRes); + } + + if (exporterSet != nullptr && exporterSet->resSaveFunc != nullptr) + exporterSet->resSaveFunc(res, writerRes); } - if (memStream->GetLength() > 0) + if (memStreamFile->GetLength() > 0) { File::WriteAllBytes(StringHelper::Sprintf("%s%s.bin", Globals::Instance->outputPath.string().c_str(), GetName().c_str()), - memStream->ToVector()); + memStreamFile->ToVector()); } - writer.Close(); + writerFile.Close(); if (exporterSet != nullptr && exporterSet->endFileFunc != nullptr) exporterSet->endFileFunc(this); @@ -935,9 +950,6 @@ std::string ZFile::ProcessDeclarations() defines += ProcessTextureIntersections(name); - // Account for padding/alignment - uint32_t lastAddr = 0; - // printf("RANGE START: 0x%06X - RANGE END: 0x%06X\n", rangeStart, rangeEnd); // Optimization: See if there are any arrays side by side that can be merged... @@ -988,43 +1000,6 @@ std::string ZFile::ProcessDeclarations() { while (item.second->size % 4 != 0) item.second->size++; - - if (lastAddr != 0) - { - if (item.second->alignment == DeclarationAlignment::Align16) - { - int32_t curPtr = lastAddr + declarations[lastAddr]->size; - - while (curPtr % 4 != 0) - { - declarations[lastAddr]->size++; - curPtr++; - } - } - else if (item.second->alignment == DeclarationAlignment::Align8) - { - size_t curPtr = lastAddr + declarations[lastAddr]->size; - - while (curPtr % 4 != 0) - { - declarations[lastAddr]->size++; - curPtr++; - } - - while (curPtr % 8 != 0) - { - char buffer[2048]; - - sprintf(buffer, "u32 %s_align%02zX = 0;\n", name.c_str(), curPtr); - item.second->preText = buffer + item.second->preText; - - declarations[lastAddr]->size += 4; - curPtr += 4; - } - } - } - - lastAddr = item.first; } HandleUnaccountedData(); @@ -1070,8 +1045,6 @@ std::string ZFile::ProcessDeclarations() } } - output += "\n"; - return output; } @@ -1187,14 +1160,15 @@ void ZFile::HandleUnaccountedData() { uint32_t lastAddr = 0; uint32_t lastSize = 0; - std::vector declsAddresses; + std::vector declsAddresses; + for (const auto& item : declarations) { declsAddresses.push_back(item.first); } bool breakLoop = false; - for (uint32_t currentAddress : declsAddresses) + for (offset_t currentAddress : declsAddresses) { if (currentAddress >= rangeEnd) { @@ -1223,7 +1197,7 @@ void ZFile::HandleUnaccountedData() } } -bool ZFile::HandleUnaccountedAddress(uint32_t currentAddress, uint32_t lastAddr, uint32_t& lastSize) +bool ZFile::HandleUnaccountedAddress(offset_t currentAddress, offset_t lastAddr, uint32_t& lastSize) { if (currentAddress != lastAddr && declarations.find(lastAddr) != declarations.end()) { @@ -1234,11 +1208,12 @@ bool ZFile::HandleUnaccountedAddress(uint32_t currentAddress, uint32_t lastAddr, { Declaration* currentDecl = declarations.at(currentAddress); - fprintf(stderr, - "WARNING: Intersection detected from 0x%06X:0x%06X (%s), conflicts with " - "0x%06X (%s)\n", - lastAddr, lastAddr + lastSize, lastDecl->varName.c_str(), currentAddress, - currentDecl->varName.c_str()); + std::string intersectionInfo = StringHelper::Sprintf( + "Resource from 0x%06X:0x%06X (%s) conflicts with 0x%06X (%s).", lastAddr, + lastAddr + lastSize, lastDecl->varName.c_str(), currentAddress, + currentDecl->varName.c_str()); + HANDLE_WARNING_RESOURCE(WarningType::Intersection, this, nullptr, currentAddress, + "intersection detected", intersectionInfo); } } @@ -1262,6 +1237,29 @@ bool ZFile::HandleUnaccountedAddress(uint32_t currentAddress, uint32_t lastAddr, xmlFilePath.c_str(), currentAddress, name.c_str(), rawData.size())); } + // Handle Align8 + if (currentAddress % 8 == 0 && diff % 8 != 0) + { + Declaration* currentDecl = GetDeclaration(currentAddress); + + if (currentDecl != nullptr) + { + if (currentDecl->alignment == DeclarationAlignment::Align8) + { + // Check removed bytes are zeroes + if (BitConverter::ToUInt32BE(rawData, unaccountedAddress + diff - 4) == 0) + { + diff -= 4; + } + } + + if (diff == 0) + { + return false; + } + } + } + for (int i = 0; i < diff; i++) { uint8_t val = rawData.at(unaccountedAddress + i); @@ -1307,27 +1305,22 @@ bool ZFile::HandleUnaccountedAddress(uint32_t currentAddress, uint32_t lastAddr, StringHelper::Sprintf("%s_%s_%06X", name.c_str(), unaccountedPrefix.c_str(), unaccountedAddress), diff, src); - decl->isUnaccounted = true; - if (Globals::Instance->warnUnaccounted) + decl->isUnaccounted = true; + if (Globals::Instance->forceUnaccountedStatic) + decl->staticConf = StaticConfig::On; + + if (nonZeroUnaccounted) { - if (nonZeroUnaccounted) - { - fprintf(stderr, - "Warning in file: %s (%s)\n" - "\t A non-zero unaccounted block was found at offset '0x%06X'.\n" - "\t Block size: '0x%X'.\n", - xmlFilePath.c_str(), name.c_str(), unaccountedAddress, diff); - } - else if (diff >= 16) - { - fprintf(stderr, - "Warning in file: %s (%s)\n" - "\t A big (size>=0x10) zero-only unaccounted block was found " - "at offset '0x%06X'.\n" - "\t Block size: '0x%X'.\n", - xmlFilePath.c_str(), name.c_str(), unaccountedAddress, diff); - } + HANDLE_WARNING_RESOURCE(WarningType::Unaccounted, this, nullptr, unaccountedAddress, + "a non-zero unaccounted block was found", + StringHelper::Sprintf("Block size: '0x%X'", diff)); + } + else if (diff >= 16) + { + HANDLE_WARNING_RESOURCE(WarningType::Unaccounted, this, nullptr, unaccountedAddress, + "a big (size>=0x10) zero-only unaccounted block was found", + StringHelper::Sprintf("Block size: '0x%X'", diff)); } } } diff --git a/tools/ZAPD/ZAPD/ZFile.h b/tools/ZAPD/ZAPD/ZFile.h index 9de6950e4..ac4062d5b 100644 --- a/tools/ZAPD/ZAPD/ZFile.h +++ b/tools/ZAPD/ZAPD/ZFile.h @@ -1,6 +1,5 @@ #pragma once -#include #include #include @@ -46,6 +45,7 @@ public: ~ZFile(); std::string GetName() const; + std::string GetOutName() const; ZFileMode GetMode() const; const fs::path& GetXmlFilePath() const; const std::vector& GetRawData() const; @@ -133,5 +133,5 @@ protected: std::string ProcessTextureIntersections(const std::string& prefix); void HandleUnaccountedData(); - bool HandleUnaccountedAddress(uint32_t currentAddress, uint32_t lastAddr, uint32_t& lastSize); + bool HandleUnaccountedAddress(offset_t currentAddress, offset_t lastAddr, uint32_t& lastSize); }; diff --git a/tools/ZAPD/ZAPD/ZLimb.cpp b/tools/ZAPD/ZAPD/ZLimb.cpp index 77c66871f..330fbaf7c 100644 --- a/tools/ZAPD/ZAPD/ZLimb.cpp +++ b/tools/ZAPD/ZAPD/ZLimb.cpp @@ -4,7 +4,7 @@ #include "Globals.h" #include "Utils/BitConverter.h" -#include "Utils/StringHelper.h" +#include "WarningHandler.h" REGISTER_ZFILENODE(Limb, ZLimb); @@ -37,17 +37,15 @@ void ZLimb::ParseXML(tinyxml2::XMLElement* reader) if (limbType == "") { - throw std::runtime_error(StringHelper::Sprintf("ZLimb::ParseXML: Error in '%s'.\n" - "\t Missing 'LimbType' attribute in xml.\n", - name.c_str())); + HANDLE_ERROR_RESOURCE(WarningType::MissingAttribute, parent, this, rawDataIndex, + "missing 'LimbType' attribute in ", ""); } type = GetTypeByAttributeName(limbType); if (type == ZLimbType::Invalid) { - throw std::runtime_error(StringHelper::Sprintf("ZLimb::ParseXML: Error in '%s'.\n" - "\t Invalid 'LimbType' found: '%s'.\n", - name.c_str(), limbType.c_str())); + HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + "invalid value found for 'LimbType' attribute", ""); } } @@ -109,8 +107,12 @@ void ZLimb::ParseRawData() } break; - default: - throw std::runtime_error("Invalid ZLimb type"); + case ZLimbType::Curve: + case ZLimbType::Legacy: + break; + + case ZLimbType::Invalid: + assert(!"whoops"); break; } } @@ -226,8 +228,8 @@ std::string ZLimb::GetBodySourceCode() const { std::string childName; std::string siblingName; - Globals::Instance->GetSegmentedPtrName(childPtr, parent, "Gfx", childName); - Globals::Instance->GetSegmentedPtrName(siblingPtr, parent, "Gfx", siblingName); + Globals::Instance->GetSegmentedPtrName(childPtr, parent, "LegacyLimb", childName); + Globals::Instance->GetSegmentedPtrName(siblingPtr, parent, "LegacyLimb", siblingName); entryStr += StringHelper::Sprintf("%s,\n", dListStr.c_str()); entryStr += diff --git a/tools/ZAPD/ZAPD/ZPath.cpp b/tools/ZAPD/ZAPD/ZPath.cpp index 4a95c5b91..e19513db3 100644 --- a/tools/ZAPD/ZAPD/ZPath.cpp +++ b/tools/ZAPD/ZAPD/ZPath.cpp @@ -3,6 +3,7 @@ #include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZFile.h" REGISTER_ZFILENODE(Path, ZPath); @@ -20,10 +21,12 @@ void ZPath::ParseXML(tinyxml2::XMLElement* reader) numPaths = StringHelper::StrToL(registeredAttributes.at("NumPaths").value); if (numPaths < 1) - throw std::runtime_error( - StringHelper::Sprintf("ZPath::ParseXML: Fatal error in '%s'.\n" - "\t Invalid value for attribute 'NumPaths': '%i'\n", - name.c_str(), numPaths)); + { + HANDLE_ERROR_RESOURCE( + WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + StringHelper::Sprintf("invalid value '%d' found for 'NumPaths' attribute", numPaths), + "Should be at least '1'"); + } } void ZPath::ParseRawData() @@ -144,7 +147,7 @@ void PathwayEntry::DeclareReferences(const std::string& prefix) if (addressFound) return; - std::string declaration; + std::string declaration = ""; size_t index = 0; for (const auto& point : points) diff --git a/tools/ZAPD/ZAPD/ZResource.cpp b/tools/ZAPD/ZAPD/ZResource.cpp index cb811f4c3..2dfe6d5ea 100644 --- a/tools/ZAPD/ZAPD/ZResource.cpp +++ b/tools/ZAPD/ZAPD/ZResource.cpp @@ -4,6 +4,7 @@ #include #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZFile.h" ZResource::ZResource(ZFile* nParent) @@ -85,29 +86,33 @@ void ZResource::ParseXML(tinyxml2::XMLElement* reader) } if (!attrDeclared) - fprintf(stderr, - "ZResource::ParseXML: Warning while parsing '%s'.\n" - "\t Unexpected '%s' attribute in resource '%s'.\n", - parent->GetName().c_str(), attrName.c_str(), reader->Name()); + { + HANDLE_WARNING_RESOURCE( + WarningType::UnknownAttribute, parent, this, rawDataIndex, + StringHelper::Sprintf("unexpected '%s' attribute in resource <%s>", + attrName.c_str(), reader->Name()), + ""); + } attrs = attrs->Next(); } if (!canHaveInner && !reader->NoChildren()) { - throw std::runtime_error( - StringHelper::Sprintf("ZResource::ParseXML: Fatal error in '%s'.\n" - "\t Resource '%s' with inner element/child detected.\n", - name.c_str(), reader->Name())); + std::string errorHeader = StringHelper::Sprintf( + "resource '%s' with inner element/child detected", reader->Name()); + HANDLE_ERROR_PROCESS(WarningType::InvalidXML, errorHeader, ""); } for (const auto& attr : registeredAttributes) { if (attr.second.isRequired && attr.second.value == "") - throw std::runtime_error(StringHelper::Sprintf( - "ZResource::ParseXML: Fatal error while parsing '%s'.\n" - "\t Missing required attribute '%s' in resource '%s'.\n" - "\t Aborting...", - parent->GetName().c_str(), attr.first.c_str(), reader->Name())); + { + std::string headerMsg = + StringHelper::Sprintf("missing required attribute '%s' in resource <%s>", + attr.first.c_str(), reader->Name()); + HANDLE_ERROR_RESOURCE(WarningType::MissingAttribute, parent, this, rawDataIndex, + headerMsg, ""); + } } name = registeredAttributes.at("Name").value; @@ -118,10 +123,8 @@ void ZResource::ParseXML(tinyxml2::XMLElement* reader) { if (!std::regex_match(name, r)) { - throw std::domain_error( - StringHelper::Sprintf("ZResource::ParseXML: Fatal error in '%s'.\n" - "\t Resource with invalid 'Name' attribute.\n", - name.c_str())); + HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, + rawDataIndex, "invalid value found for 'Name' attribute", ""); } } @@ -146,7 +149,9 @@ void ZResource::ParseXML(tinyxml2::XMLElement* reader) } else { - throw std::runtime_error("Invalid value for 'Static' attribute."); + HANDLE_ERROR_RESOURCE( + WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + StringHelper::Sprintf("invalid value '%s' for 'Static' attribute", staticConf), ""); } declaredInXml = true; @@ -253,18 +258,21 @@ std::string ZResource::GetDefaultName(const std::string& prefix) const rawDataIndex); } -std::string ZResource::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) +void ZResource::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) { std::string bodyStr = GetBodySourceCode(); - Declaration* decl = parent->GetDeclaration(rawDataIndex); - if (decl == nullptr || decl->isPlaceholder) - decl = DeclareVar(prefix, bodyStr); - else - decl->text = bodyStr; - decl->staticConf = staticConf; + if (bodyStr != "ERROR") + { + Declaration* decl = parent->GetDeclaration(rawDataIndex); - return ""; + if (decl == nullptr || decl->isPlaceholder) + decl = DeclareVar(prefix, bodyStr); + else + decl->text = bodyStr; + + decl->staticConf = staticConf; + } } std::string ZResource::GetSourceOutputHeader([[maybe_unused]] const std::string& prefix) @@ -312,13 +320,13 @@ offset_t Seg2Filespace(segptr_t segmentedAddress, uint32_t parentBaseAddress) uint32_t parentBaseOffset = GETSEGOFFSET(parentBaseAddress); if (parentBaseOffset > currentPtr) { - throw std::runtime_error( - StringHelper::Sprintf("\nSeg2Filespace: Segmented address is smaller than " - "'BaseAddress'. Maybe your 'BaseAddress' is wrong?\n" - "\t SegmentedAddress: 0x%08X\n" - "\t BaseAddress: 0x%08X\n", - segmentedAddress, parentBaseAddress)); + HANDLE_ERROR(WarningType::Always, + StringHelper::Sprintf( + "resource address 0x%08X is smaller than 'BaseAddress' 0x%08X", + segmentedAddress, parentBaseAddress), + "Maybe your 'BaseAddress' is wrong?"); } + currentPtr -= parentBaseOffset; } diff --git a/tools/ZAPD/ZAPD/ZResource.h b/tools/ZAPD/ZAPD/ZResource.h index ff35786fa..4dad39895 100644 --- a/tools/ZAPD/ZAPD/ZResource.h +++ b/tools/ZAPD/ZAPD/ZResource.h @@ -1,16 +1,15 @@ #pragma once -#include +#include #include #include -#include #include #include #include "Declaration.h" +#include "Utils/BinaryWriter.h" +#include "Utils/Directory.h" #include "tinyxml2.h" -#include - #define SEGMENT_SCENE 2 #define SEGMENT_ROOM 3 #define SEGMENT_KEEP 4 @@ -113,7 +112,7 @@ public: */ [[nodiscard]] virtual std::string GetDefaultName(const std::string& prefix) const; - virtual std::string GetSourceOutputCode(const std::string& prefix); + virtual void GetSourceOutputCode(const std::string& prefix); virtual std::string GetSourceOutputHeader(const std::string& prefix); virtual void CalcHash(); /** diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.cpp index d1c8abd5c..ba0bbe2c2 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.cpp @@ -1,8 +1,10 @@ #include "SetMesh.h" -#include -#include + +#include "Globals.h" #include "Utils/BitConverter.h" +#include "Utils/Path.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZBackground.h" #include "ZFile.h" #include "ZRoom/ZRoom.h" @@ -34,9 +36,8 @@ void SetMesh::ParseRawData() break; default: - throw std::runtime_error(StringHelper::Sprintf("Error in SetMesh::ParseRawData\n" - "\t Unknown meshHeaderType: %i\n", - meshHeaderType)); + HANDLE_ERROR(WarningType::InvalidExtractedData, + StringHelper::Sprintf("unknown meshHeaderType: %i", meshHeaderType), ""); } polyType->ParseRawData(); @@ -53,11 +54,9 @@ void SetMesh::DeclareReferences(const std::string& prefix) void GenDListDeclarations(ZRoom* zRoom, ZFile* parent, ZDisplayList* dList) { if (dList == nullptr) - { return; - } - std::string sourceOutput = dList->GetSourceOutputCode(zRoom->GetName()); + dList->DeclareReferences(zRoom->GetName()); for (ZDisplayList* otherDList : dList->otherDLists) GenDListDeclarations(zRoom, parent, otherDList); @@ -143,21 +142,16 @@ std::string PolygonDlist::GetBodySourceCode() const return bodyStr; } -std::string PolygonDlist::GetSourceOutputCode(const std::string& prefix) +void PolygonDlist::GetSourceOutputCode(const std::string& prefix) { std::string bodyStr = StringHelper::Sprintf("\n\t%s\n", GetBodySourceCode().c_str()); Declaration* decl = parent->GetDeclaration(rawDataIndex); - if (decl == nullptr) - { - DeclareVar(prefix, bodyStr); - } - else - { - decl->text = bodyStr; - } - return ""; + if (decl == nullptr) + DeclareVar(prefix, bodyStr); + else + decl->text = bodyStr; } std::string PolygonDlist::GetSourceTypeName() const @@ -472,8 +466,8 @@ void PolygonType1::DeclareReferences(const std::string& prefix) break; default: - throw std::runtime_error(StringHelper::Sprintf( - "Error in PolygonType1::PolygonType1\n\t Unknown format: %i\n", format)); + HANDLE_ERROR(WarningType::InvalidExtractedData, + StringHelper::Sprintf("unknown format: %i", format), ""); break; } } @@ -582,9 +576,11 @@ void PolygonType2::DeclareReferences(const std::string& prefix) polyDListName = StringHelper::Sprintf("%s%s_%06X", prefix.c_str(), polyDlistType.c_str(), GETSEGOFFSET(start)); - parent->AddDeclarationArray(GETSEGOFFSET(start), DeclarationAlignment::Align4, - polyDLists.size() * polyDLists.at(0).GetRawDataSize(), - polyDlistType, polyDListName, polyDLists.size(), declaration); + Declaration* decl = parent->AddDeclarationArray( + GETSEGOFFSET(start), DeclarationAlignment::Align4, + polyDLists.size() * polyDLists.at(0).GetRawDataSize(), polyDlistType, polyDListName, + polyDLists.size(), declaration); + decl->forceArrayCnt = true; } parent->AddDeclaration(GETSEGOFFSET(end), DeclarationAlignment::Align4, 4, "s32", diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.h index 566711a9a..9d9037417 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.h +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetMesh.h @@ -28,7 +28,7 @@ public: std::string GetBodySourceCode() const override; - std::string GetSourceOutputCode(const std::string& prefix) override; + void GetSourceOutputCode(const std::string& prefix) override; std::string GetSourceTypeName() const override; ZResourceType GetResourceType() const override; diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.cpp index 43c396822..7027fa1f9 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.cpp @@ -115,11 +115,9 @@ std::string RomFile::GetBodySourceCode() const return declaration; } -std::string RomFile::GetSourceOutputCode(const std::string& prefix) +void RomFile::GetSourceOutputCode(const std::string& prefix) { DeclareVar(prefix, GetBodySourceCode()); - - return ""; } std::string RomFile::GetSourceTypeName() const diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.h b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.h index 4fb2ced17..2ae48b68d 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.h +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetRoomList.h @@ -24,7 +24,7 @@ public: Declaration* DeclareVar(const std::string& prefix, const std::string& body) override; std::string GetBodySourceCode() const override; - std::string GetSourceOutputCode(const std::string& prefix) override; + void GetSourceOutputCode(const std::string& prefix) override; std::string GetSourceTypeName() const override; virtual ZResourceType GetResourceType() const override; diff --git a/tools/ZAPD/ZAPD/ZRoom/Commands/SetSpecialObjects.cpp b/tools/ZAPD/ZAPD/ZRoom/Commands/SetSpecialObjects.cpp index 0c24a2f32..696a3de01 100644 --- a/tools/ZAPD/ZAPD/ZRoom/Commands/SetSpecialObjects.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/Commands/SetSpecialObjects.cpp @@ -1,6 +1,8 @@ #include "SetSpecialObjects.h" + #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" +#include "ZRoom/ZNames.h" SetSpecialObjects::SetSpecialObjects(ZFile* nParent) : ZRoomCommand(nParent) { @@ -15,8 +17,10 @@ void SetSpecialObjects::ParseRawData() std::string SetSpecialObjects::GetBodySourceCode() const { - return StringHelper::Sprintf("SCENE_CMD_SPECIAL_FILES(0x%02X, 0x%04X)", elfMessage, - globalObject); + std::string objectName = ZNames::GetObjectName(globalObject); + + return StringHelper::Sprintf("SCENE_CMD_SPECIAL_FILES(0x%02X, %s)", elfMessage, + objectName.c_str()); } std::string SetSpecialObjects::GetCommandCName() const diff --git a/tools/ZAPD/ZAPD/ZRoom/ZRoom.cpp b/tools/ZAPD/ZAPD/ZRoom/ZRoom.cpp index edc0cad02..5831eaa56 100644 --- a/tools/ZAPD/ZAPD/ZRoom/ZRoom.cpp +++ b/tools/ZAPD/ZAPD/ZRoom/ZRoom.cpp @@ -2,7 +2,9 @@ #include #include #include +#include #include + #include "Commands/EndMarker.h" #include "Commands/SetActorCutsceneList.h" #include "Commands/SetActorList.h" @@ -40,6 +42,7 @@ #include "Utils/File.h" #include "Utils/Path.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZBlob.h" #include "ZCutscene.h" #include "ZFile.h" @@ -123,10 +126,12 @@ void ZRoom::ParseXML(tinyxml2::XMLElement* reader) { hackMode = std::string(reader->Attribute("HackMode")); if (hackMode != "syotes_room") - throw std::runtime_error( - StringHelper::Sprintf("ZRoom::ParseXML: Fatal error in '%s'.\n" - "\t Invalid value for attribute 'HackMode': '%s'\n", - name.c_str(), hackMode.c_str())); + { + std::string headerError = StringHelper::Sprintf( + "invalid value found for 'HackMode' attribute: '%s'", hackMode.c_str()); + HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + headerError, ""); + } } } @@ -256,9 +261,10 @@ void ZRoom::ParseRawData() if (Globals::Instance->profile) { auto end = std::chrono::steady_clock::now(); - auto diff = std::chrono::duration_cast(end - start).count(); + int64_t diff = + std::chrono::duration_cast(end - start).count(); if (diff > 50) - printf("OP: %s, TIME: %lims\n", cmd->GetCommandCName().c_str(), diff); + printf("OP: %s, TIME: %" PRIi64 "ms\n", cmd->GetCommandCName().c_str(), diff); } cmd->cmdIndex = currentIndex; @@ -392,14 +398,10 @@ size_t ZRoom::GetCommandSizeFromNeighbor(ZRoomCommand* cmd) return 0; } -std::string ZRoom::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) +void ZRoom::GetSourceOutputCode([[maybe_unused]] const std::string& prefix) { - if (hackMode == "syotes_room") - return ""; - - DeclareVar(prefix, GetBodySourceCode()); - - return ""; + if (hackMode != "syotes_room") + DeclareVar(prefix, GetBodySourceCode()); } size_t ZRoom::GetRawDataSize() const diff --git a/tools/ZAPD/ZAPD/ZRoom/ZRoom.h b/tools/ZAPD/ZAPD/ZRoom/ZRoom.h index 0993a9d30..e837ec70a 100644 --- a/tools/ZAPD/ZAPD/ZRoom/ZRoom.h +++ b/tools/ZAPD/ZAPD/ZRoom/ZRoom.h @@ -34,7 +34,7 @@ public: Declaration* DeclareVar(const std::string& prefix, const std::string& body) override; std::string GetBodySourceCode() const override; - std::string GetSourceOutputCode(const std::string& prefix) override; + void GetSourceOutputCode(const std::string& prefix) override; std::string GetDefaultName(const std::string& prefix) const override; size_t GetDeclarationSizeFromNeighbor(uint32_t declarationAddress); diff --git a/tools/ZAPD/ZAPD/ZScalar.cpp b/tools/ZAPD/ZAPD/ZScalar.cpp index 062fb0e07..7e4be4d57 100644 --- a/tools/ZAPD/ZAPD/ZScalar.cpp +++ b/tools/ZAPD/ZAPD/ZScalar.cpp @@ -4,6 +4,7 @@ #include "Utils/BitConverter.h" #include "Utils/File.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZFile.h" REGISTER_ZFILENODE(Scalar, ZScalar); @@ -207,8 +208,8 @@ void ZScalar::ParseRawData() scalarData.f64 = BitConverter::ToDoubleBE(rawData, rawDataIndex); break; case ZScalarType::ZSCALAR_NONE: - fprintf(stderr, "Warning in ZScalar: Invalid type. %d %s %d\n", (int32_t)scalarType, - __FILE__, __LINE__); + HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + "invalid value found for 'Type' attribute", "Defaulting to ''"); break; } } diff --git a/tools/ZAPD/ZAPD/ZScalar.h b/tools/ZAPD/ZAPD/ZScalar.h index d269995cc..8f98f261d 100644 --- a/tools/ZAPD/ZAPD/ZScalar.h +++ b/tools/ZAPD/ZAPD/ZScalar.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include "ZResource.h" diff --git a/tools/ZAPD/ZAPD/ZSkeleton.cpp b/tools/ZAPD/ZAPD/ZSkeleton.cpp index 84f00c818..4467c9632 100644 --- a/tools/ZAPD/ZAPD/ZSkeleton.cpp +++ b/tools/ZAPD/ZAPD/ZSkeleton.cpp @@ -5,6 +5,7 @@ #include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" REGISTER_ZFILENODE(Skeleton, ZSkeleton); REGISTER_ZFILENODE(LimbTable, ZLimbTable); @@ -27,18 +28,19 @@ void ZSkeleton::ParseXML(tinyxml2::XMLElement* reader) type = ZSkeletonType::Curve; else if (skelTypeXml != "Normal") { - throw std::runtime_error(StringHelper::Sprintf("ZSkeleton::ParseXML: Error in '%s'.\n" - "\t Invalid Type found: '%s'.\n", - name.c_str(), skelTypeXml.c_str())); + HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + "invalid value found for 'Type' attribute", ""); } std::string limbTypeXml = registeredAttributes.at("LimbType").value; limbType = ZLimb::GetTypeByAttributeName(limbTypeXml); if (limbType == ZLimbType::Invalid) { - throw std::runtime_error(StringHelper::Sprintf("ZSkeleton::ParseXML: Error in '%s'.\n" - "\t Invalid LimbType found: '%s'.\n", - name.c_str(), limbTypeXml.c_str())); + HANDLE_ERROR_RESOURCE( + WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + StringHelper::Sprintf("invalid value '%s' found for 'LimbType' attribute", + limbTypeXml.c_str()), + "Defaulting to 'Standard'."); } } @@ -137,7 +139,7 @@ ZResourceType ZSkeleton::GetResourceType() const DeclarationAlignment ZSkeleton::GetDeclarationAlignment() const { - return DeclarationAlignment::Align16; + return DeclarationAlignment::Align4; } uint8_t ZSkeleton::GetLimbCount() @@ -170,11 +172,9 @@ void ZLimbTable::ParseXML(tinyxml2::XMLElement* reader) limbType = ZLimb::GetTypeByAttributeName(limbTypeXml); if (limbType == ZLimbType::Invalid) { - fprintf(stderr, - "ZLimbTable::ParseXML: Warning in '%s'.\n" - "\t Invalid LimbType found: '%s'.\n" - "\t Defaulting to 'Standard'.\n", - name.c_str(), limbTypeXml.c_str()); + HANDLE_WARNING_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + "invalid value found for 'LimbType' attribute.", + "Defaulting to 'Standard'."); limbType = ZLimbType::Standard; } diff --git a/tools/ZAPD/ZAPD/ZSymbol.cpp b/tools/ZAPD/ZAPD/ZSymbol.cpp index b24c3de4b..eabfc2faa 100644 --- a/tools/ZAPD/ZAPD/ZSymbol.cpp +++ b/tools/ZAPD/ZAPD/ZSymbol.cpp @@ -1,6 +1,7 @@ #include "ZSymbol.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZFile.h" REGISTER_ZFILENODE(Symbol, ZSymbol); @@ -20,11 +21,8 @@ void ZSymbol::ParseXML(tinyxml2::XMLElement* reader) if (typeXml == "") { - fprintf(stderr, - "ZSymbol::ParseXML: Warning in '%s'.\n" - "\t Missing 'Type' attribute in xml.\n" - "\t Defaulting to 'void*'.\n", - name.c_str()); + HANDLE_WARNING_RESOURCE(WarningType::MissingAttribute, parent, this, rawDataIndex, + "missing 'Type' attribute in ", "Defaulting to 'void*'."); type = "void*"; } else @@ -35,11 +33,8 @@ void ZSymbol::ParseXML(tinyxml2::XMLElement* reader) std::string typeSizeXml = registeredAttributes.at("TypeSize").value; if (typeSizeXml == "") { - fprintf(stderr, - "ZSymbol::ParseXML: Warning in '%s'.\n" - "\t Missing 'TypeSize' attribute in xml.\n" - "\t Defaulting to '4'.\n", - name.c_str()); + HANDLE_WARNING_RESOURCE(WarningType::MissingAttribute, parent, this, rawDataIndex, + "missing 'TypeSize' attribute in ", "Defaulting to '4'."); typeSize = 4; // Size of a word. } else @@ -58,7 +53,9 @@ void ZSymbol::ParseXML(tinyxml2::XMLElement* reader) if (registeredAttributes.at("Static").value == "On") { - fprintf(stderr, "A can't be marked as static.\n\t Disabling static\n"); + HANDLE_WARNING_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + "a cannot be marked as static", + "Disabling static for this resource."); } staticConf = StaticConfig::Off; } diff --git a/tools/ZAPD/ZAPD/ZTexture.cpp b/tools/ZAPD/ZAPD/ZTexture.cpp index 33ee54d1b..7bd31438b 100644 --- a/tools/ZAPD/ZAPD/ZTexture.cpp +++ b/tools/ZAPD/ZAPD/ZTexture.cpp @@ -8,6 +8,7 @@ #include "Utils/Directory.h" #include "Utils/File.h" #include "Utils/Path.h" +#include "WarningHandler.h" REGISTER_ZFILENODE(Texture, ZTexture); @@ -57,17 +58,17 @@ void ZTexture::ParseXML(tinyxml2::XMLElement* reader) if (!StringHelper::HasOnlyDigits(widthXml)) { - throw std::runtime_error( - StringHelper::Sprintf("ZTexture::ParseXML: Error in %s\n" - "\t Value of 'Width' attribute has non-decimal digits: '%s'.\n", - name.c_str(), widthXml.c_str())); + std::string errorHeader = StringHelper::Sprintf( + "value of 'Width' attribute has non-decimal digits: '%s'", widthXml.c_str()); + HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + errorHeader, ""); } if (!StringHelper::HasOnlyDigits(heightXml)) { - throw std::runtime_error( - StringHelper::Sprintf("ZTexture::ParseXML: Error in %s\n" - "\t Value of 'Height' attribute has non-decimal digits: '%s'.\n", - name.c_str(), heightXml.c_str())); + std::string errorHeader = StringHelper::Sprintf( + "value of 'Height' attribute has non-decimal digits: '%s'", heightXml.c_str()); + HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + errorHeader, ""); } width = StringHelper::StrToL(widthXml); @@ -77,7 +78,10 @@ void ZTexture::ParseXML(tinyxml2::XMLElement* reader) format = GetTextureTypeFromString(formatStr); if (format == TextureType::Error) - throw std::runtime_error("Format " + formatStr + " is not supported!"); + { + HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + "invalid value found for 'Format' attribute", ""); + } const auto& tlutOffsetAttr = registeredAttributes.at("TlutOffset"); if (tlutOffsetAttr.wasSet) @@ -90,10 +94,9 @@ void ZTexture::ParseXML(tinyxml2::XMLElement* reader) break; default: - throw std::runtime_error(StringHelper::Sprintf( - "ZTexture::ParseXML: Error in %s\n" - "\t 'TlutOffset' declared in non color-indexed (ci4 or ci8) texture.\n", - name.c_str())); + HANDLE_ERROR_RESOURCE(WarningType::InvalidXML, parent, this, rawDataIndex, + "'TlutOffset' declared in non color-indexed (ci4 or ci8) texture", + ""); break; } } @@ -102,10 +105,10 @@ void ZTexture::ParseXML(tinyxml2::XMLElement* reader) void ZTexture::ParseRawData() { if (rawDataIndex % 8 != 0) - fprintf(stderr, - "ZTexture::ParseXML: Warning in '%s'.\n" - "\t This texture is not 64-bit aligned.\n", - name.c_str()); + { + HANDLE_WARNING_RESOURCE(WarningType::NotImplemented, parent, this, rawDataIndex, + "this texture is not 64-bit aligned", ""); + } switch (format) { @@ -136,8 +139,11 @@ void ZTexture::ParseRawData() case TextureType::Palette8bpp: PrepareBitmapPalette8(); break; - default: - throw std::runtime_error("Format is not supported!"); + case TextureType::Error: + HANDLE_ERROR_RESOURCE(WarningType::InvalidAttributeValue, parent, this, rawDataIndex, + StringHelper::Sprintf("Invalid texture format", format), ""); + assert(!"TODO"); + break; } } @@ -375,8 +381,9 @@ void ZTexture::PrepareRawDataFromFile(const fs::path& pngFilePath) case TextureType::Palette8bpp: PrepareRawDataPalette8(pngFilePath); break; - default: - throw std::runtime_error("Format is not supported!"); + case TextureType::Error: + HANDLE_ERROR_PROCESS(WarningType::InvalidPNG, "Input PNG file has invalid format type", ""); + break; } } @@ -860,13 +867,9 @@ TextureType ZTexture::GetTextureTypeFromString(const std::string& str) else if (str == "rgb5a1") { texType = TextureType::RGBA16bpp; -#ifdef DEPRECATION_ON - fprintf(stderr, "ZTexture::GetTextureTypeFromString: Deprecation warning.\n" - "\t The texture format 'rgb5a1' is currently deprecated, and will be " - "removed in a future " - "version.\n" - "\t Use the format 'rgba16' instead.\n"); -#endif + HANDLE_WARNING(WarningType::Deprecated, + "the texture format 'rgb5a1' is currently deprecated", + "It will be removed in a future version. Use the format 'rgba16' instead."); } else if (str == "i4") texType = TextureType::Grayscale4bpp; @@ -883,7 +886,9 @@ TextureType ZTexture::GetTextureTypeFromString(const std::string& str) else if (str == "ci8") texType = TextureType::Palette8bpp; else - fprintf(stderr, "Encountered Unknown Texture format %s \n", str.c_str()); + // TODO: handle this case in a more coherent way + HANDLE_WARNING(WarningType::InvalidAttributeValue, + "invalid value found for 'Type' attribute", "Defaulting to ''."); return texType; } diff --git a/tools/ZAPD/ZAPD/ZTextureAnimation.cpp b/tools/ZAPD/ZAPD/ZTextureAnimation.cpp index 4332fcf1e..698054fa8 100644 --- a/tools/ZAPD/ZAPD/ZTextureAnimation.cpp +++ b/tools/ZAPD/ZAPD/ZTextureAnimation.cpp @@ -2,8 +2,8 @@ * File: ZTextureAnimation.cpp * ZResources defined: ZTextureAnimation, ZTextureAnimationParams (XML declaration not supported for * the latter) - * Purpose: extracting texture animating structures from asset files Note: data type is exclusive to - * Majora's Mask + * Purpose: extracting texture animating structures from asset files + * Note: data type is exclusive to Majora's Mask * * Structure of data: * A texture animation consists of a main array of data of the form @@ -82,6 +82,7 @@ #include "Globals.h" #include "Utils/BitConverter.h" +#include "WarningHandler.h" #include "ZFile.h" #include "ZResource.h" #include "tinyxml2.h" @@ -115,7 +116,7 @@ void ZTextureAnimationParams::ExtractFromBinary(uint32_t nRawDataIndex) ParseRawData(); } -// Implemented by TextureScrollingParams only[ +// Implemented by TextureScrollingParams only void ZTextureAnimationParams::ExtractFromBinary([[maybe_unused]] uint32_t nRawDataIndex, [[maybe_unused]] int count) { @@ -217,19 +218,8 @@ void TextureColorChangingParams::ParseRawData() ((type == TextureAnimationParamsType::ColorChange) ? animLength : colorListCount); if (listLength == 0) - throw std::runtime_error(StringHelper::Sprintf( - "When processing file %s: in input binary file %s, offset 0x%06X:" - "\n\t" - "\033[97m" - "TextureColorChangingParams::ParseRawData:" - "\033[0m" - "\033[91m" - " error: " - "\033[0m" - "\033[97m" - "color list length cannot be 0\n" - "\033[0m", - Globals::Instance->inputPath.c_str(), parent->GetName().c_str(), rawDataIndex)); + HANDLE_ERROR_RESOURCE(WarningType::Always, parent, this, rawDataIndex, + "color list length cannot be 0", ""); primColorListAddress = BitConverter::ToUInt32BE(rawData, rawDataIndex + 4); envColorListAddress = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8); @@ -378,20 +368,8 @@ void TextureCyclingParams::ParseRawData() cycleLength = BitConverter::ToUInt16BE(rawData, rawDataIndex); if (cycleLength == 0) - throw std::runtime_error( - StringHelper::Sprintf("When processing file %s: in input binary file %s, offset 0x%06X:" - "\n\t" - "\033[97m" - "TextureCyclingParams::ParseRawData:" - "\033[0m" - "\033[91m" - " error: " - "\033[0m" - "\033[97m" - "cycleLength cannot be 0\n" - "\033[0m", - Globals::Instance->inputPath.c_str(), parent->GetName().c_str(), - Seg2Filespace(rawDataIndex, 0))); + HANDLE_ERROR_RESOURCE(WarningType::Always, parent, this, rawDataIndex, + "cycle length cannot be 0", ""); textureListAddress = BitConverter::ToUInt32BE(rawData, rawDataIndex + 4); textureIndexListAddress = BitConverter::ToUInt32BE(rawData, rawDataIndex + 8); @@ -454,21 +432,12 @@ void TextureCyclingParams::DeclareReferences([[maybe_unused]] const std::string& { comment = " // Raw pointer, declare texture in XML to use proper symbol"; - fprintf(stderr, - "When processing file %s: in input binary file %s, offset 0x%06X:" - "\n\t" - "\033[97m" - "TextureCyclingParams::DeclareReferences:" - "\033[0m" - "\033[95m" - " warning: " - "\033[0m" - "\033[97m" - "TexCycle declared here points to unknown texture at address %s. " - "Please declare the texture in the XML to use the proper symbol.\n" - "\033[0m", - Globals::Instance->inputPath.c_str(), parent->GetName().c_str(), - Seg2Filespace(textureListAddress, parent->baseAddress), texName.c_str()); + auto msgHeader = StringHelper::Sprintf( + "TexCycle texture array declared here points to unknown texture at address %s", + texName.c_str()); + HANDLE_WARNING_RESOURCE( + WarningType::HardcodedPointer, parent, this, rawDataIndex, msgHeader, + "Please declare the texture in the XML to use the proper symbol."); } texturesBodyStr += StringHelper::Sprintf("\t%s,%s\n", texName.c_str(), comment.c_str()); } @@ -546,22 +515,14 @@ void ZTextureAnimation::ParseRawData() if ((type < 0) || (type > 6)) { - throw std::runtime_error(StringHelper::Sprintf( - "When processing file %s: in input binary file %s, offset 0x%06X:" - "\n\t" - "\033[97m" - "ZTextureAnimation::ParseRawData:" - "\033[0m" - "\033[91m" - " error: " - "\033[0m" - "\033[97m" - "unknown TextureAnimationParams type 0x%02X in TextureAnimation: entry reads\n\t{ " - "0x%02X, 0x%02X, 0x%08X }\n(type should be between " - "0x00 and 0x06)\n" - "\033[0m", - Globals::Instance->inputPath.c_str(), parent->GetName().c_str(), rawDataIndex, type, - currentEntry.segment, type, currentEntry.paramsPtr)); + HANDLE_ERROR_RESOURCE( + WarningType::Always, parent, this, rawDataIndex, + StringHelper::Sprintf( + "unknown TextureAnimationParams type 0x%02X in TextureAnimation", type), + StringHelper::Sprintf( + "Entry reads { 0x%02X, 0x%02X, 0x%08X } , but type should be " + "between 0x00 and 0x06 inclusive.", + currentEntry.segment, type, currentEntry.paramsPtr)); } if (currentEntry.segment <= 0) @@ -589,13 +550,24 @@ void ZTextureAnimation::DeclareReferences(const std::string& prefix) if (!parent->HasDeclaration(paramsOffset)) { ZTextureAnimationParams* params; - int count = 2; + int count; switch (entry.type) { case TextureAnimationParamsType::SingleScroll: - count = 1; - [[fallthrough]]; - case TextureAnimationParamsType::DualScroll: + if (true) + { + count = 1; + // The else now allows SingleScroll to fall through to params = ... without + // touching the code in the else block + } + else + { + // The contents of this block can only be run by jumping into it with the + // case label + [[fallthrough]]; + case TextureAnimationParamsType::DualScroll: + count = 2; + } params = new TextureScrollingParams(parent); params->ExtractFromBinary(paramsOffset, count); break; @@ -614,22 +586,12 @@ void ZTextureAnimation::DeclareReferences(const std::string& prefix) break; case TextureAnimationParamsType::Empty: - fprintf(stderr, - "When processing file %s: in input binary file %s: offset 0x%06X:" - "\n\t" - "\033[97m" - "ZTextureAnimation::DeclareReferences:" - "\033[0m" - "\033[95m" - " warning: " - "\033[0m" - "\033[97m" - "TextureAnimationParams entry has empty type (6), but params pointer " - "is not NULL. Params read\n\t\t" - "{ 0x%02X, 0x%02X, 0x%08X }\n" - "\033[0m", - Globals::Instance->inputPath.c_str(), parent->GetName().c_str(), - rawDataIndex, entry.segment, (int)entry.type, entry.paramsPtr); + HANDLE_WARNING_RESOURCE( + WarningType::InvalidExtractedData, parent, this, rawDataIndex, + "TextureAnimationParams entry has empty type (6), but params pointer is " + "not NULL", + StringHelper::Sprintf("Params read { 0x%02X, 0x%02X, 0x%08X } .", + entry.segment, (int)entry.type, entry.paramsPtr)); return; default: // Because GCC is worried this could happen diff --git a/tools/ZAPD/ZAPD/ZVector.cpp b/tools/ZAPD/ZAPD/ZVector.cpp index c940b0b0d..a5a059e35 100644 --- a/tools/ZAPD/ZAPD/ZVector.cpp +++ b/tools/ZAPD/ZAPD/ZVector.cpp @@ -6,6 +6,7 @@ #include "Utils/BitConverter.h" #include "Utils/File.h" #include "Utils/StringHelper.h" +#include "WarningHandler.h" #include "ZFile.h" REGISTER_ZFILENODE(Vector, ZVector); @@ -86,20 +87,18 @@ std::string ZVector::GetSourceTypeName() const return "Vec3i"; else { - std::string output = StringHelper::Sprintf( - "Encountered unsupported vector type: %d dimensions, %s type", dimensions, + std::string msgHeader = StringHelper::Sprintf( + "encountered unsupported vector type: %d dimensions, %s type", dimensions, ZScalar::MapScalarTypeToOutputType(scalarType).c_str()); - if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_DEBUG) - printf("%s\n", output.c_str()); - - throw std::runtime_error(output); + HANDLE_ERROR_RESOURCE(WarningType::NotImplemented, parent, this, rawDataIndex, msgHeader, + ""); } } std::string ZVector::GetBodySourceCode() const { - std::string body; + std::string body = ""; for (size_t i = 0; i < scalars.size(); i++) { diff --git a/tools/ZAPD/ZAPD/ZVector.h b/tools/ZAPD/ZAPD/ZVector.h index d1a738968..a50d3e808 100644 --- a/tools/ZAPD/ZAPD/ZVector.h +++ b/tools/ZAPD/ZAPD/ZVector.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include "ZResource.h" diff --git a/tools/ZAPD/ZAPD/ZVtx.cpp b/tools/ZAPD/ZAPD/ZVtx.cpp index d5214e840..e4b3d9796 100644 --- a/tools/ZAPD/ZAPD/ZVtx.cpp +++ b/tools/ZAPD/ZAPD/ZVtx.cpp @@ -82,5 +82,5 @@ std::string ZVtx::GetExternalExtension() const DeclarationAlignment ZVtx::GetDeclarationAlignment() const { - return DeclarationAlignment::Align16; + return DeclarationAlignment::Align8; } diff --git a/tools/ZAPD/ZAPD/ZVtx.h b/tools/ZAPD/ZAPD/ZVtx.h index 018a1d4a9..511048791 100644 --- a/tools/ZAPD/ZAPD/ZVtx.h +++ b/tools/ZAPD/ZAPD/ZVtx.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include #include "ZResource.h" diff --git a/tools/ZAPD/ZAPD/any/any/zlib.static.txt b/tools/ZAPD/ZAPD/any/any/zlib.static.txt new file mode 100644 index 000000000..e69de29bb diff --git a/tools/ZAPD/ZAPD/packages.config b/tools/ZAPD/ZAPD/packages.config index a7f2abbd2..c387aaed7 100644 --- a/tools/ZAPD/ZAPD/packages.config +++ b/tools/ZAPD/ZAPD/packages.config @@ -1,8 +1,9 @@  - - + + + \ No newline at end of file diff --git a/tools/ZAPD/ZAPDUtils/Color3b.h b/tools/ZAPD/ZAPDUtils/Color3b.h index 7e59f6b7f..507c099f5 100644 --- a/tools/ZAPD/ZAPDUtils/Color3b.h +++ b/tools/ZAPD/ZAPDUtils/Color3b.h @@ -1,6 +1,6 @@ #pragma once -#include +#include struct Color3b { diff --git a/tools/ZAPD/ZAPDUtils/Makefile b/tools/ZAPD/ZAPDUtils/Makefile index aef678031..e8941ed77 100644 --- a/tools/ZAPD/ZAPDUtils/Makefile +++ b/tools/ZAPD/ZAPDUtils/Makefile @@ -1,7 +1,7 @@ # Only used for standalone compilation, usually inherits these from the main makefile CXXFLAGS ?= -Wall -Wextra -O2 -g -std=c++17 -SRC_DIRS := $(shell find -type d -not -path "*build*") +SRC_DIRS := $(shell find . -type d -not -path "*build*") CPP_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.cpp)) H_FILES := $(foreach dir,$(SRC_DIRS),$(wildcard $(dir)/*.h)) diff --git a/tools/ZAPD/ZAPDUtils/StrHash.h b/tools/ZAPD/ZAPDUtils/StrHash.h index 68d22b9cd..c611bddda 100644 --- a/tools/ZAPD/ZAPDUtils/StrHash.h +++ b/tools/ZAPD/ZAPDUtils/StrHash.h @@ -1,8 +1,8 @@ #pragma once -#include -#include -#include +#include +#include +#include typedef uint32_t strhash; diff --git a/tools/ZAPD/ZAPDUtils/Utils/BinaryReader.cpp b/tools/ZAPD/ZAPDUtils/Utils/BinaryReader.cpp index a4cf78229..35412781c 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/BinaryReader.cpp +++ b/tools/ZAPD/ZAPDUtils/Utils/BinaryReader.cpp @@ -1,5 +1,5 @@ #include "BinaryReader.h" -#include +#include #include #include "Stream.h" @@ -89,7 +89,7 @@ float BinaryReader::ReadSingle() stream->Read((char*)&result, sizeof(float)); - if (isnan(result)) + if (std::isnan(result)) throw std::runtime_error("BinaryReader::ReadSingle(): Error reading stream"); return result; @@ -100,7 +100,7 @@ double BinaryReader::ReadDouble() double result = NAN; stream->Read((char*)&result, sizeof(double)); - if (isnan(result)) + if (std::isnan(result)) throw std::runtime_error("BinaryReader::ReadDouble(): Error reading stream"); return result; diff --git a/tools/ZAPD/ZAPDUtils/Utils/BitConverter.h b/tools/ZAPD/ZAPDUtils/Utils/BitConverter.h index 5cca35b31..e672b97c2 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/BitConverter.h +++ b/tools/ZAPD/ZAPDUtils/Utils/BitConverter.h @@ -1,7 +1,7 @@ #pragma once +#include #include -#include #include class BitConverter diff --git a/tools/ZAPD/ZAPDUtils/Utils/File.h b/tools/ZAPD/ZAPDUtils/Utils/File.h index e3f8880cb..084152f79 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/File.h +++ b/tools/ZAPD/ZAPDUtils/Utils/File.h @@ -1,8 +1,8 @@ #pragma once +#include #include #include -#include #include #include #include "Directory.h" diff --git a/tools/ZAPD/ZAPDUtils/Utils/MemoryStream.cpp b/tools/ZAPD/ZAPDUtils/Utils/MemoryStream.cpp index 6c27399d6..6e85c59a0 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/MemoryStream.cpp +++ b/tools/ZAPD/ZAPDUtils/Utils/MemoryStream.cpp @@ -1,5 +1,5 @@ #include "MemoryStream.h" -#include +#include #ifndef _MSC_VER #define memcpy_s(dest, destSize, source, sourceSize) memcpy(dest, source, destSize) diff --git a/tools/ZAPD/ZAPDUtils/Utils/Path.h b/tools/ZAPD/ZAPDUtils/Utils/Path.h index 496a0ae13..0f7ef2743 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/Path.h +++ b/tools/ZAPD/ZAPDUtils/Utils/Path.h @@ -18,13 +18,13 @@ public: static std::string GetFileName(const fs::path& input) { // https://en.cppreference.com/w/cpp/filesystem/path/filename - return input.filename(); + return input.filename().string(); }; static std::string GetFileNameWithoutExtension(const fs::path& input) { // https://en.cppreference.com/w/cpp/filesystem/path/stem - return input.stem(); + return input.stem().string(); }; static std::string GetFileNameExtension(const std::string& input) diff --git a/tools/ZAPD/ZAPDUtils/Utils/Stream.h b/tools/ZAPD/ZAPDUtils/Utils/Stream.h index 060e23cd2..e73a9a70d 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/Stream.h +++ b/tools/ZAPD/ZAPDUtils/Utils/Stream.h @@ -1,7 +1,7 @@ #pragma once +#include #include -#include enum class SeekOffsetType { diff --git a/tools/ZAPD/ZAPDUtils/Utils/StringHelper.h b/tools/ZAPD/ZAPDUtils/Utils/StringHelper.h index 74607ce3a..6c9e54119 100644 --- a/tools/ZAPD/ZAPDUtils/Utils/StringHelper.h +++ b/tools/ZAPD/ZAPDUtils/Utils/StringHelper.h @@ -1,18 +1,12 @@ #pragma once #include +#include #include #include -#include #include #include -#ifdef _MSC_VER -#define __PRETTY_FUNCTION__ __FUNCSIG__ -#elif not defined(__GNUC__) -#define __PRETTY_FUNCTION__ __func__ -#endif - class StringHelper { public: @@ -111,4 +105,10 @@ public: { return std::all_of(str.begin(), str.end(), ::isdigit); } + + static bool IEquals(const std::string& a, const std::string& b) + { + return std::equal(a.begin(), a.end(), b.begin(), b.end(), + [](char a, char b) { return tolower(a) == tolower(b); }); + } }; diff --git a/tools/ZAPD/ZAPDUtils/Utils/vt.h b/tools/ZAPD/ZAPDUtils/Utils/vt.h new file mode 100644 index 000000000..23f424442 --- /dev/null +++ b/tools/ZAPD/ZAPDUtils/Utils/vt.h @@ -0,0 +1,45 @@ +#ifndef VT_H +#define VT_H + +// clang-format off +#define VT_COLOR_BLACK 0 +#define VT_COLOR_RED 1 +#define VT_COLOR_GREEN 2 +#define VT_COLOR_YELLOW 3 +#define VT_COLOR_BLUE 4 +#define VT_COLOR_PURPLE 5 +#define VT_COLOR_CYAN 6 +#define VT_COLOR_WHITE 7 +#define VT_COLOR_LIGHTGRAY 8 +#define VT_COLOR_DARKGRAY 9 + +#define VT_COLOR_FOREGROUND 3 +#define VT_COLOR_BACKGROUND 4 +// clang-format on + +#define VT_COLOR_EXPAND0(type, color) #type #color +#define VT_COLOR_EXPAND1(type, color) VT_COLOR_EXPAND0(type, color) +#define VT_COLOR(type, color) VT_COLOR_EXPAND1(VT_COLOR_##type, VT_COLOR_##color) + +#define VT_ESC "\x1b" +#define VT_CSI "[" +#define VT_CUP(x, y) VT_ESC VT_CSI y ";" x "H" +#define VT_ED(n) VT_ESC VT_CSI #n "J" +#define VT_SGR(n) VT_ESC VT_CSI n "m" + +// Add more macros if necessary +#define VT_COL(back, fore) VT_SGR(VT_COLOR(BACKGROUND, back) ";" VT_COLOR(FOREGROUND, fore)) +#define VT_FGCOL(color) VT_SGR(VT_COLOR(FOREGROUND, color)) +#define VT_BGCOL(color) VT_SGR(VT_COLOR(BACKGROUND, color)) + +// Bold +#define VT_BOLD "1" + +// Bold color support +#define VT_BOLD_FGCOL(color) VT_SGR(VT_BOLD ";" VT_COLOR(FOREGROUND, color)) +#define VT_BOLD_BGCOL(color) VT_SGR(VT_BOLD ";" VT_COLOR(BACKGROUND, color)) + +#define VT_RST VT_SGR("") +#define VT_CLS VT_ED(2) + +#endif diff --git a/tools/ZAPD/ZAPDUtils/Vec2f.h b/tools/ZAPD/ZAPDUtils/Vec2f.h index 9d4beeb46..73e9259a8 100644 --- a/tools/ZAPD/ZAPDUtils/Vec2f.h +++ b/tools/ZAPD/ZAPDUtils/Vec2f.h @@ -1,6 +1,6 @@ #pragma once -#include +#include struct Vec2f { diff --git a/tools/ZAPD/ZAPDUtils/Vec3f.h b/tools/ZAPD/ZAPDUtils/Vec3f.h index 4bfbb3c25..d6e9c5568 100644 --- a/tools/ZAPD/ZAPDUtils/Vec3f.h +++ b/tools/ZAPD/ZAPDUtils/Vec3f.h @@ -1,6 +1,6 @@ #pragma once -#include +#include struct Vec3f { diff --git a/tools/ZAPD/ZAPDUtils/Vec3s.h b/tools/ZAPD/ZAPDUtils/Vec3s.h index 23e4673b8..05816eddb 100644 --- a/tools/ZAPD/ZAPDUtils/Vec3s.h +++ b/tools/ZAPD/ZAPDUtils/Vec3s.h @@ -1,6 +1,6 @@ #pragma once -#include +#include struct Vec3s { diff --git a/tools/ZAPD/ZAPDUtils/ZAPDUtils.vcxproj b/tools/ZAPD/ZAPDUtils/ZAPDUtils.vcxproj index 803cdb5f0..0a09666e0 100644 --- a/tools/ZAPD/ZAPDUtils/ZAPDUtils.vcxproj +++ b/tools/ZAPD/ZAPDUtils/ZAPDUtils.vcxproj @@ -43,7 +43,7 @@ StaticLibrary true v142 - Unicode + MultiByte Application @@ -116,6 +116,8 @@ true _DEBUG;_CONSOLE;%(PreprocessorDefinitions) true + MultiThreadedDebug + Default Console @@ -155,6 +157,7 @@ + diff --git a/tools/ZAPD/ZAPDUtils/ZAPDUtils.vcxproj.filters b/tools/ZAPD/ZAPDUtils/ZAPDUtils.vcxproj.filters index 48117c845..4765ad5d4 100644 --- a/tools/ZAPD/ZAPDUtils/ZAPDUtils.vcxproj.filters +++ b/tools/ZAPD/ZAPDUtils/ZAPDUtils.vcxproj.filters @@ -19,6 +19,9 @@ {e047919d-7186-49ca-b115-e48fbb5c8743} + + {3de9dd46-0dfd-4d48-9f20-9f24e5b80fe0} + @@ -74,5 +77,8 @@ Source Files\Utils + + Source Files\Libraries + \ No newline at end of file diff --git a/tools/ZAPD/docs/zapd_warning_example.png b/tools/ZAPD/docs/zapd_warning_example.png new file mode 100644 index 000000000..a001c64d6 Binary files /dev/null and b/tools/ZAPD/docs/zapd_warning_example.png differ diff --git a/tools/ZAPDConfigs/MM/Config.xml b/tools/ZAPDConfigs/MM/Config.xml index 657040010..02656c7df 100644 --- a/tools/ZAPDConfigs/MM/Config.xml +++ b/tools/ZAPDConfigs/MM/Config.xml @@ -4,10 +4,5 @@ - - diff --git a/tools/actorfixer.py b/tools/actorfixer.py index e89303ba5..979106fb3 100755 --- a/tools/actorfixer.py +++ b/tools/actorfixer.py @@ -154,23 +154,160 @@ animdict = { "MainHeap_Init": "ZeldaArena_Init", "MainHeap_Cleanup": "ZeldaArena_Cleanup", "MainHeap_IsInitialized": "ZeldaArena_IsInitialized", - - "skelanime.unk03": "skelanime.taper", - "skelanime.animCurrentSeg": "skelanime.animation", - "skelanime.initialFrame": "skelanime.startFrame", - "skelanime.animFrameCount": "skelanime.endFrame", - "skelanime.totalFrames": "skelanime.animLength", - "skelanime.animCurrentFrame": "skelanime.curFrame", - "skelanime.animPlaybackSpeed": "skelanime.playSpeed", - "skelanime.limbDrawTbl": "skelanime.jointTable", - "skelanime.transitionDrawTbl": "skelanime.morphTable", - "skelanime.transCurrentFrame": "skelanime.morphWeight", - "skelanime.transitionStep": "skelanime.morphRate", - "skelanime.animUpdate": "skelanime.update", - "skelanime.flags": "skelanime.moveFlags", - "skelanime.prevFrameRot": "skelanime.prevRot", - "skelanime.prevFramePos": "skelanime.prevTransl", - "skelanime.unk3E": "skelanime.baseTransl", + # "BgCheck_RelocateMeshHeader": "CollisionHeader_GetVirtual", + # "BgCheck_AddActorMesh": "DynaPoly_SetBgActor", + # "BgCheck_RemoveActorMesh": "DynaPoly_DeleteBgActor", + "BgCheck_PolygonLinkedListNodeInit": "SSNode_SetValue", + "BgCheck_PolygonLinkedListResetHead": "SSList_SetNull", + "BgCheck_ScenePolygonListsNodeInsert": "SSNodeList_SetSSListHead", + "BgCheck_PolygonLinkedListNodeInsert": "DynaSSNodeList_SetSSListHead", + "BgCheck_PolygonLinkedListInit": "DynaSSNodeList_Init", + "BgCheck_PolygonLinkedListAlloc": "DynaSSNodeList_Alloc", + "BgCheck_PolygonLinkedListReset": "DynaSSNodeList_ResetCount", + "BgCheck_AllocPolygonLinkedListNode": "DynaSSNodeList_GetNextNodeIdx", + "BgCheck_CreateVec3fFromVertex": "BgCheck_Vec3sToVec3f", + "BgCheck_CreateVertexFromVec3f": "BgCheck_Vec3fToVec3s", + "BgCheck_PolygonGetMinY": "CollisionPoly_GetMinY", + "BgCheck_PolygonGetNormal": "CollisionPoly_GetNormalF", + "func_800C01B8": "CollisionPoly_GetPointDistanceFromPlane", + "BgCheck_CreateTriNormFromPolygon": "CollisionPoly_GetVertices", + "func_800C02C0": "CollisionPoly_GetVerticesByBgId", + "BgCheck_PolygonCollidesWithSphere": "CollisionPoly_SphVsPoly", + "BgCheck_ScenePolygonListsInsertSorted": "StaticLookup_AddPolyToSSList", + "BgCheck_ScenePolygonListsInsert": "StaticLookup_AddPoly", + "BgCheck_GetPolyMinSubdivisions": "BgCheck_GetSubdivisionMinBounds", + "BgCheck_GetPolyMaxSubdivisions": "BgCheck_GetSubdivisionMaxBounds", + "BgCheck_GetPolyMinMaxSubdivisions": "BgCheck_GetPolySubdivisionBounds", + "func_800C2BE0": "BgCheck_PolyIntersectsSubdivision", + "BgCheck_SplitScenePolygonsIntoSubdivisions": "BgCheck_InitStaticLookup", + "BgCheck_GetIsDefaultSpecialScene": "BgCheck_IsSmallMemScene", + "BgCheck_GetSpecialSceneMaxMemory": "BgCheck_TryGetCustomMemsize", + "BgCheck_CalcSubdivisionSize": "BgCheck_SetSubdivisionDimension", + "BgCheck_Init(": "BgCheck_Allocate(", + "func_800C3C00": "BgCheck_SetContextFlags", + "func_800C3C14": "BgCheck_UnsetContextFlags", + "BgCheck_GetActorMeshHeader": "BgCheck_GetCollisionHeader", + "func_800C3D50": "BgCheck_RaycastFloorImpl", + "func_800C3F40": "BgCheck_CameraRaycastFloor1", + "func_800C3FA0": "BgCheck_EntityRaycastFloor1", + "func_800C4000": "BgCheck_EntityRaycastFloor2", + "func_800C4058": "BgCheck_EntityRaycastFloor2_1", + "func_800C40B4": "BgCheck_EntityRaycastFloor3", + "func_800C411C": "BgCheck_EntityRaycastFloor5", + "func_800C4188": "BgCheck_EntityRaycastFloor5_2", + "func_800C41E4": "BgCheck_EntityRaycastFloor5_3", + "func_800C4240": "BgCheck_EntityRaycastFloor6", + "func_800C42A8": "BgCheck_EntityRaycastFloor7", + "func_800C4314": "BgCheck_AnyRaycastFloor1", + "func_800C43CC": "BgCheck_AnyRaycastFloor2", + "func_800C4488": "BgCheck_CameraRaycastFloor2", + "func_800C44F0": "BgCheck_EntityRaycastFloor8", + "func_800C455C": "BgCheck_EntityRaycastFloor9", + "func_800C45C4": "BgCheck_CheckWallImpl", + "func_800C4C74": "BgCheck_EntitySphVsWall1", + "func_800C4CD8": "BgCheck_EntitySphVsWall2", + "func_800C4D3C": "BgCheck_EntitySphVsWall3", + "func_800C4DA4": "BgCheck_EntitySphVsWall4", + "func_800C4E10": "BgCheck_CheckCeilingImpl", + "func_800C4F38": "BgCheck_AnyCheckCeiling", + "func_800C4F84": "BgCheck_EntityCheckCeiling", + "func_800C54AC": "BgCheck_CameraLineTest1", + "func_800C5538": "BgCheck_CameraLineTest2", + "func_800C55C4": "BgCheck_EntityLineTest1", + "func_800C5650": "BgCheck_EntityLineTest2", + "func_800C56E0": "BgCheck_EntityLineTest3", + "func_800C576C": "BgCheck_ProjectileLineTest", + "func_800C57F8": "BgCheck_AnyLineTest1", + "func_800C583C": "BgCheck_AnyLineTest2", + "func_800C58C8": "BgCheck_AnyLineTest3", + "func_800C5954": "BgCheck_SphVsFirstPolyImpl", + "func_800C5A20": "BgCheck_SphVsFirstPoly", + "func_800C5A64": "BgCheck_SphVsFirstWall", + "BgCheck_ScenePolygonListsInit": "SSNodeList_Init", + "BgCheck_ScenePolygonListsAlloc": "SSNodeList_Alloc", + "func_800C5B80": "SSNodeList_GetNextNode", + "BgCheck_ScenePolygonListsReserveNode": "SSNodeList_GetNextNodeIdx", + "BgCheck_ActorMeshParamsInit": "ScaleRotPos_Init", + "BgCheck_SetActorMeshParams": "ScaleRotPos_SetValue", + "BgCheck_ActorMeshPolyListsHeadsInit": "DynaLookup_ResetLists", + "BgCheck_ActorMeshPolyListsInit": "DynaLookup_Reset", + "BgCheck_ActorMeshVerticesIndexInit": "DynaLookup_ResetVtxStartIndex", + "BgCheck_ActorMeshWaterboxesIndexInit": "DynaLookup_ResetWaterBoxStartIndex", + "BgCheck_ActorMeshInit": "BgActor_Init", + "BgCheck_ActorMeshInitFromActor": "BgActor_SetActor", + "BgCheck_HasActorMeshChanged": "BgActor_IsTransformUnchanged", + "BgCheck_PolygonsInit": "DynaPoly_NullPolyList", + "BgCheck_PolygonsAlloc": "DynaPoly_AllocPolyList", + "BgCheck_VerticesInit": "DynaPoly_NullVtxList", + "BgCheck_VerticesListAlloc": "DynaPoly_AllocVtxList", + "BgCheck_WaterboxListInit": "DynaPoly_InitWaterBoxList", + "BgCheck_WaterboxListAlloc": "DynaPoly_AllocWaterBoxList", + "BgCheck_ActorMeshUpdateParams": "DynaPoly_SetBgActorPrevTransform", + "BgCheck_IsActorMeshIndexValid": "DynaPoly_IsBgIdBgActor", + "BgCheck_DynaInit": "DynaPoly_Init", + "BgCheck_DynaAlloc": "DynaPoly_Alloc", + "BgCheck_AddActorMesh": "DynaPoly_SetBgActor", + "BgCheck_GetActorOfMesh": "DynaPoly_GetActor", + "BgCheck_RemoveActorMesh": "DynaPoly_DeleteBgActor", + "BgCheck_AddActorMeshToLists": "DynaPoly_ExpandSRT", + "BgCheck_Update": "DynaPoly_Setup", + "BgCheck_UpdateAllActorMeshes": "DynaPoly_UpdateBgActorTransforms", + "BgCheck_RelocateMeshHeaderPointers": "CollisionHeader_SegmentedToVirtual", + "BgCheck_RelocateMeshHeader": "CollisionHeader_GetVirtual", + "BgCheck_RelocateAllMeshHeaders": "BgCheck_InitCollisionHeaders", + "BgCheck_GetPolygonAttributes": "SurfaceType_GetData", + "func_800C9704": "SurfaceType_GetCamDataIndex", + "func_800C9924": "SurfaceType_GetCamPosData", + "func_800C99AC": "SurfaceType_GetSceneExitIndex", + "func_800C9B90": "SurfaceType_IsHorseBlocked", + "func_800C9BDC": "SurfaceType_GetSfx", + "func_800C9C74": "SurfaceType_GetSlope", + "func_800C9C9C": "SurfaceType_GetLightSettingIndex", + "func_800C9CC4": "SurfaceType_GetEcho", + "func_800C9CEC": "SurfaceType_IsHookshotSurface", + "func_800C9D14": "SurfaceType_IsIgnoredByEntities", + "func_800C9D50": "SurfaceType_IsIgnoredByProjectiles", + "func_800C9D8C": "SurfaceType_IsConveyor", + "func_800C9E18": "SurfaceType_GetConveyorSpeed", + "func_800C9E40": "SurfaceType_GetConveyorDirection", + "func_800C9E88": "SurfaceType_IsWallDamage", + "func_800C9EBC": "WaterBox_GetSurfaceImpl", + "func_800CA1AC": "WaterBox_GetSurface1", + "func_800CA1E8": "WaterBox_GetSurface1_2", + "func_800CA22C": "WaterBox_GetSurface2", + "func_800CA6D8": "WaterBox_GetLightSettingIndex", + "func_80179678": "Math3D_PlaneVsLineSegClosestPoint", + "Math3D_DistanceSquared": "Math3D_Vec3fDistSq", + "Math3D_NormalVector": "Math3D_SurfaceNorm", + "func_8017A954": "Math3D_PointRelativeToCubeFaces", + "func_8017AA0C": "Math3D_PointRelativeToCubeEdges", + "func_8017ABBC": "Math3D_PointRelativeToCubeVertices", + "func_8017AD38": "Math3D_LineVsCube", + "Math3D_NormalizedDistanceFromPlane": "Math3D_UDistPlaneToPos", + "Math3D_NormalizedSignedDistanceFromPlane": "Math3D_DistPlaneToPos", + "func_8017BAD0": "Math3D_TriChkPointParaYDist", + "func_8017BE30": "Math3D_TriChkPointParaYIntersectDist", + "func_8017BEE0": "Math3D_TriChkPointParaYIntersectInsideTri", + "func_8017C008": "Math3D_TriChkLineSegParaYIntersect", + "func_8017C494": "Math3D_TriChkPointParaYIntersectInsideTri2", + "func_8017C540": "Math3D_TriChkPointParaXDist", + "func_8017C850": "Math3D_TriChkPointParaXIntersect", + "func_8017C980": "Math3D_TriChkLineSegParaXIntersect", + "func_8017CB7C": "Math3D_TriChkLineSegParaZDist", + "func_8017CEF0": "Math3D_TriChkPointParaZIntersect", + "func_8017D020": "Math3D_TriChkLineSegParaZIntersect", + "Math3D_ColSphereLineSeg": "Math3D_LineVsSph", + "Math3D_ColSphereSphere(": "Math3D_SphVsSph(", + "func_8017F9C0": "Math3D_XZInSphere", + "func_8017FA34": "Math3D_XYInSphere", + "func_8017FAA8": "Math3D_YZInSphere", + "func_8013A7C0": "SubS_FindDoor", + "func_8013E640": "SubS_FindActorCustom", + "func_ActorCategoryIterateById": "SubS_FindActor", + "func_8013BB7C": "SubS_FindNearestActor", + "func_800A81F0": "EffectBlure_AddVertex", + "func_800A8514": "EffectBlure_AddSpace", + "Effect_GetParams": "Effect_GetByIndex", "skelAnime.unk03": "skelAnime.taper", "skelAnime.animCurrentSeg": "skelAnime.animation", @@ -188,8 +325,16 @@ animdict = { "skelAnime.prevFrameRot": "skelAnime.prevRot", "skelAnime.prevFramePos": "skelAnime.prevTransl", "skelAnime.unk3E": "skelAnime.baseTransl", - "actor.yDistToWater" : "actor.depthInWater", - "actor.yDistToPlayer" : "actor.playerHeightRel", + "actor.yDistToWater": "actor.depthInWater", + "actor.yDistToPlayer": "actor.playerHeightRel", + "globalCtx->mf_187FC": "globalCtx->billboardMtxF", + "globalCtx->projectionMatrix": "globalCtx->viewProjectionMtxF", + + "D_0407D590": "gGameplayKeepDrawFlameDL", + "D_801D15B0": "gZeroVec3f", + "D_801D15BC": "gZeroVec3s", + "D_801D1DE0": "gIdentityMtx", + "D_801D1E20": "gIdentityMtxF", } def replace_anim(file): @@ -220,11 +365,25 @@ def replace_anim_all(repo): if(filename.endswith('.c')): file = subdir + os.sep + filename replace_anim(file) + for subdir, dirs, files in os.walk(repo + os.sep + 'asm'): + for filename in files: + if(filename.endswith('.s')): + file = subdir + os.sep + filename + replace_anim(file) + + for subdir, dirs, files in os.walk(repo + os.sep + 'data'): for filename in files: if(filename.endswith('.s')): file = subdir + os.sep + filename replace_anim(file) + + for subdir, dirs, files in os.walk(repo + os.sep + 'docs'): + for filename in files: + if(filename.endswith('.md')): + file = subdir + os.sep + filename + replace_anim(file) + for subdir, dirs, files in os.walk(repo + os.sep + 'tools' + os.sep + 'sizes'): for filename in files: if(filename.endswith('.csv')): diff --git a/tools/asm-differ/.gitrepo b/tools/asm-differ/.gitrepo index d3e4418c9..241c0ad6b 100644 --- a/tools/asm-differ/.gitrepo +++ b/tools/asm-differ/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/simonlindholm/asm-differ.git branch = main - commit = f30d43aceba6291aa3c08b7317b0458b6d734321 - parent = e977dfeb374c6de4076ca9a0f44ba5a6a701d849 + commit = 70c33cc125666495f84f8c7bee60d3158b4b1164 + parent = 62341d8db0c29d1d4f0c360196e428309ac373b6 method = merge cmdver = 0.4.3 diff --git a/tools/asm-differ/diff.py b/tools/asm-differ/diff.py index d7ac3f344..2ec117a12 100755 --- a/tools/asm-differ/diff.py +++ b/tools/asm-differ/diff.py @@ -640,6 +640,7 @@ class Text: class TableMetadata: headers: Tuple[Text, ...] current_score: int + max_score: int previous_score: Optional[int] @@ -832,6 +833,7 @@ class JsonFormatter(Formatter): for h, name in zip(meta.headers, ("base", "current", "previous")) } output["current_score"] = meta.current_score + output["max_score"] = meta.max_score if meta.previous_score is not None: output["previous_score"] = meta.previous_score output_rows: List[Dict[str, Any]] = [] @@ -1184,8 +1186,9 @@ def parse_elf_data_references(data: bytes) -> List[Tuple[int, int, str]]: assert len(symtab_sections) == 1 symtab = sections[symtab_sections[0]] - text_sections = [i for i in range(e_shnum) if sec_names[i] == b".text"] - assert len(text_sections) == 1 + text_sections = [i for i in range(e_shnum) if sec_names[i] == b".text" and sections[i].sh_size != 0] + if len(text_sections) != 1: + return [] text_section = text_sections[0] ret: List[Tuple[int, int, str]] = [] @@ -1327,11 +1330,23 @@ def dump_binary( (objdump_flags + flags2, project.myimg, None), ) +DATA_POOL_PLACEHOLDER = "DATA_POOL_PLACEHOLDER-OFFSET_{}" +DATA_POOL_PLACEHOLDER_PATTERN = re.compile( + r"DATA_POOL_PLACEHOLDER-OFFSET_([a-zA-z0-9]+)" +) -class DifferenceNormalizer: +# Example: "ldr r4, [pc, #56] ; (4c )" +ARM32_LOAD_POOL_PATTERN = r"(ldr\s+r([0-9]|1[0-3]),\s+\[pc,.*;\s*)(\([a-fA-F0-9]+.*\))" + + +# The base class is a no-op. +class AsmProcessor: def __init__(self, config: Config) -> None: self.config = config + def process_reloc(self, row: str, prev: str) -> str: + return prev + def normalize(self, mnemonic: str, row: str) -> str: """This should be called exactly once for each line.""" arch = self.config.arch @@ -1342,9 +1357,143 @@ class DifferenceNormalizer: def _normalize_arch_specific(self, mnemonic: str, row: str) -> str: return row + + def post_process(self, lines: List["Line"]) -> None: + return -class DifferenceNormalizerAArch64(DifferenceNormalizer): +class AsmProcessorMIPS(AsmProcessor): + def process_reloc(self, row: str, prev: str) -> str: + arch = self.config.arch + if "R_MIPS_NONE" in row: + # GNU as emits no-op relocations immediately after real ones when + # assembling with -mabi=64. Return without trying to parse 'imm' as an + # integer. + return prev + before, imm, after = parse_relocated_line(prev) + repl = row.split()[-1] + if imm != "0": + # MIPS uses relocations with addends embedded in the code as immediates. + # If there is an immediate, show it as part of the relocation. Ideally + # we'd show this addend in both %lo/%hi, but annoyingly objdump's output + # doesn't include enough information to pair up %lo's and %hi's... + # TODO: handle unambiguous cases where all addends for a symbol are the + # same, or show "+???". + mnemonic = prev.split()[0] + if ( + mnemonic in arch.instructions_with_address_immediates + and not imm.startswith("0x") + ): + imm = "0x" + imm + repl += "+" + imm if int(imm, 0) > 0 else imm + if "R_MIPS_LO16" in row: + repl = f"%lo({repl})" + elif "R_MIPS_HI16" in row: + # Ideally we'd pair up R_MIPS_LO16 and R_MIPS_HI16 to generate a + # correct addend for each, but objdump doesn't give us the order of + # the relocations, so we can't find the right LO16. :( + repl = f"%hi({repl})" + elif "R_MIPS_26" in row: + # Function calls + pass + elif "R_MIPS_PC16" in row: + # Branch to glabel. This gives confusing output, but there's not much + # we can do here. + pass + else: + assert False, f"unknown relocation type '{row}' for line '{prev}'" + return before + repl + after + + +class AsmProcessorPPC(AsmProcessor): + def process_reloc(self, row: str, prev: str) -> str: + arch = self.config.arch + assert any( + r in row for r in ["R_PPC_REL24", "R_PPC_ADDR16", "R_PPC_EMB_SDA21"] + ), f"unknown relocation type '{row}' for line '{prev}'" + before, imm, after = parse_relocated_line(prev) + repl = row.split()[-1] + if "R_PPC_REL24" in row: + # function calls + pass + elif "R_PPC_ADDR16_HI" in row: + # absolute hi of addr + repl = f"{repl}@h" + elif "R_PPC_ADDR16_HA" in row: + # adjusted hi of addr + repl = f"{repl}@ha" + elif "R_PPC_ADDR16_LO" in row: + # lo of addr + repl = f"{repl}@l" + elif "R_PPC_ADDR16" in row: + # 16-bit absolute addr + if "+0x7" in repl: + # remove the very large addends as they are an artifact of (label-_SDA(2)_BASE_) + # computations and are unimportant in a diff setting. + if int(repl.split("+")[1], 16) > 0x70000000: + repl = repl.split("+")[0] + elif "R_PPC_EMB_SDA21" in row: + # small data area + pass + return before + repl + after + + +class AsmProcessorARM32(AsmProcessor): + def process_reloc(self, row: str, prev: str) -> str: + arch = self.config.arch + before, imm, after = parse_relocated_line(prev) + repl = row.split()[-1] + return before + repl + after + + def _normalize_arch_specific(self, mnemonic: str, row: str) -> str: + if self.config.ignore_addr_diffs: + row = self._normalize_bl(mnemonic, row) + row = self._normalize_data_pool(row) + return row + + def _normalize_bl(self, mnemonic: str, row: str) -> str: + if mnemonic != "bl": + return row + + row, _ = split_off_address(row) + return row + "" + + def _normalize_data_pool(self, row: str) -> str: + pool_match = re.search(ARM32_LOAD_POOL_PATTERN, row) + if pool_match: + offset = pool_match.group(3).split(" ")[0][1:] + repl = DATA_POOL_PLACEHOLDER.format(offset) + return pool_match.group(1) + repl + return row + + def post_process(self, lines: List["Line"]) -> None: + lines_by_line_number = {} + for line in lines: + lines_by_line_number[line.line_num] = line + for line in lines: + reloc_match = re.search( + DATA_POOL_PLACEHOLDER_PATTERN, line.normalized_original + ) + if reloc_match is None: + continue + + # Get value at relocation + reloc = reloc_match.group(0) + line_number = re.search( + DATA_POOL_PLACEHOLDER_PATTERN, reloc).group(1) + line_original = lines_by_line_number[int(line_number, 16)].original + value = line_original.split()[1] + + # Replace relocation placeholder with value + replaced = re.sub( + DATA_POOL_PLACEHOLDER_PATTERN, + f"={value} ({line_number})", + line.normalized_original, + ) + line.original = replaced + + +class AsmProcessorAArch64(AsmProcessor): def __init__(self, config: Config) -> None: super().__init__(config) self._adrp_pair_registers: Set[str] = set() @@ -1394,23 +1543,6 @@ class DifferenceNormalizerAArch64(DifferenceNormalizer): return row -class DifferenceNormalizerARM32(DifferenceNormalizer): - def __init__(self, config: Config) -> None: - super().__init__(config) - - def _normalize_arch_specific(self, mnemonic: str, row: str) -> str: - if self.config.ignore_addr_diffs: - row = self._normalize_bl(mnemonic, row) - return row - - def _normalize_bl(self, mnemonic: str, row: str) -> str: - if mnemonic != "bl": - return row - - row, _ = split_off_address(row) - return row + "" - - @dataclass class ArchSettings: name: str @@ -1420,14 +1552,15 @@ class ArchSettings: re_sprel: Pattern[str] re_large_imm: Pattern[str] re_imm: Pattern[str] + re_reloc: Pattern[str] branch_instructions: Set[str] instructions_with_address_immediates: Set[str] forbidden: Set[str] = field(default_factory=lambda: set(string.ascii_letters + "_")) arch_flags: List[str] = field(default_factory=list) branch_likely_instructions: Set[str] = field(default_factory=set) - difference_normalizer: Type[DifferenceNormalizer] = DifferenceNormalizer + proc: Type[AsmProcessor] = AsmProcessor big_endian: Optional[bool] = True - + delay_slot_instructions: Set[str] = field(default_factory=set) MIPS_BRANCH_LIKELY_INSTRUCTIONS = { "beql", @@ -1543,10 +1676,13 @@ MIPS_SETTINGS = ArchSettings( re_sprel=re.compile(r"(?<=,)([0-9]+|0x[0-9a-f]+)\(sp\)"), re_large_imm=re.compile(r"-?[1-9][0-9]{2,}|-?0x[0-9a-f]{3,}"), re_imm=re.compile(r"(\b|-)([0-9]+|0x[0-9a-fA-F]+)\b(?!\(sp)|%(lo|hi)\([^)]*\)"), + re_reloc=re.compile(r"R_MIPS_"), arch_flags=["-m", "mips:4300"], branch_likely_instructions=MIPS_BRANCH_LIKELY_INSTRUCTIONS, branch_instructions=MIPS_BRANCH_INSTRUCTIONS, instructions_with_address_immediates=MIPS_BRANCH_INSTRUCTIONS.union({"jal", "j"}), + delay_slot_instructions=MIPS_BRANCH_INSTRUCTIONS.union({"j", "jal", "jr", "jalr"}), + proc=AsmProcessorMIPS, ) MIPSEL_SETTINGS = replace(MIPS_SETTINGS, name="mipsel", big_endian=False) @@ -1566,9 +1702,10 @@ ARM32_SETTINGS = ArchSettings( re_sprel=re.compile(r"sp, #-?(0x[0-9a-fA-F]+|[0-9]+)\b"), re_large_imm=re.compile(r"-?[1-9][0-9]{2,}|-?0x[0-9a-f]{3,}"), re_imm=re.compile(r"(? Tuple[str, str, str]: return before, imm, after -def process_mips_reloc(row: str, prev: str, arch: ArchSettings) -> str: - if "R_MIPS_NONE" in row: - # GNU as emits no-op relocations immediately after real ones when - # assembling with -mabi=64. Return without trying to parse 'imm' as an - # integer. - return prev - before, imm, after = parse_relocated_line(prev) - repl = row.split()[-1] - if imm != "0": - # MIPS uses relocations with addends embedded in the code as immediates. - # If there is an immediate, show it as part of the relocation. Ideally - # we'd show this addend in both %lo/%hi, but annoyingly objdump's output - # doesn't include enough information to pair up %lo's and %hi's... - # TODO: handle unambiguous cases where all addends for a symbol are the - # same, or show "+???". - mnemonic = prev.split()[0] - if ( - mnemonic in arch.instructions_with_address_immediates - and not imm.startswith("0x") - ): - imm = "0x" + imm - repl += "+" + imm if int(imm, 0) > 0 else imm - if "R_MIPS_LO16" in row: - repl = f"%lo({repl})" - elif "R_MIPS_HI16" in row: - # Ideally we'd pair up R_MIPS_LO16 and R_MIPS_HI16 to generate a - # correct addend for each, but objdump doesn't give us the order of - # the relocations, so we can't find the right LO16. :( - repl = f"%hi({repl})" - elif "R_MIPS_26" in row: - # Function calls - pass - elif "R_MIPS_PC16" in row: - # Branch to glabel. This gives confusing output, but there's not much - # we can do here. - pass - else: - assert False, f"unknown relocation type '{row}' for line '{prev}'" - return before + repl + after - - -def process_ppc_reloc(row: str, prev: str) -> str: - assert any( - r in row for r in ["R_PPC_REL24", "R_PPC_ADDR16", "R_PPC_EMB_SDA21"] - ), f"unknown relocation type '{row}' for line '{prev}'" - before, imm, after = parse_relocated_line(prev) - repl = row.split()[-1] - if "R_PPC_REL24" in row: - # function calls - pass - elif "R_PPC_ADDR16_HI" in row: - # absolute hi of addr - repl = f"{repl}@h" - elif "R_PPC_ADDR16_HA" in row: - # adjusted hi of addr - repl = f"{repl}@ha" - elif "R_PPC_ADDR16_LO" in row: - # lo of addr - repl = f"{repl}@l" - elif "R_PPC_ADDR16" in row: - # 16-bit absolute addr - if "+0x7" in repl: - # remove the very large addends as they are an artifact of (label-_SDA(2)_BASE_) - # computations and are unimportant in a diff setting. - if int(repl.split("+")[1], 16) > 0x70000000: - repl = repl.split("+")[0] - elif "R_PPC_EMB_SDA21" in row: - # small data area - pass - return before + repl + after - - -def process_arm_reloc(row: str, prev: str, arch: ArchSettings) -> str: - before, imm, after = parse_relocated_line(prev) - repl = row.split()[-1] - return before + repl + after - - def pad_mnemonic(line: str) -> str: if "\t" not in line: return line @@ -1741,7 +1803,7 @@ class Line: def process(dump: str, config: Config) -> List[Line]: arch = config.arch - normalizer = arch.difference_normalizer(config) + processor = arch.proc(config) skip_next = False source_lines = [] source_filename = None @@ -1783,7 +1845,7 @@ def process(dump: str, config: Config) -> List[Line]: ) break - if not re.match(r"^ +[0-9a-f]+:\t", row): + if not re.match(r"^\s+[0-9a-f]+:\s+", row): # This regex is conservative, and assumes the file path does not contain "weird" # characters like colons, tabs, or angle brackets. if re.match( @@ -1797,10 +1859,11 @@ def process(dump: str, config: Config) -> List[Line]: m_comment = re.search(arch.re_comment, row) comment = m_comment[0] if m_comment else None row = re.sub(arch.re_comment, "", row) + line_num_str = row.split(":")[0] row = row.rstrip() tabs = row.split("\t") row = "\t".join(tabs[2:]) - line_num = eval_line_num(tabs[0].strip()) + line_num = eval_line_num(line_num_str.strip()) if line_num in data_refs: refs = data_refs[line_num] @@ -1835,20 +1898,13 @@ def process(dump: str, config: Config) -> List[Line]: while i < len(lines): reloc_row = lines[i] - if "R_AARCH64_" in reloc_row: - # TODO: handle relocation - pass - elif "R_MIPS_" in reloc_row: - original = process_mips_reloc(reloc_row, original, arch) - elif "R_PPC_" in reloc_row: - original = process_ppc_reloc(reloc_row, original) - elif "R_ARM_" in reloc_row: - original = process_arm_reloc(reloc_row, original, arch) + if re.search(arch.re_reloc, reloc_row): + original = processor.process_reloc(reloc_row, original) else: break i += 1 - normalized_original = normalizer.normalize(mnemonic, original) + normalized_original = processor.normalize(mnemonic, original) scorable_line = normalized_original if not config.score_stack_differences: @@ -1904,6 +1960,7 @@ def process(dump: str, config: Config) -> List[Line]: elif stop_after_delay_slot: break + processor.post_process(output) return output @@ -2123,8 +2180,15 @@ class OutputLine: class Diff: lines: List[OutputLine] score: int + max_score: int +def trim_nops(lines: List[Line], arch: ArchSettings) -> List[Line]: + lines = lines[:] + while lines and lines[-1].mnemonic == "nop" and (len(lines) == 1 or lines[-2].mnemonic not in arch.delay_slot_instructions): + lines.pop() + return lines + def do_diff(lines1: List[Line], lines2: List[Line], config: Config) -> Diff: if config.show_source: import cxxfilt @@ -2152,8 +2216,12 @@ def do_diff(lines1: List[Line], lines2: List[Line], config: Config) -> Diff: btset.add(bt) sc(str(bt)) + lines1 = trim_nops(lines1, arch) + lines2 = trim_nops(lines2, arch) + diffed_lines = diff_lines(lines1, lines2, config.algorithm) score = score_diff_lines(diffed_lines, config) + max_score = len(lines1) * config.penalty_deletion line_num_base = -1 line_num_offset = 0 @@ -2385,7 +2453,7 @@ def do_diff(lines1: List[Line], lines2: List[Line], config: Config) -> Diff: ) output = output[config.skip_lines :] - return Diff(lines=output, score=score) + return Diff(lines=output, score=score, max_score=max_score) def chunk_diff_lines( @@ -2461,6 +2529,7 @@ def align_diffs( Text(f"{padding}PREVIOUS ({old_diff.score})"), ), current_score=new_diff.score, + max_score=new_diff.max_score, previous_score=old_diff.score, ) old_chunks = chunk_diff_lines(old_diff.lines) @@ -2504,6 +2573,7 @@ def align_diffs( Text(f"{padding}CURRENT ({new_diff.score})"), ), current_score=new_diff.score, + max_score=new_diff.max_score, previous_score=None, ) diff_lines = [(line, line) for line in new_diff.lines] diff --git a/tools/disasm/disasm.py b/tools/disasm/disasm.py old mode 100644 new mode 100755 index 8c6c86824..e0b7705ea --- a/tools/disasm/disasm.py +++ b/tools/disasm/disasm.py @@ -1,11 +1,23 @@ #!/usr/bin/env python3 import argparse, ast, math, os, re, struct +import bisect from mips_isa import * -from multiprocessing import Pool +from multiprocessing import * +from pathlib import Path parser = argparse.ArgumentParser() -parser.add_argument('-j', dest='jobs', type=int, default=1, help='number of processes to run at once') +parser.add_argument( + "-j", dest="jobs", type=int, default=1, help="number of processes to run at once" +) +parser.add_argument( + "--full", + "-f", + dest="full", + action="store_true", + default=False, + help="Decompile all files regardless of whether they are used or not", +) args = parser.parse_args() jobs = args.jobs @@ -13,119 +25,241 @@ jobs = args.jobs ASM_OUT = "asm/" DATA_OUT = "data/" + +def discard_decomped_files(files_spec): + root_path = Path(__file__).parent.parent.parent + + with open(root_path / "spec", "r") as f: + spec = f.read() + # No need to check anything beyond here + spec = spec[: spec.find('name "gameplay_keep"')].splitlines()[:-2] + + new_spec = [] + for f in files_spec: + name, _, type, _, file_list = f + + # Find the beginseg for this file + i = 0 + while i < len(spec): + if spec[i].startswith("beginseg") and f'"{name}"' in spec[i + 1]: + break + i += 1 + + # For every file within this segment, look through the seg for lines with this file's name + # if found, check whether it's still in build/asm/ or build/data/, in which case it's not decomped + # if all references to it are in build/src/ then it should be ok to skip, some code/boot files are a bit different + + seg_start = i + new_files = {} + included = False + saved_off = 0 + for offset, file in file_list.items(): + if file == "[PADDING]": + continue + + # some files aren't named + if file == "": + file = f"{type}_{offset:08X}" + include = True + # flg_set_table is not in the spec, and buffers has its own section, just add them + elif file == "flg_set_table" or "buffers" in file: + include = True + else: + include = False + i = seg_start + last_line = "" + while not spec[i].startswith("endseg"): + if f"/{file}." in spec[i]: + if spec[i].count(".") == 1: + last_line = spec[i] + if "build/asm/" in spec[i] or "build/data/" in spec[i]: + include = True + break + i += 1 + else: + # Many code/boot files only have a single section (i.e .text) + # In that case it will be inside build/src/ and pragma in the asm + # For these files, open the source and look for the pragmas to be sure + # Overlays always have at least a data section we can check in the spec, so it's not needed for them + if type != "overlay" and last_line != "": + assert last_line.count(".") == 1 + last_line = ( + last_line.strip() + .split("build/", 1)[1] + .replace(".o", ".c")[:-1] + ) + with open(root_path / last_line, "r") as f2: + if "GLOBAL_ASM" in f2.read(): + include = True + + if include: + new_files[offset] = file + included = True + + if type == "overlay" and not included: + continue + if included: + f[4] = new_files + + new_spec.append(f) + + return new_spec + + MIPS_BRANCH_LIKELY_INSNS = [ - MIPS_INS_BEQL, MIPS_INS_BGEZALL, - MIPS_INS_BGEZL, MIPS_INS_BGTZL, - MIPS_INS_BLEZL, MIPS_INS_BLTZALL, - MIPS_INS_BLTZL, MIPS_INS_BNEL, - MIPS_INS_BC1TL, MIPS_INS_BC1FL, + MIPS_INS_BEQL, + MIPS_INS_BGEZALL, + MIPS_INS_BGEZL, + MIPS_INS_BGTZL, + MIPS_INS_BLEZL, + MIPS_INS_BLTZALL, + MIPS_INS_BLTZL, + MIPS_INS_BNEL, + MIPS_INS_BC1TL, + MIPS_INS_BC1FL, ] MIPS_BRANCH_INSNS = [ *MIPS_BRANCH_LIKELY_INSNS, MIPS_INS_BEQ, - MIPS_INS_BGEZ, MIPS_INS_BGEZAL, + MIPS_INS_BGEZ, + MIPS_INS_BGEZAL, MIPS_INS_BGTZ, MIPS_INS_BNE, - MIPS_INS_BLTZ, MIPS_INS_BLTZAL, + MIPS_INS_BLTZ, + MIPS_INS_BLTZAL, MIPS_INS_BLEZ, - MIPS_INS_BC1T, MIPS_INS_BC1F, - + MIPS_INS_BC1T, + MIPS_INS_BC1F, MIPS_INS_BEQZ, MIPS_INS_BNEZ, MIPS_INS_B, ] -MIPS_JUMP_INSNS = [ - MIPS_INS_JAL, MIPS_INS_JALR, MIPS_INS_J, MIPS_INS_JR -] +MIPS_JUMP_INSNS = [MIPS_INS_JAL, MIPS_INS_JALR, MIPS_INS_J, MIPS_INS_JR] -MIPS_FP_LOAD_INSNS = [ - MIPS_INS_LWC1, MIPS_INS_LDC1 -] +MIPS_FP_LOAD_INSNS = [MIPS_INS_LWC1, MIPS_INS_LDC1] -MIPS_FP_STORE_INSNS = [ - MIPS_INS_SWC1, MIPS_INS_SDC1 -] +MIPS_FP_STORE_INSNS = [MIPS_INS_SWC1, MIPS_INS_SDC1] -MIPS_FP_LOAD_STORE_INSNS = [ - *MIPS_FP_LOAD_INSNS, *MIPS_FP_STORE_INSNS -] +MIPS_FP_LOAD_STORE_INSNS = [*MIPS_FP_LOAD_INSNS, *MIPS_FP_STORE_INSNS] MIPS_STORE_INSNS = [ - MIPS_INS_SB, - MIPS_INS_SH, - MIPS_INS_SW, MIPS_INS_SWL, MIPS_INS_SWR, - MIPS_INS_SD, MIPS_INS_SDL, MIPS_INS_SDR, - MIPS_INS_SC, MIPS_INS_SCD, - *MIPS_FP_STORE_INSNS + MIPS_INS_SB, + MIPS_INS_SH, + MIPS_INS_SW, + MIPS_INS_SWL, + MIPS_INS_SWR, + MIPS_INS_SD, + MIPS_INS_SDL, + MIPS_INS_SDR, + MIPS_INS_SC, + MIPS_INS_SCD, + *MIPS_FP_STORE_INSNS, ] MIPS_LOAD_STORE_INSNS = [ - MIPS_INS_LB, MIPS_INS_LBU, - MIPS_INS_LH, MIPS_INS_LHU, - MIPS_INS_LW, MIPS_INS_LWL, MIPS_INS_LWR, MIPS_INS_LWU, - MIPS_INS_LD, MIPS_INS_LDL, MIPS_INS_LDR, - MIPS_INS_LL, MIPS_INS_LLD, + MIPS_INS_LB, + MIPS_INS_LBU, + MIPS_INS_LH, + MIPS_INS_LHU, + MIPS_INS_LW, + MIPS_INS_LWL, + MIPS_INS_LWR, + MIPS_INS_LWU, + MIPS_INS_LD, + MIPS_INS_LDL, + MIPS_INS_LDR, + MIPS_INS_LL, + MIPS_INS_LLD, *MIPS_STORE_INSNS, - *MIPS_FP_LOAD_STORE_INSNS + *MIPS_FP_LOAD_STORE_INSNS, ] -functions = set() # vram of functions -data_labels = set() # vram of data labels, TODO this + functions can merge into something more general eventually +VRAM_BASE = { + "code": {"data": 0x801AAAB0, "rodata": 0x801DBDF0, "bss": 0x801E3FA0}, + "boot": {"data": 0x800969C0, "rodata": 0x80098190, "bss": 0x80099500}, +} +functions = set() # vram of functions +# vram of data labels, TODO this + functions can merge into something more general eventually +data_labels = set() branch_labels = set() # vram of branch labels via branch/jump instructions -jtbls = set() # vram of jump tables -jtbl_labels = set() # vram of branch labels via jtbls, higher output priority than regular branch labels -floats = set() # vram of floats -doubles = set() # vram of doubles -prospective_strings = set() # vram of possible strings -strings = set() # vram of confirmed strings -symbols = {} # lui/addiu pairs : {addr of %hi : full symbol} AND {addr of %lo : full symbol} , twice the space complexity but much less time complexity -constants = {} # lui/ori pairs : {addr of %hi : full constant} AND {addr of %lo : full constant} , twice the space complexity but much less time complexity -dwords = set() # doublewords -multiply_referenced_rodata = set() # rodata with more than 1 reference outside of the same function cannot be migrated +jtbls = set() # vram of jump tables +# vram of branch labels via jtbls, higher output priority than regular branch labels +jtbl_labels = set() +floats = set() # vram of floats +doubles = set() # vram of doubles +prospective_strings = set() # vram of possible strings +strings = set() # vram of confirmed strings +# lui/addiu pairs : {addr of %hi : full symbol} AND {addr of %lo : full symbol} , +# twice the space complexity but much less time complexity +symbols = {} +# lui/ori pairs : {addr of %hi : full constant} AND {addr of %lo : full constant} , +# twice the space complexity but much less time complexity +constants = {} +dwords = set() # doublewords +# rodata with more than 1 reference outside of the same function cannot be migrated +multiply_referenced_rodata = set() +files = set() # vram start of file -files = set() # vram start of file - -vrom_variables = list() # (name,addr) +vrom_variables = list() # (name,addr) +vrom_addrs = set() # set of addrs from vrom_variables, for faster lookup functions_ast = None variables_ast = None +variable_addrs = None + +files_text = {} -vars_cache = {} # (address: variable + addend) def proper_name(symbol, in_data=False, is_symbol=True): # hacks - if symbol == 0x809C46F0: # ovl_En_Encount4 fake symbol at the very end of the data section + # ovl_En_Encount4 fake symbol at the very end of the data section + if symbol == 0x809C46F0: return variables_ast[0x809C46DC][0] + " + 0x14" - elif symbol == 0x801EF66D: # z_message_nes constant-folding stray fairy array + elif symbol == 0x801EF66D: # z_message_nes constant-folding stray fairy array return variables_ast[0x801EF670][0] + f" - 0x{0x801EF670 - 0x801EF66D:X}" - elif symbol == 0x80A09740: # boss_07 symbol with large addend folded into %lo + elif symbol == 0x80A09740: # boss_07 symbol with large addend folded into %lo return variables_ast[0x80A09A60][0] + f" - 0x{0x80A09A60 - 0x80A09740:X}" - elif symbol == 0x80B80248: # bg_ikana_mirror symbol with large addend folded into %lo + # bg_ikana_mirror symbol with large addend folded into %lo + elif symbol == 0x80B80248: return variables_ast[0x80B801A8][0] + f" + 0x{0x80B80248 - 0x80B801A8:X}" - elif symbol == 0x8084D2FC: # player symbol with very large addend folded into %lo, since we don't know the real symbol just use the first data symbol for now + # player symbol with very large addend folded into %lo, since we don't know the real symbol just use the first data symbol for now + elif symbol == 0x8084D2FC: return variables_ast[0x8085B9F0][0] + f" - 0x{0x8085B9F0 - 0x8084D2FC:X}" - elif symbol == 0x001ABAB0 or symbol == 0x001E3BB0: # OS_K0_TO_PHYSICAL on rspS2DEX text and data symbols + # OS_K0_TO_PHYSICAL on rspS2DEX text and data symbols + elif symbol == 0x001ABAB0 or symbol == 0x001E3BB0: return variables_ast[symbol + 0x80000000][0] + " - 0x80000000" - elif symbol == 0x00AC0480: # do_action_static + 0x480, this is the only rom segment that has a constant offset folded into it so just hack it + # do_action_static + 0x480, this is the only rom segment that has a constant offset folded into it so just hack it + elif symbol == 0x00AC0480: return "_do_action_staticSegmentRomStart + 0x480" # real names - if symbol in functions and symbol in functions_ast.keys(): + if symbol in functions_ast.keys(): return functions_ast[symbol][0] elif symbol in variables_ast.keys(): return variables_ast[symbol][0] - elif symbol in [addr for _,addr in vrom_variables]: + elif symbol in vrom_addrs: # prefer "start" vrom symbols - if symbol in [addr for name,addr in vrom_variables if "SegmentRomStart" in name]: - return [name for name,addr in vrom_variables if "SegmentRomStart" in name and addr == symbol][0] + filteredVromSymbols = { + addr: name + for name, addr in vrom_variables + if "SegmentRomStart" in name and addr == symbol + } + if symbol in filteredVromSymbols: + return filteredVromSymbols[symbol] else: - return [name for name,addr in vrom_variables if addr == symbol][0] + return [name for name, addr in vrom_variables if addr == symbol][0] # addends - if is_symbol and symbol in vars_cache.keys(): - return vars_cache[symbol] + if is_symbol: + symbol_index = bisect.bisect(variable_addrs, symbol) + if symbol_index: + vram_addr = variable_addrs[symbol_index - 1] + symbol_name, _, _, symbol_size = variables_ast[vram_addr] + + if vram_addr < symbol < vram_addr + symbol_size: + return f"{symbol_name} + 0x{symbol-vram_addr:X}" # generated names if symbol in functions and not in_data: @@ -140,63 +274,77 @@ def proper_name(symbol, in_data=False, is_symbol=True): else: return f"0x{symbol:08X}" + def lookup_name(symbol, word): # hacks for vrom variables in data - if word in [addr for _,addr in vrom_variables]: - if word == 0: # no makerom segment start + if word in vrom_addrs: + if word == 0: # no makerom segment start return "0x00000000" - if symbol in [0x801AE4A0, # effect table - 0x801C2740, # object table - 0x801C2650, # elf_message table - 0x801C3CA0, # scene table - 0x801AEFD0, # actor table - 0x801D0B70, # kaleido table - 0x801D0BB0, # fbdemo table - 0x801BE4D4, # kankyo skybox table - 0x801BD910, # gamestate table - 0x801C2660 # scene textures table - ]: # data labels that are allowed to have vrom variables + if symbol in [ + 0x801AE4A0, # effect table + 0x801C2740, # object table + 0x801C2650, # elf_message table + 0x801C3CA0, # scene table + 0x801AEFD0, # actor table + 0x801D0B70, # kaleido table + 0x801D0BB0, # fbdemo table + 0x801BE4D4, # kankyo skybox table + 0x801BD910, # gamestate table + 0x801C2660, # scene textures table + ]: # data labels that are allowed to have vrom variables return proper_name(word, is_symbol=False) else: return f"0x{word:08X}" # hacks for variables with references to variables with addends (i.e. gSaveContext + 0x...) - if symbol in [0x800980C4, 0x801AE8F0]: # __osViNext and flg_set table + if symbol in [0x800980C4, 0x801AE8F0]: # __osViNext and flg_set table return proper_name(word, is_symbol=True) return proper_name(word, is_symbol=False) + def as_double(b): return struct.unpack(">d", b)[0] + def as_float(b): return struct.unpack(">f", b)[0] + def as_dword(b): return struct.unpack(">Q", b)[0] + def as_word(b): return struct.unpack(">I", b)[0] + def as_hword(b): return struct.unpack(">H", b)[0] + def as_double_list(b): return [i[0] for i in struct.iter_unpack(">d", b)] + def as_float_list(b): return [i[0] for i in struct.iter_unpack(">f", b)] + def as_dword_list(b): return [i[0] for i in struct.iter_unpack(">Q", b)] + def as_word_list(b): return [i[0] for i in struct.iter_unpack(">I", b)] + def as_hword_list(b): return [h[0] for h in struct.iter_unpack(">H", b)] + STR_INDENT = " " -def try_decode_string(data_bytes, output_ends = True, force_ascii = False): + +def try_decode_string(data_bytes, output_ends=True, force_ascii=False): """ Swiss Cheese """ @@ -217,20 +365,49 @@ def try_decode_string(data_bytes, output_ends = True, force_ascii = False): char = "\\x1B" index = data_bytes.index(0x1B) else: - assert False , "???" + assert False, "???" part1 = try_decode_string(data_bytes[0:index], output_ends=False) - part2 = try_decode_string(data_bytes[index+1:], output_ends=False) + part2 = try_decode_string(data_bytes[index + 1 :], output_ends=False) if part2 != "": - result = part1 + (("\"\n" + STR_INDENT + ".ascii \"") if part2[0] in hex_digits and part1 != "" else "") + \ - char + (("\"\n" + STR_INDENT + ".asciz \"") if part2[0] in hex_digits else "") + part2 + result = ( + part1 + + ( + ('"\n' + STR_INDENT + '.ascii "') + if part2[0] in hex_digits and part1 != "" + else "" + ) + + char + + (('"\n' + STR_INDENT + '.asciz "') if part2[0] in hex_digits else "") + + part2 + ) if output_ends and part2[0] in hex_digits and part1 == "": directive = "ascii" else: - result = part1 + (("\"\n" + STR_INDENT + ".ascii \"") if part2[0] in hex_digits and part1 != "" else "") + char + "\"\n" + result = ( + part1 + + ( + ('"\n' + STR_INDENT + '.ascii "') + if part2[0] in hex_digits and part1 != "" + else "" + ) + + char + + '"\n' + ) else: - result = data_bytes.decode("EUC-JP").replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t").replace("\0", "") + result = ( + data_bytes.decode("EUC-JP") + .replace("\n", "\\n") + .replace("\r", "\\r") + .replace("\t", "\\t") + .replace("\0", "") + ) + + return ( + (("." + directive + ' "') if output_ends else "") + + result + + ('"' if output_ends else "") + ) - return (("." + directive + " \"") if output_ends else "") + result + ("\"" if output_ends else "") def reduce_float(flt_str, is_double=False): def n_digits(str): @@ -241,8 +418,8 @@ def reduce_float(flt_str, is_double=False): def str_round(string, precision): if "." not in string or precision < 0: return string - int_part = string.split(".")[0] - frac_part = string.split(".")[1] + int_part = string.split(".")[0] + frac_part = string.split(".")[1] while len(frac_part) > precision: last_digit = int(frac_part[-1]) @@ -263,7 +440,9 @@ def reduce_float(flt_str, is_double=False): return int_part + "." + frac_part def to_binary(flt_str): - return as_dword(struct.pack(">d", float(flt_str))) if is_double else as_word(struct.pack(">f", float(flt_str))) + if is_double: + return as_dword(struct.pack(">d", float(flt_str))) + return as_word(struct.pack(">f", float(flt_str))) exponent = "" if "e" in flt_str: @@ -292,18 +471,20 @@ def reduce_float(flt_str, is_double=False): return flt_str + exponent + def format_f64(d_dwd): d = as_double(struct.pack(">Q", d_dwd)) if math.isnan(d): return f".long 0x{d_dwd:016X}" return f".double {reduce_float(repr(d), is_double=True)}" + def format_f32(f_wd): # GNU AS isn't ieee compliant? if f_wd in [0xB8E4AECD, 0xB8E4C3AA, 0x38D1B718]: return f".word 0x{f_wd:08X}" - if f_wd == 0x7F7FFFFF: # FLT_MAX + if f_wd == 0x7F7FFFFF: # FLT_MAX return ".float 3.4028235e+38" f = as_float(struct.pack(">I", f_wd)) @@ -311,19 +492,30 @@ def format_f32(f_wd): return f".word 0x{f_wd:08X}" return f".float {reduce_float(repr(f))}" + def put_symbol(symbols_dict, setname, symbol): if setname in symbols_dict: symbols_dict[setname].add(symbol) else: symbols_dict[setname] = {symbol} + def put_symbols(symbols_dict, setname, symbols): if setname in symbols_dict: symbols_dict[setname].update(symbols) else: symbols_dict[setname] = symbols.copy() + +def put_text(name, text): + files_text[name] = text + + def update_symbols_from_dict(symbols_dict): + file_text = [] + if type(symbols_dict) == tuple: + symbols_dict, file_text = symbols_dict + for setname, symbol in symbols_dict.items(): if setname == "functions": functions.update(symbol) @@ -352,10 +544,18 @@ def update_symbols_from_dict(symbols_dict): elif setname == "files": files.update(symbol) -def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs, segment_name): + for file in file_text: + put_text(file[0], file[1]) + + +def find_symbols_in_text(section, rodata_section, data_regions): + data, rodata = section[4], rodata_section[4] if rodata_section else None + vram, vram_rodata = section[0], rodata_section[0] if rodata_section else None + relocs, info = section[5], section[-1] + symbols_dict = dict() - print(f"Finding symbols from .text in {segment_name}") + print(f"Finding symbols from .text in {info['name']}") if rodata is not None: rodata_words = as_word_list(rodata) @@ -368,14 +568,15 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs, put_symbol(symbols_dict, "files", vram) # lui trackers are saved at branches to be restored when the branch target is reached - saved_lui_trackers = {} # vram: tracker list + saved_lui_trackers = {} # vram: tracker list + def save_tracker(restore_at, tracker): if restore_at in saved_lui_trackers.keys(): saved_lui_trackers[restore_at].update(tracker) else: saved_lui_trackers.update({restore_at: tracker}) - lui_tracker = {} # register : (addr, immediate) + lui_tracker = {} # register : (addr, immediate) prospective_jtbls = set() @@ -383,7 +584,7 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs, func_jtbl_labels = set() individual_jtbl_labels = {} - clobber_later = {} # addr : reg + clobber_later = {} # addr : reg delay_slot = False delayed_insn = None @@ -401,8 +602,14 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs, # print(f"insn: {insn.mnemonic}, rt: {insn.rt}, first: {insn.value_forname(insn.fields[0])}") # assert insn.id not in [MIPS_INS_ORI, MIPS_INS_ADDIU, *MIPS_LOAD_STORE_INSNS] or insn.rt == insn.value_forname(insn.fields[0]) - if delay_slot and delayed_insn is not None and delayed_insn.id in MIPS_BRANCH_LIKELY_INSNS: - clobber_later.update({delayed_insn.offset : insn.value_forname(insn.fields[0])}) + if ( + delay_slot + and delayed_insn is not None + and delayed_insn.id in MIPS_BRANCH_LIKELY_INSNS + ): + clobber_later.update( + {delayed_insn.offset: insn.value_forname(insn.fields[0])} + ) else: lui_tracker.pop(insn.value_forname(insn.fields[0]), None) @@ -412,45 +619,9 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs, if region[1] % 0x10 == 0: put_symbol(symbols_dict, "files", region[1]) - if relocs is not None: - """ - Relocation info is our friend. Get symbols via relocations first. - """ - prev_hi = None - hi_vram = -1 - for reloc in relocs: - insn = decode_insn(raw_insns[reloc[2]//4], vram + reloc[2]) - - if reloc[1] == 2: # R_MIPS_32 - assert False , "R_MIPS_32 in .text section?" - elif reloc[1] == 4: # R_MIPS_26 - """ - Relocated jump targets give us functions in this section - """ - assert insn.id == MIPS_INS_JAL , f"R_MIPS_26 applied to {insn.mnemonic} when it should be JAL" - put_symbol(symbols_dict, "functions", insn.target) - elif reloc[1] == 5: # R_MIPS_HI16 - """ - Relocated %hi gives us %hi values to match with associated %lo - """ - assert insn.id == MIPS_INS_LUI , f"R_MIPS_HI16 applied to {insn.mnemonic} when it should be LUI" - prev_hi = insn.imm - hi_vram = vram + reloc[2] - elif reloc[1] == 6: # R_MIPS_LO16 - """ - Relocated %lo + a %hi to match with gives us relocated symbols in data sections - """ - assert insn.id == MIPS_INS_ADDIU or insn.id in MIPS_LOAD_STORE_INSNS , f"R_MIPS_HI16 applied to {insn.mnemonic} when it should be ADDIU or a load/store" - symbol_value = (prev_hi << 0x10) + insn.imm - put_symbols(symbols_dict, "symbols", {hi_vram : symbol_value}) - put_symbols(symbols_dict, "symbols", {vram + reloc[2] : symbol_value}) - else: - assert False , "Invalid relocation type encountered" - - for i,raw_insn in enumerate(raw_insns,0): - i *= 4 - vaddr = vram + i - insn = decode_insn(raw_insn, vaddr) + insns = [] + for i, raw_insn in enumerate(raw_insns, 0): + insn = decode_insn(raw_insn, vram + i * 4) if insn.id == MIPS_INS_JR and insn.rs != MIPS_REG_RA: # It's hard to find when two jump tables next to each other end, so do a naive first pass @@ -461,17 +632,72 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs, # addu $at, $at, $reg # lw $reg, %lo(jtbl)($at) # jr $reg - insn_m1 = decode_insn(raw_insns[i//4 - 1], vaddr - 0x4) - insn_m2 = decode_insn(raw_insns[i//4 - 2], vaddr - 0x8) - insn_m3 = decode_insn(raw_insns[i//4 - 3], vaddr - 0xC) - - if insn_m1.id == MIPS_INS_LW and insn_m2.id == MIPS_INS_ADDU and insn_m3.id == MIPS_INS_LUI: + insn_m1 = insns[-1] + insn_m2 = insns[-2] + insn_m3 = insns[-3] + if ( + insn_m1.id == MIPS_INS_LW + and insn_m2.id == MIPS_INS_ADDU + and insn_m3.id == MIPS_INS_LUI + ): prospective_jtbls.add((insn_m3.imm << 0x10) + insn_m1.imm) + insns.append(insn) - for i,raw_insn in enumerate(raw_insns,0): - i *= 4 - vaddr = vram + i - insn = decode_insn(raw_insn, vaddr) + if relocs is not None: + """ + Relocation info is our friend. Get symbols via relocations first. + """ + prev_hi = None + hi_vram = -1 + for reloc in relocs: + insn = insns[reloc[2] // 4] + + if reloc[1] == 2: # R_MIPS_32 + assert False, "R_MIPS_32 in .text section?" + elif reloc[1] == 4: # R_MIPS_26 + """ + Relocated jump targets give us functions in this section + """ + assert ( + insn.id == MIPS_INS_JAL + ), f"R_MIPS_26 applied to {insn.mnemonic} when it should be JAL" + put_symbol(symbols_dict, "functions", insn.target) + elif reloc[1] == 5: # R_MIPS_HI16 + """ + Relocated %hi gives us %hi values to match with associated %lo + """ + assert ( + insn.id == MIPS_INS_LUI + ), f"R_MIPS_HI16 applied to {insn.mnemonic} when it should be LUI" + prev_hi = insn.imm + hi_vram = vram + reloc[2] + elif reloc[1] == 6: # R_MIPS_LO16 + """ + Relocated %lo + a %hi to match with gives us relocated symbols in data sections + """ + assert ( + insn.id == MIPS_INS_ADDIU or insn.id in MIPS_LOAD_STORE_INSNS + ), f"R_MIPS_HI16 applied to {insn.mnemonic} when it should be ADDIU or a load/store" + symbol_value = (prev_hi << 0x10) + insn.imm + put_symbols(symbols_dict, "symbols", {hi_vram: symbol_value}) + put_symbols(symbols_dict, "symbols", {vram + reloc[2]: symbol_value}) + else: + assert False, "Invalid relocation type encountered" + + result_files = [] + results = [asm_header(".text")] + raw_insns = as_word_list(data) + + cur_file = "" + cur_vaddr = 0 + + segment_dirname = ("" if info["type"] != "overlay" else "overlays/") + info["name"] + + delayed_insn = None + delay_slot = False + + for i, insn in enumerate(insns, 0): + vaddr = vram + i * 4 # sometimes there's data embedded in .text in handwritten asm files that don't respect section contents in_data = False @@ -480,6 +706,16 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs, in_data = True break if in_data: + results.append( + { + "vaddr": vaddr, + "insn": {"id": insn.id}, + "addr": f"/* {i*4:06X} {vaddr:08X} {raw_insns[i]:08X} */ ", + "mnem": "", + "op": [f" .word 0x{raw_insns[i]:08X}"], + "data": True, + } + ) continue if vaddr in functions or vaddr in symbols_dict["functions"]: @@ -517,64 +753,99 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs, func_branch_labels.add(insn.target) elif insn.id == MIPS_INS_JR: # check if anything branches past it in either branch or jtbl labels - if vaddr >= max(func_branch_labels, default=0) and vaddr >= max(func_jtbl_labels, default=0): # vaddr being largest in list means nothing branches past here + if vaddr >= max(func_branch_labels, default=0) and vaddr >= max( + func_jtbl_labels, default=0 + ): # vaddr being largest in list means nothing branches past here # mark next function after delay slot and after any nop padding if present - if len(raw_insns) > i//4 + 2: + if len(insns) > i + 2: n_padding = 0 end = False - while (raw_insns[i//4 + 2 + n_padding] == 0): + while raw_insns[i + 2 + n_padding] == 0: n_padding += 1 - if len(raw_insns) <= i//4 + 2 + n_padding: + if len(raw_insns) <= i + 2 + n_padding: end = True break if not end: if n_padding > 0: - assert (vaddr + 8 + n_padding * 4) % 0x10 == 0 , f"padding to non-0x10 alignment?, 0x{vaddr + 8 + n_padding * 4:08X}" - put_symbol(symbols_dict, "functions", vaddr + 8 + n_padding * 4) - put_symbol(symbols_dict, "functions", vaddr + 8 + n_padding * 4) + assert ( + vaddr + 8 + n_padding * 4 + ) % 0x10 == 0, f"padding to non-0x10 alignment?, 0x{vaddr + 8 + n_padding * 4:08X}" + put_symbol( + symbols_dict, "functions", vaddr + 8 + n_padding * 4 + ) + put_symbol( + symbols_dict, "functions", vaddr + 8 + n_padding * 4 + ) delayed_insn = insn elif insn.id == MIPS_INS_LUI: """ Process LUI instruction - + All symbol loading involves LUI, and tracking how %hi values loaded via LUI instructions propagate through a function is key to identifying symbol references """ # add lui to tracker - if delay_slot and delayed_insn is not None and delayed_insn.id in MIPS_BRANCH_LIKELY_INSNS: + if ( + delay_slot + and delayed_insn is not None + and delayed_insn.id in MIPS_BRANCH_LIKELY_INSNS + ): # for branch likelies, the current tracker does not update but the lui is saved to be tracked at the branch target - save_tracker(delayed_insn.offset, {insn.rt : (vaddr, insn.imm)}) + save_tracker(delayed_insn.offset, {insn.rt: (vaddr, insn.imm)}) else: - lui_tracker.update({insn.rt : (vaddr, insn.imm)}) + lui_tracker.update({insn.rt: (vaddr, insn.imm)}) elif insn.id == MIPS_INS_ADDIU or insn.id in MIPS_LOAD_STORE_INSNS: # try match with tracked lui and mark symbol - hi_vram, imm_value = lui_tracker.get(insn.rs if insn.id == MIPS_INS_ADDIU else insn.base, (None, None)) + hi_vram, imm_value = lui_tracker.get( + insn.rs if insn.id == MIPS_INS_ADDIU else insn.base, (None, None) + ) # if a match was found, validate and record the symbol, TODO improve validation - if hi_vram != None and ((((imm_value >> 0x8) & 0xF) != 0 and imm_value < 0x1000) or \ - (imm_value >= 0x8000 and imm_value < 0x80D0) or \ - (imm_value >= 0xA400 and imm_value < 0xA480) or (imm_value < 0x0400 and insn.id == MIPS_INS_ADDIU)): + if hi_vram != None and ( + (((imm_value >> 0x8) & 0xF) != 0 and imm_value < 0x1000) + or (imm_value >= 0x8000 and imm_value < 0x80D0) + or (imm_value >= 0xA400 and imm_value < 0xA480) + or (imm_value < 0x0400 and insn.id == MIPS_INS_ADDIU) + ): lo_vram = vaddr symbol_value = (imm_value << 0x10) + insn.imm - put_symbols(symbols_dict, "symbols", {hi_vram : symbol_value}) - put_symbols(symbols_dict, "symbols", {lo_vram : symbol_value}) + put_symbols(symbols_dict, "symbols", {hi_vram: symbol_value}) + put_symbols(symbols_dict, "symbols", {lo_vram: symbol_value}) if insn.id == MIPS_INS_LW: # try find jr within the same block - cur_idx = i//4 - lookahead_insn = decode_insn(raw_insns[cur_idx], vram + cur_idx * 4) # TODO fix vaddr here + cur_idx = i + lookahead_insn = insns[cur_idx] # TODO fix vaddr here # still in same block unless one of these instructions are found - while lookahead_insn.id not in [*MIPS_BRANCH_INSNS, MIPS_INS_JAL, MIPS_INS_JALR, MIPS_INS_J]: + while lookahead_insn.id not in [ + *MIPS_BRANCH_INSNS, + MIPS_INS_JAL, + MIPS_INS_JALR, + MIPS_INS_J, + ]: if lookahead_insn.id == MIPS_INS_JR: - if lookahead_insn.rs == (insn.ft if insn.id in MIPS_FP_LOAD_STORE_INSNS else insn.rt): + if lookahead_insn.rs == ( + insn.ft + if insn.id in MIPS_FP_LOAD_STORE_INSNS + else insn.rt + ): # read the jtbl and add targets to func_jtbl_labels - assert rodata is not None , "A rodata section should be present if functions use jump tables" + assert ( + rodata is not None + ), "A rodata section should be present if functions use jump tables" next_jtbl_jr = vaddr + cur_idx * 4 - individual_jtbl_labels.update({next_jtbl_jr : set()}) + individual_jtbl_labels.update({next_jtbl_jr: set()}) - offset = (symbol_value - vram_rodata)//4 + offset = (symbol_value - vram_rodata) // 4 label = rodata_words[offset] - while label >= vram and label < vram + len(data) and \ - (vram_rodata + offset * 4 not in prospective_jtbls or vram_rodata + offset * 4 == symbol_value): + while ( + label >= vram + and label < vram + len(data) + and ( + vram_rodata + offset * 4 + not in prospective_jtbls + or vram_rodata + offset * 4 == symbol_value + ) + ): func_jtbl_labels.add(label) individual_jtbl_labels[next_jtbl_jr].add(label) offset += 1 @@ -585,44 +856,55 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs, put_symbol(symbols_dict, "jtbls", symbol_value) # found a jr that matches, no need to keep searching break - elif (insn.ft if insn.id in MIPS_FP_LOAD_STORE_INSNS else insn.rt) in [lookahead_insn.value_forname(field) for field in lookahead_insn.fields[1:]]: + elif ( + insn.ft if insn.id in MIPS_FP_LOAD_STORE_INSNS else insn.rt + ) in [ + lookahead_insn.value_forname(field) + for field in lookahead_insn.fields[1:] + ]: # register clobbered, no need to keep searching break cur_idx += 1 # found end before finding jr insn, not a jtbl if cur_idx >= len(raw_insns): break - lookahead_insn = decode_insn(raw_insns[cur_idx], vram + cur_idx * 4) # TODO fix vaddr here - elif insn.id == MIPS_INS_LD: # doubleword loads + lookahead_insn = insns[cur_idx] # TODO fix vaddr here + elif insn.id == MIPS_INS_LD: # doubleword loads put_symbol(symbols_dict, "dwords", symbol_value) - elif insn.id in [MIPS_INS_LWC1, MIPS_INS_SWC1]: # float load/stores + elif insn.id in [MIPS_INS_LWC1, MIPS_INS_SWC1]: # float load/stores # add float put_symbol(symbols_dict, "floats", symbol_value) - elif insn.id in [MIPS_INS_LDC1, MIPS_INS_SDC1]: # double load/stores + elif insn.id in [MIPS_INS_LDC1, MIPS_INS_SDC1]: # double load/stores # add double put_symbol(symbols_dict, "doubles", symbol_value) - elif insn.id == MIPS_INS_ADDIU and vaddr % 4 == 0: # strings seem to only ever be 4-byte aligned + elif ( + insn.id == MIPS_INS_ADDIU and vaddr % 4 == 0 + ): # strings seem to only ever be 4-byte aligned # add possible string put_symbol(symbols_dict, "prospective_strings", symbol_value) # clear lui tracking state if register is clobbered by the addiu/load instruction itself - # insn.rt == (insn.rs if insn.id == MIPS_INS_ADDIU else insn.base) and + # insn.rt == (insn.rs if insn.id == MIPS_INS_ADDIU else insn.base) and if insn.id not in MIPS_STORE_INSNS and insn.id not in MIPS_FP_LOAD_INSNS: clobber_conditionally(insn) elif insn.id == MIPS_INS_ORI: # try match with tracked lui and mark constant hi_vram, imm_value = lui_tracker.get(insn.rs, (None, None)) - if hi_vram != None: # found match + if hi_vram != None: # found match lo_vram = vaddr const_value = (imm_value << 0x10) | insn.imm - put_symbols(symbols_dict, "constants", {hi_vram : const_value}) - put_symbols(symbols_dict, "constants", {lo_vram : const_value}) + put_symbols(symbols_dict, "constants", {hi_vram: const_value}) + put_symbols(symbols_dict, "constants", {lo_vram: const_value}) # clear lui tracking state if register is clobbered by the ori instruction itself - # insn.rt == insn.rs or + # insn.rt == insn.rs or if insn.rt in lui_tracker.keys(): clobber_conditionally(insn) else: # clear lui tracking if register is clobbered by something unrelated - if insn.id == MIPS_INS_ADDU and insn.rs in lui_tracker.keys() and (insn.rd == insn.rs): + if ( + insn.id == MIPS_INS_ADDU + and insn.rs in lui_tracker.keys() + and (insn.rd == insn.rs) + ): # array accesses optimisation: # lui reg, %hi(symbol) # addu reg, reg, idx @@ -631,22 +913,113 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs, # if the output is not currently tracked it will behave as intended anyway pass # insns listed either write to fprs/cop0 or don't write to any - elif insn.id not in [MIPS_INS_MTC0, MIPS_INS_MTC1, MIPS_INS_DMTC1, - MIPS_INS_MULT, MIPS_INS_MULTU, MIPS_INS_DMULT, MIPS_INS_DMULTU, - MIPS_INS_DIV, MIPS_INS_DIVU, MIPS_INS_DDIV, MIPS_INS_DDIVU, - MIPS_INS_MTHI, MIPS_INS_MTLO, - MIPS_INS_CTC1, - MIPS_INS_NOP, - MIPS_INS_BREAK, - MIPS_INS_TLBP, MIPS_INS_TLBR, MIPS_INS_TLBWI, - MIPS_INS_MOV_S, MIPS_INS_MOV_D, MIPS_INS_C_LT_S, MIPS_INS_C_LT_D, - MIPS_INS_DIV_S, MIPS_INS_MUL_S, MIPS_INS_TRUNC_W_S, MIPS_INS_CVT_S_W, - MIPS_INS_SUB_S, MIPS_INS_ADD_S]: + elif insn.id not in [ + MIPS_INS_MTC0, + MIPS_INS_MTC1, + MIPS_INS_DMTC1, + MIPS_INS_MULT, + MIPS_INS_MULTU, + MIPS_INS_DMULT, + MIPS_INS_DMULTU, + MIPS_INS_DIV, + MIPS_INS_DIVU, + MIPS_INS_DDIV, + MIPS_INS_DDIVU, + MIPS_INS_MTHI, + MIPS_INS_MTLO, + MIPS_INS_CTC1, + MIPS_INS_NOP, + MIPS_INS_BREAK, + MIPS_INS_TLBP, + MIPS_INS_TLBR, + MIPS_INS_TLBWI, + MIPS_INS_MOV_S, + MIPS_INS_MOV_D, + MIPS_INS_C_LT_S, + MIPS_INS_C_LT_D, + MIPS_INS_DIV_S, + MIPS_INS_MUL_S, + MIPS_INS_TRUNC_W_S, + MIPS_INS_CVT_S_W, + MIPS_INS_SUB_S, + MIPS_INS_ADD_S, + ]: clobber_conditionally(insn) + ############# Start text disassembly ########## + # Symbols aren't avaialble here yet, so placeholders are added + # in each instruction, to be looked up later + mnemonic = f" {insn.mnemonic}" if delay_slot else insn.mnemonic + op_str = insn.op_str + instr = {"id": insn.id} + + if vaddr in full_file_list[info["name"]]: + if cur_file != "": + if cur_vaddr in info["syms"]: + result_files.append([cur_file, results]) + results = [asm_header(".text")] + cur_vaddr = vaddr + cur_file = full_file_list[info["name"]][vaddr] + if cur_file == "": + cur_file = f"{info['name']}_{vaddr:08X}" + + if insn.id in MIPS_BRANCH_INSNS: + op_str_parts = [] + for field in insn.fields: + if field == "offset": + op_str_parts.append(f".L{insn.offset:08X}") + else: + op_str_parts.append(insn.format_field(field)) + op_str = [", ".join(op_str_parts)] + + elif insn.id in MIPS_JUMP_INSNS: + op_str = [] + op_str_parts = [] + for field in insn.fields: + if field == "target": + op_str_parts.append([insn.target, False, True]) + else: + op_str_parts.append(insn.format_field(field)) + for x, part in enumerate(op_str_parts): + if x + 1 < len(op_str_parts): + part += ", " + op_str.append(part) + + elif insn.id == MIPS_INS_LUI: + op_str = [op_str] + instr["rt"] = insn.rt + + elif insn.id == MIPS_INS_ADDIU or insn.id in MIPS_LOAD_STORE_INSNS: + op_str = [op_str] + instr["rt"] = insn.rt + instr["rs"] = insn.rs + instr["ft"] = insn.ft + instr["base"] = insn.base + + elif insn.id == MIPS_INS_ORI: + op_str = [op_str] + instr["rt"] = insn.rt + instr["rs"] = insn.rs + + results.append( + { + "vaddr": vaddr, + "insn": instr, + "addr": f"/* {i*4:06X} {vaddr:08X} {raw_insns[i]:08X} */ ", + "mnem": mnemonic, + "op": op_str, + "data": False, + } + ) + + ######### End text disassembly ############## + if delay_slot and delayed_insn is not None: - if delayed_insn.id == MIPS_INS_JAL or delayed_insn.id == MIPS_INS_JALR or \ - (delayed_insn.id == MIPS_INS_JR and delayed_insn.rs == MIPS_REG_RA): + if ( + delayed_insn.id == MIPS_INS_JAL + or delayed_insn.id == MIPS_INS_JALR + or (delayed_insn.id == MIPS_INS_JR and delayed_insn.rs == MIPS_REG_RA) + ): # destroy lui tracking state lui_tracker.clear() elif delayed_insn.id == MIPS_INS_JR and vaddr == next_jtbl_jr + 4: @@ -665,82 +1038,124 @@ def find_symbols_in_text(data, rodata, vram, vram_rodata, data_regions, relocs, delay_slot = delayed_insn is not None + result_files.append([cur_file, results]) + put_symbols(symbols_dict, "branch_labels", func_branch_labels) put_symbols(symbols_dict, "jtbl_labels", func_jtbl_labels) - return symbols_dict + return symbols_dict, result_files -def find_symbols_in_data(data, vram, end, relocs, segment_name): + +def find_symbols_in_data(section): + data, vram, end, relocs = section[4], section[0], section[1], section[5] symbols_dict = dict() - print(f"Finding symbols from .data in {segment_name}") + print(f"Finding symbols from .data in {section[-1]['name']}") # read relocations for symbols if relocs is not None: for reloc in relocs: - if reloc[1] == 2: # R_MIPS_32 - put_symbol(symbols_dict, "data_labels", as_word(data[reloc[2] : reloc[2] + 4])) - elif reloc[1] == 4: # R_MIPS_26 - assert False , "R_MIPS_26 in .data section?" - elif reloc[1] == 5: # R_MIPS_HI16 - assert False , "R_MIPS_HI16 in .data section?" - elif reloc[1] == 6: # R_MIPS_LO16 - assert False , "R_MIPS_LO16 in .data section?" + if reloc[1] == 2: # R_MIPS_32 + put_symbol( + symbols_dict, "data_labels", as_word(data[reloc[2] : reloc[2] + 4]) + ) + elif reloc[1] == 4: # R_MIPS_26 + assert False, "R_MIPS_26 in .data section?" + elif reloc[1] == 5: # R_MIPS_HI16 + assert False, "R_MIPS_HI16 in .data section?" + elif reloc[1] == 6: # R_MIPS_LO16 + assert False, "R_MIPS_LO16 in .data section?" else: - assert False , "Invalid relocation type encountered" + assert False, "Invalid relocation type encountered" return symbols_dict # TODO more -# matches several codepoint regions of EUC-JP -strings_regex = re.compile(rb'^(?:[\x00\x1A\x1B\n\t\x20-\x7E\x8C\x8D]|\x30[\x00-\xFF]|[\x4E-\x9F][\x00-\xFF]|[\xA4\xA5\xBB][\xA1-\xF6]|[\xA1-\xA3\xB0-\xBF\xC0-\xCF][\xA1-\xFE]|\xFF[\x00-\xEF])+$') -def find_symbols_in_rodata(data, vram, end, relocs, segment): +# matches several codepoint regions of EUC-JP +strings_regex = re.compile( + rb"^(?:[\x00\x1A\x1B\n\t\x20-\x7E\x8C\x8D]|\x30[\x00-\xFF]|[\x4E-\x9F][\x00-\xFF]|[\xA4\xA5\xBB][\xA1-\xF6]|[\xA1-\xA3\xB0-\xBF\xC0-\xCF][\xA1-\xFE]|\xFF[\x00-\xEF])+$" +) + + +def find_symbols_in_rodata(section): + data, vram, end, relocs = section[4], section[0], section[1], section[5] + symbols_dict = dict() + + print(f"Finding symbols from .rodata in {section[-1]['name']}") + # read relocations for symbols if relocs is not None: for reloc in relocs: - if reloc[1] == 2: # R_MIPS_32 - data_labels.add(as_word(data[reloc[2] : reloc[2] + 4])) - elif reloc[1] == 4: # R_MIPS_26 - assert False , "R_MIPS_26 in .rodata section?" - elif reloc[1] == 5: # R_MIPS_HI16 - assert False , "R_MIPS_HI16 in .rodata section?" - elif reloc[1] == 6: # R_MIPS_LO16 - assert False , "R_MIPS_LO16 in .rodata section?" + if reloc[1] == 2: # R_MIPS_32 + put_symbol( + symbols_dict, "data_labels", as_word(data[reloc[2] : reloc[2] + 4]) + ) + elif reloc[1] == 4: # R_MIPS_26 + assert False, "R_MIPS_26 in .rodata section?" + elif reloc[1] == 5: # R_MIPS_HI16 + assert False, "R_MIPS_HI16 in .rodata section?" + elif reloc[1] == 6: # R_MIPS_LO16 + assert False, "R_MIPS_LO16 in .rodata section?" else: - assert False , "Invalid relocation type encountered" + assert False, "Invalid relocation type encountered" - section_symbols = set([sym for sym in symbols.values() if sym >= vram and sym < end]) + section_symbols = set( + [sym for sym in symbols.values() if sym >= vram and sym < end] + ) section_symbols.add(vram) - section_symbols.update(set([sym for sym in data_labels if sym >= vram and sym < end])) + section_symbols.update( + set([sym for sym in data_labels if sym >= vram and sym < end]) + ) # TODO temp hack, move - for data_file_st in [sym for sym in segment[4].keys() if sym >= vram and sym < end]: + for data_file_st in [ + sym for sym in section[-1]["syms"].keys() if sym >= vram and sym < end + ]: section_symbols.add(data_file_st) - rodata_starts = [addr for addr,name in segment[4].items() if addr >= vram and addr < end] + rodata_starts = [ + addr + for addr, name in section[-1]["syms"].items() + if addr >= vram and addr < end + ] section_symbols.update(set(rodata_starts)) section_symbols = list(section_symbols) section_symbols.sort() - section_late_rodata = [sym for sym in section_symbols if sym in floats or sym in doubles or sym in jtbls] + section_late_rodata = [ + sym + for sym in section_symbols + if sym in floats or sym in doubles or sym in jtbls + ] # string finding is best done per-file as the late_rodata sections are not merged per-segment, so you get stripes of # rodata - late_rodata -(file boundary)- rodata - late_rodata -(file boundary)- etc. # all rodata file starts - for fi,rodata_start in enumerate(rodata_starts,0): - next_rodata_start = rodata_starts[fi + 1] if fi < len(rodata_starts) - 1 else end + for fi, rodata_start in enumerate(rodata_starts, 0): + next_rodata_start = ( + rodata_starts[fi + 1] if fi < len(rodata_starts) - 1 else end + ) # symbols in this file - file_symbols = [sym for sym in section_symbols if sym >= rodata_start and sym < next_rodata_start] + file_symbols = [ + sym + for sym in section_symbols + if sym >= rodata_start and sym < next_rodata_start + ] # the first (minimum st_value) symbol in section_late_rodata in this file is the start of late_rodata - late_rodata_start = min([sym for sym in file_symbols if sym in section_late_rodata], default=next_rodata_start) + late_rodata_start = min( + [sym for sym in file_symbols if sym in section_late_rodata], + default=next_rodata_start, + ) - for i,symbol in enumerate(file_symbols,0): - next_symbol = file_symbols[i + 1] if i < len(file_symbols) - 1 else next_rodata_start + for i, symbol in enumerate(file_symbols, 0): + next_symbol = ( + file_symbols[i + 1] if i < len(file_symbols) - 1 else next_rodata_start + ) # not late_rodata if symbol >= late_rodata_start: @@ -751,7 +1166,7 @@ def find_symbols_in_rodata(data, vram, end, relocs, segment): data_offset = symbol - vram data_size = next_symbol - symbol - string_data = data[data_offset:data_offset+data_size] + string_data = data[data_offset : data_offset + data_size] if len(string_data) > 0 and string_data[0] == 0: # empty strings that are auto-detected are dubious @@ -761,8 +1176,10 @@ def find_symbols_in_rodata(data, vram, end, relocs, segment): if strings_regex.match(string_data) != None: k = 0 done = False - for j,b in enumerate(string_data,0): - if b == 0 and (j + 1 >= len(string_data) or string_data[j + 1] != 0): + for j, b in enumerate(string_data, 0): + if b == 0 and ( + j + 1 >= len(string_data) or string_data[j + 1] != 0 + ): # try: # decoded = try_decode_string(string_data[k:string_data.index(0)]) # except UnicodeDecodeError: @@ -770,14 +1187,16 @@ def find_symbols_in_rodata(data, vram, end, relocs, segment): # done = True # if done: # break - data_labels.add(symbol + k) - strings.add(symbol + k) - data_labels.add(symbol + j + 1) + put_symbol(symbols_dict, "data_labels", symbol + k) + put_symbol(symbols_dict, "data_labels", symbol + j + 1) + put_symbol(symbols_dict, "strings", symbol + k) k = j + 1 # TODO more + return symbols_dict -def asm_header(section_name): + +def asm_header(section_name): return f""".include "macro.inc" # assembler directives @@ -790,36 +1209,128 @@ def asm_header(section_name): .balign 16 """ -def disassemble_text(data, vram, data_regions, segment): + +def fixup_text_symbols(data, vram, data_regions, info): + segment_dirname = "" if info["type"] != "overlay" else "overlays/" + if info["type"] in ("boot", "code"): + segment_dirname += info["type"] + else: + segment_dirname += info["name"] + + os.makedirs(f"{ASM_OUT}/{segment_dirname}/", exist_ok=True) + + file = files_text[info["name"]] + # header + text = [file.pop(0)] + + # We didn't have full symbols available during initial disassembly, + # so here we loop over each instruction, and do symbol lookups, add labels etc + + for i, entry in enumerate(file): + vaddr = entry["vaddr"] + + if vaddr in functions: + text.append(f"\nglabel {proper_name(vaddr, in_data=entry['data'])}\n") + if vaddr in jtbl_labels: + text.append(f"glabel L{vaddr:08X}\n") + if vaddr in branch_labels: + text.append(f".L{vaddr:08X}:\n") + + line = entry["addr"] + if not entry["data"]: + line += f"{entry['mnem']:12}" + + insn = entry["insn"] + if insn["id"] in MIPS_JUMP_INSNS: + for op_part in entry["op"]: + if type(op_part) == list: + line += proper_name( + op_part[0], in_data=op_part[1], is_symbol=op_part[2] + ) + else: + line += op_part + + elif insn["id"] == MIPS_INS_LUI: + symbol_value = symbols.get(vaddr, None) + if symbol_value is not None: + line += ( + f"{mips_gpr_names[insn['rt']]}, %hi({proper_name(symbol_value)})" + ) + else: + constant_value = constants.get(vaddr, None) + if constant_value is not None: + line += ( + f"{mips_gpr_names[insn['rt']]}, (0x{constant_value:08X} >> 16)" + ) + else: + line += entry["op"][0] + + elif insn["id"] == MIPS_INS_ADDIU or insn["id"] in MIPS_LOAD_STORE_INSNS: + symbol_value = symbols.get(vaddr, None) + if symbol_value is not None: + if insn["id"] == MIPS_INS_ADDIU: + line += f"{mips_gpr_names[insn['rt']]}, {mips_gpr_names[insn['rs']]}, %lo({proper_name(symbol_value)})" + else: + line += f"{mips_fpr_names[insn['ft']] if insn['id'] in MIPS_FP_LOAD_STORE_INSNS else mips_gpr_names[insn['rt']]}, %lo({proper_name(symbol_value)})({mips_gpr_names[insn['base']]})" + else: + line += entry["op"][0] + + elif insn["id"] == MIPS_INS_ORI: + constant_value = constants.get(vaddr, None) + if constant_value is not None: + line += f"{mips_gpr_names[insn['rt']]}, {mips_gpr_names[insn['rs']]}, (0x{constant_value:08X} & 0xFFFF)" + else: + line += entry["op"][0] + + else: + for part in entry["op"]: + if type(part) == list: + line += ( + f"{proper_name(part[0], in_data=part[1], is_symbol=part[2])}" + ) + else: + line += part + + line += "\n" + text.append(line) + + with open(f"{ASM_OUT}/{segment_dirname}/{info['name']}.text.s", "w") as outfile: + outfile.write("".join(text)) + + +def disassemble_text(data, vram, data_regions, info): result = asm_header(".text") raw_insns = as_word_list(data) cur_file = "" + cur_vaddr = 0 - segment_dirname = ("" if segment[2] != "overlay" else "overlays/") + segment[0] + segment_dirname = ("" if info["type"] != "overlay" else "overlays/") + info["name"] + os.makedirs(f"{ASM_OUT}/{segment_dirname}/", exist_ok=True) delayed_insn = None delay_slot = False - for i,raw_insn in enumerate(raw_insns,0): + for i, raw_insn in enumerate(raw_insns, 0): i *= 4 vaddr = vram + i - insn = decode_insn(raw_insns[i//4], vaddr) + insn = decode_insn(raw_insns[i // 4], vaddr) mnemonic = insn.mnemonic op_str = insn.op_str - if vaddr in segment[4].keys(): + if vaddr in full_file_list[info["name"]]: if cur_file != "": - os.makedirs(f"{ASM_OUT}/{segment_dirname}/", exist_ok=True) - with open(f"{ASM_OUT}/{segment_dirname}/{cur_file}.text.s", "w") as outfile: - outfile.write(result) + if cur_vaddr in info["syms"]: + os.makedirs(f"{ASM_OUT}/{segment_dirname}/", exist_ok=True) + with open( + f"{ASM_OUT}/{segment_dirname}/{cur_file}.text.s", "w" + ) as outfile: + outfile.write(result) result = asm_header(".text") - cur_file = segment[4][vaddr] + cur_vaddr = vaddr + cur_file = full_file_list[info["name"]][vaddr] if cur_file == "": - cur_file = f"{segment[0]}_{vaddr:08X}" - - if cur_file == "[PADDING]": # workaround for assumed linker bug - continue + cur_file = f"{info['name']}_{vaddr:08X}" # DATA EMBEDDED IN TEXT in_data = False @@ -828,9 +1339,12 @@ def disassemble_text(data, vram, data_regions, segment): in_data = True break if in_data: - if vaddr in functions: # TODO not really a function if it falls in a data region... + # TODO not really a function if it falls in a data region... + if vaddr in functions: result += f"\nglabel {proper_name(vaddr, True)}\n" - result += f"/* {i:06X} {vaddr:08X} {raw_insn:08X} */ .word 0x{raw_insn:08X}\n" + result += ( + f"/* {i:06X} {vaddr:08X} {raw_insn:08X} */ .word 0x{raw_insn:08X}\n" + ) continue # LABELS @@ -845,7 +1359,7 @@ def disassemble_text(data, vram, data_regions, segment): if insn.id in MIPS_BRANCH_INSNS: op_str_parts = [] for field in insn.fields: - if field == 'offset': + if field == "offset": op_str_parts.append(f".L{insn.offset:08X}") else: op_str_parts.append(insn.format_field(field)) @@ -854,7 +1368,7 @@ def disassemble_text(data, vram, data_regions, segment): elif insn.id in MIPS_JUMP_INSNS: op_str_parts = [] for field in insn.fields: - if field == 'target': + if field == "target": op_str_parts.append(proper_name(insn.target, is_symbol=True)) else: op_str_parts.append(insn.format_field(field)) @@ -867,7 +1381,9 @@ def disassemble_text(data, vram, data_regions, segment): else: constant_value = constants.get(vaddr, None) if constant_value is not None: - op_str = f"{mips_gpr_names[insn.rt]}, (0x{constant_value:08X} >> 16)" + op_str = ( + f"{mips_gpr_names[insn.rt]}, (0x{constant_value:08X} >> 16)" + ) elif insn.id == MIPS_INS_ADDIU or insn.id in MIPS_LOAD_STORE_INSNS: symbol_value = symbols.get(vaddr, None) if symbol_value is not None: @@ -889,194 +1405,458 @@ def disassemble_text(data, vram, data_regions, segment): result += f"/* {i:06X} {vaddr:08X} {raw_insn:08X} */ {mnemonic:12}{op_str}\n" - os.makedirs(f"{ASM_OUT}/{segment_dirname}/", exist_ok=True) with open(f"{ASM_OUT}/{segment_dirname}/{cur_file}.text.s", "w") as outfile: outfile.write(result) -def disassemble_data(data, vram, end, segment): + +def disassemble_data(data, vram, end, info): section_symbols = [sym for sym in symbols.values() if sym >= vram and sym < end] section_symbols.append(vram) section_symbols.extend([sym for sym in data_labels if sym >= vram and sym < end]) - section_symbols.extend([sym for sym in variables_ast.keys() if sym >= vram and sym < end]) + section_symbols.extend( + [sym for sym in variables_ast.keys() if sym >= vram and sym < end] + ) # TODO temp hack, move - section_symbols.extend([sym for sym in segment[4].keys() if sym >= vram and sym < end]) + section_symbols.extend( + [sym for sym in info["syms"].keys() if sym >= vram and sym < end] + ) # remove symbols that are addends of other symbols - section_symbols = [sym for sym in section_symbols if " + 0x" not in proper_name(sym, True) and " - 0x" not in proper_name(sym, True)] + section_symbols = [ + sym + for sym in section_symbols + if " + 0x" not in proper_name(sym, True) + and " - 0x" not in proper_name(sym, True) + ] section_symbols = list(set(section_symbols)) section_symbols.sort() - segment_dirname = ("" if segment[2] != "overlay" else "overlays/") + segment[0] - - result = asm_header(".data") - cur_file = "" - - for i,symbol in enumerate(section_symbols,0): - next_symbol = section_symbols[i + 1] if i < len(section_symbols) - 1 else end - - # assert symbol % 4 == 0 , f"Unaligned .data symbol 0x{symbol:08X}" - - if symbol in segment[4].keys(): - if cur_file != "": - os.makedirs(f"{DATA_OUT}/{segment_dirname}/", exist_ok=True) - with open(f"{DATA_OUT}/{segment_dirname}/{cur_file}.data.s", "w") as outfile: - outfile.write(result) - result = asm_header(".data") - cur_file = segment[4][symbol] - if cur_file == "": - cur_file = f"{segment[0]}_{symbol:08X}" - - data_offset = symbol - vram - data_size = next_symbol - symbol - - if data_offset == len(data): - continue - - result += f"\nglabel {proper_name(symbol, True)}\n" - - if symbol % 8 == 0 and data_size % 8 == 0 and symbol in doubles: - result += "\n".join(\ - [f"/* {data_offset + j * 8:06X} {symbol + j * 8:08X} {dbl_dwd:016X} */ {format_f64(dbl_dwd)}" for j,dbl_dwd in enumerate(as_dword_list(data[data_offset:data_offset + data_size]), 0)]) + "\n" - elif symbol % 8 == 0 and data_size % 8 == 0 and symbol in dwords: - result += "\n".join(\ - [f"/* {data_offset + j * 8:06X} {symbol + j * 8:08X} */ .quad 0x{dword:08X}" for j,dword in enumerate(as_dword_list(data[data_offset:data_offset + data_size]), 0)]) + "\n" - elif symbol % 4 == 0 and data_size % 4 == 0: - if symbol in floats: - result += "\n".join(\ - [f"/* {data_offset + j * 4:06X} {symbol + j * 4:08X} {flt_wd:08X} */ {format_f32(flt_wd)}" for j,flt_wd in enumerate(as_word_list(data[data_offset:data_offset + data_size]), 0)]) + "\n" - else: - result += "\n".join(\ - [f"/* {data_offset + j * 4:06X} {symbol + j * 4:08X} */ .word {lookup_name(symbol, word)}" for j,word in enumerate(as_word_list(data[data_offset:data_offset + data_size]), 0)]) + "\n" - elif symbol % 2 == 0 and data_size % 2 == 0: - result += "\n".join(\ - [f"/* {data_offset + j * 2:06X} {symbol + j * 2:08X} */ .half 0x{hword:04X}" for j,hword in enumerate(as_hword_list(data[data_offset:data_offset + data_size]), 0)]) + "\n" - else: - result += "\n".join(\ - [f"/* {data_offset + j:06X} {symbol + j:08X} */ .byte 0x{byte:02X}" for j,byte in enumerate(data[data_offset:data_offset + data_size], 0)]) + "\n" - - os.makedirs(f"{DATA_OUT}/{segment[0]}/", exist_ok=True) - with open(f"{DATA_OUT}/{segment[0]}/{cur_file}.data.s", "w") as outfile: - outfile.write(result) - -def disassemble_rodata(data, vram, end, segment): - section_symbols = [sym for sym in symbols.values() if sym >= vram and sym < end] - section_symbols.append(vram) - section_symbols.extend([sym for sym in data_labels if sym >= vram and sym < end]) - section_symbols.extend([sym for sym in variables_ast.keys() if sym >= vram and sym < end]) - # TODO temp hack, move - section_symbols.extend([sym for sym in segment[4].keys() if sym >= vram and sym < end]) - - # remove symbols that are addends of other symbols - section_symbols = [sym for sym in section_symbols if " + 0x" not in proper_name(sym, True) and " - 0x" not in proper_name(sym, True)] - - section_symbols = list(set(section_symbols)) - - section_symbols.sort() - - segment_dirname = ("" if segment[2] != "overlay" else "overlays/") + segment[0] - - result = asm_header(".rodata") - cur_file = "" - - force_ascii_str = False # hack for non-null-terminated strings in .data - - for i,symbol in enumerate(section_symbols,0): - next_symbol = section_symbols[i + 1] if i < len(section_symbols) - 1 else end - - # assert symbol % 4 == 0 , f"Unaligned .data symbol 0x{symbol:08X}" - - if symbol in segment[4].keys(): - if cur_file != "": - os.makedirs(f"{DATA_OUT}/{segment_dirname}/", exist_ok=True) - with open(f"{DATA_OUT}/{segment_dirname}/{cur_file}.rodata.s", "w") as outfile: - outfile.write(result) - result = asm_header(".rodata") - cur_file = segment[4][symbol] - if cur_file == "": - cur_file = f"{segment[0]}_{symbol:08X}" - - data_offset = symbol - vram - data_size = next_symbol - symbol - - if data_offset == len(data): - continue - - force_ascii_str = symbol in [0x801D0708] - - result += f"\nglabel {proper_name(symbol, True)}\n" - - if symbol in strings: - string_data = data[data_offset:data_offset+data_size] - string_data = string_data[:string_data.index(0)] - assert all([b != 0 for b in string_data[:-1]]) , f"{symbol:08X} , {data_size:X} , {string_data}" # ensure strings don't have a null char midway through - result += f"/* {data_offset:06X} {symbol:08X} */ {try_decode_string(string_data, force_ascii=force_ascii_str)}\n{STR_INDENT}.balign 4\n" - elif symbol % 8 == 0 and data_size % 8 == 0 and symbol in doubles: - result += "\n".join(\ - [f"/* {data_offset + j * 8:06X} {symbol + j * 8:08X} {dbl_dwd:016X} */ {format_f64(dbl_dwd)}" for j,dbl_dwd in enumerate(as_dword_list(data[data_offset:data_offset + data_size]), 0)]) + "\n" - elif symbol % 4 == 0 and data_size % 4 == 0: - if symbol in floats: - result += "\n".join(\ - [f"/* {data_offset + j * 4:06X} {symbol + j * 4:08X} {flt_wd:08X} */ {format_f32(flt_wd)}" for j,flt_wd in enumerate(as_word_list(data[data_offset:data_offset + data_size]), 0)]) + "\n" - else: - result += "\n".join(\ - [f"/* {data_offset + j * 4:06X} {symbol + j * 4:08X} */ .word {lookup_name(symbol, word)}" for j,word in enumerate(as_word_list(data[data_offset:data_offset + data_size]), 0)]) + "\n" - elif symbol % 2 == 0 and data_size % 2 == 0: - result += "\n".join(\ - [f"/* {data_offset + j * 2:06X} {symbol + j * 2:08X} */ .half 0x{hword:04X}" for j,hword in enumerate(as_hword_list(data[data_offset:data_offset + data_size]), 0)]) + "\n" - else: - result += "\n".join(\ - [f"/* {data_offset + j:06X} {symbol + j:08X} */ .byte 0x{byte:02X}" for j,byte in enumerate(data[data_offset:data_offset + data_size], 0)]) + "\n" - - os.makedirs(f"{DATA_OUT}/{segment[0]}/", exist_ok=True) - with open(f"{DATA_OUT}/{segment[0]}/{cur_file}.rodata.s", "w") as outfile: - outfile.write(result) - -def disassemble_bss(vram, end, segment): - section_symbols = [sym for sym in symbols.values() if sym >= vram and sym < end] - section_symbols.append(vram) - section_symbols.extend([sym for sym in data_labels if sym >= vram and sym < end]) - section_symbols.extend([sym for sym in variables_ast.keys() if sym >= vram and sym < end]) - # TODO temp hack, move - section_symbols.extend([sym for sym in segment[4].keys() if sym >= vram and sym < end]) - - # remove symbols that are addends of other symbols - section_symbols = [sym for sym in section_symbols if " + 0x" not in proper_name(sym, True) and " - 0x" not in proper_name(sym, True)] - - section_symbols = list(set(section_symbols)) - - section_symbols.sort() - - # ("" if segment[2] != "overlay" else "overlays/" - segment_dirname = segment[0] - - result = asm_header(".bss") - cur_file = "" - - for i,symbol in enumerate(section_symbols,0): - next_symbol = section_symbols[i + 1] if i < len(section_symbols) - 1 else end - - if symbol in segment[4].keys(): - if cur_file != "": - os.makedirs(f"{DATA_OUT}/{segment_dirname}/", exist_ok=True) - with open(f"{DATA_OUT}/{segment_dirname}/{cur_file}.bss.s", "w") as outfile: - outfile.write(result) - result = asm_header(".bss") - cur_file = segment[4][symbol] - if cur_file == "": - cur_file = f"{segment[0]}_{symbol:08X}" - - result += f"\nglabel {proper_name(symbol, True)}\n" - result += f"/* {symbol - vram:06X} {symbol:08X} */ .space 0x{next_symbol - symbol:X}\n" + segment_dirname = info["name"] + if info["type"] in ("boot", "code"): + segment_dirname = info["type"] os.makedirs(f"{DATA_OUT}/{segment_dirname}/", exist_ok=True) - with open(f"{DATA_OUT}/{segment_dirname}/{cur_file}.bss.s", "w") as outfile: - outfile.write(result) + + if info["type"] in ("boot", "code"): + sym_list = full_file_list[info["type"]] + else: + sym_list = full_file_list[info["name"]] + + file_syms = [] + syms = [] + file_name = "" + for i, sym in enumerate(section_symbols): + if i == 0: + if info["type"] == "overlay": + file_name = info["name"] + else: + file_name = sym_list[sym] + + if sym in sym_list: + new_file = sym_list[sym] + if file_name != new_file: + file_syms.append( + {"name": file_name, "first_sym": syms[0], "syms": syms} + ) + syms = [] + file_name = new_file + syms.append(sym) + if len(syms) > 0: + file_syms.append({"name": file_name, "first_sym": syms[0], "syms": syms}) + + for i, file in enumerate(file_syms): + if file["first_sym"] not in info["syms"]: + continue + + result = [asm_header(".data")] + + for x, symbol in enumerate(file["syms"]): + if symbol >= end: + break + if x + 1 < len(file["syms"]): + next_symbol = file["syms"][x + 1] + elif i + 1 < len(file_syms): + next_symbol = file_syms[i + 1]["first_sym"] + else: + next_symbol = end + + data_base = symbol - info["base"] + data_offset = symbol - vram + data_size = next_symbol - symbol + + if data_offset == len(data): + continue + + r = f"\nglabel {proper_name(symbol, True)}\n" + + if symbol % 8 == 0 and data_size % 8 == 0 and symbol in doubles: + r += ( + "\n".join( + [ + f"/* {data_base + j * 8:06X} {symbol + j * 8:08X} {dbl_dwd:016X} */ {format_f64(dbl_dwd)}" + for j, dbl_dwd in enumerate( + as_dword_list( + data[data_offset : data_offset + data_size] + ), + 0, + ) + ] + ) + + "\n" + ) + elif symbol % 8 == 0 and data_size % 8 == 0 and symbol in dwords: + r += ( + "\n".join( + [ + f"/* {data_base + j * 8:06X} {symbol + j * 8:08X} */ .quad 0x{dword:08X}" + for j, dword in enumerate( + as_dword_list( + data[data_offset : data_offset + data_size] + ), + 0, + ) + ] + ) + + "\n" + ) + elif symbol % 4 == 0 and data_size % 4 == 0: + if symbol in floats: + r += ( + "\n".join( + [ + f"/* {data_base + j * 4:06X} {symbol + j * 4:08X} {flt_wd:08X} */ {format_f32(flt_wd)}" + for j, flt_wd in enumerate( + as_word_list( + data[data_offset : data_offset + data_size] + ), + 0, + ) + ] + ) + + "\n" + ) + else: + r += ( + "\n".join( + [ + f"/* {data_base + j * 4:06X} {symbol + j * 4:08X} */ .word {lookup_name(symbol, word)}" + for j, word in enumerate( + as_word_list( + data[data_offset : data_offset + data_size] + ), + 0, + ) + ] + ) + + "\n" + ) + elif symbol % 2 == 0 and data_size % 2 == 0: + r += ( + "\n".join( + [ + f"/* {data_base + j * 2:06X} {symbol + j * 2:08X} */ .half 0x{hword:04X}" + for j, hword in enumerate( + as_hword_list( + data[data_offset : data_offset + data_size] + ), + 0, + ) + ] + ) + + "\n" + ) + else: + r += ( + "\n".join( + [ + f"/* {data_base + j:06X} {symbol + j:08X} */ .byte 0x{byte:02X}" + for j, byte in enumerate( + data[data_offset : data_offset + data_size], 0 + ) + ] + ) + + "\n" + ) + result.append(r) + + if len(result) > 1: + with open( + f"{DATA_OUT}/{segment_dirname}/{file['name']}.data.s", "w" + ) as outfile: + outfile.write("".join(result)) + + +def disassemble_rodata(data, vram, end, info): + section_symbols = [sym for sym in symbols.values() if sym >= vram and sym < end] + section_symbols.append(vram) + section_symbols.extend([sym for sym in data_labels if sym >= vram and sym < end]) + section_symbols.extend( + [sym for sym in variables_ast.keys() if sym >= vram and sym < end] + ) + # TODO temp hack, move + section_symbols.extend( + [sym for sym in info["syms"].keys() if sym >= vram and sym < end] + ) + + # remove symbols that are addends of other symbols + section_symbols = [ + sym + for sym in section_symbols + if " + 0x" not in proper_name(sym, True) + and " - 0x" not in proper_name(sym, True) + ] + + section_symbols = list(set(section_symbols)) + + if len(section_symbols) == 0: + return + + section_symbols.sort() + + segment_dirname = info["name"] + if info["type"] in ("boot", "code"): + segment_dirname = info["type"] + os.makedirs(f"{DATA_OUT}/{segment_dirname}/", exist_ok=True) + + if info["type"] in ("boot", "code"): + sym_list = full_file_list[info["type"]] + else: + sym_list = full_file_list[info["name"]] + + force_ascii_str = False # hack for non-null-terminated strings in .data + + file_syms = [] + syms = [] + file_name = "" + for i, sym in enumerate(section_symbols): + if i == 0: + if info["type"] == "overlay": + file_name = info["name"] + else: + file_name = sym_list[sym] + + if sym in sym_list: + new_file = sym_list[sym] + if file_name != new_file: + file_syms.append( + {"name": file_name, "first_sym": syms[0], "syms": syms} + ) + syms = [] + file_name = new_file + syms.append(sym) + if len(syms) > 0: + file_syms.append({"name": file_name, "first_sym": syms[0], "syms": syms}) + + for i, file in enumerate(file_syms): + if file["first_sym"] not in info["syms"]: + continue + + result = [asm_header(".rodata")] + + for x, symbol in enumerate(file["syms"]): + if symbol >= end: + break + if x + 1 < len(file["syms"]): + next_symbol = file["syms"][x + 1] + elif i + 1 < len(file_syms): + next_symbol = file_syms[i + 1]["first_sym"] + else: + next_symbol = end + + data_base = symbol - info["base"] + data_offset = symbol - vram + data_size = next_symbol - symbol + + if data_offset == len(data): + continue + + force_ascii_str = symbol in [0x801D0708] + + r = f"\nglabel {proper_name(symbol, True)}\n" + + if symbol in strings: + string_data = data[data_offset : data_offset + data_size] + string_data = string_data[: string_data.index(0)] + # ensure strings don't have a null char midway through + assert all( + [b != 0 for b in string_data[:-1]] + ), f"{symbol:08X} , {data_size:X} , {string_data}" + r += f"/* {data_base:06X} {symbol:08X} */ {try_decode_string(string_data, force_ascii=force_ascii_str)}\n{STR_INDENT}.balign 4\n" + elif symbol % 8 == 0 and data_size % 8 == 0 and symbol in doubles: + r += ( + "\n".join( + [ + f"/* {data_base + j * 8:06X} {symbol + j * 8:08X} {dbl_dwd:016X} */ {format_f64(dbl_dwd)}" + for j, dbl_dwd in enumerate( + as_dword_list( + data[data_offset : data_offset + data_size] + ), + 0, + ) + ] + ) + + "\n" + ) + elif symbol % 4 == 0 and data_size % 4 == 0: + if symbol in floats: + r += ( + "\n".join( + [ + f"/* {data_base + j * 4:06X} {symbol + j * 4:08X} {flt_wd:08X} */ {format_f32(flt_wd)}" + for j, flt_wd in enumerate( + as_word_list( + data[data_offset : data_offset + data_size] + ), + 0, + ) + ] + ) + + "\n" + ) + else: + r += ( + "\n".join( + [ + f"/* {data_base + j * 4:06X} {symbol + j * 4:08X} */ .word {lookup_name(symbol, word)}" + for j, word in enumerate( + as_word_list( + data[data_offset : data_offset + data_size] + ), + 0, + ) + ] + ) + + "\n" + ) + elif symbol % 2 == 0 and data_size % 2 == 0: + r += ( + "\n".join( + [ + f"/* {data_base + j * 2:06X} {symbol + j * 2:08X} */ .half 0x{hword:04X}" + for j, hword in enumerate( + as_hword_list( + data[data_offset : data_offset + data_size] + ), + 0, + ) + ] + ) + + "\n" + ) + else: + r += ( + "\n".join( + [ + f"/* {data_base + j:06X} {symbol + j:08X} */ .byte 0x{byte:02X}" + for j, byte in enumerate( + data[data_offset : data_offset + data_size], 0 + ) + ] + ) + + "\n" + ) + + result.append(r) + + if len(result) > 1: + with open( + f"{DATA_OUT}/{segment_dirname}/{file['name']}.rodata.s", "w" + ) as outfile: + outfile.write("".join(result)) + + +def disassemble_bss(vram, end, info): + section_symbols = [sym for sym in symbols.values() if sym >= vram and sym < end] + section_symbols.append(vram) + section_symbols.extend([sym for sym in data_labels if sym >= vram and sym < end]) + section_symbols.extend( + [sym for sym in variables_ast.keys() if sym >= vram and sym < end] + ) + # TODO temp hack, move + section_symbols.extend( + [sym for sym in info["syms"].keys() if sym >= vram and sym < end] + ) + + # remove symbols that are addends of other symbols + section_symbols = [ + sym + for sym in section_symbols + if " + 0x" not in proper_name(sym, True) + and " - 0x" not in proper_name(sym, True) + ] + + section_symbols = list(set(section_symbols)) + + section_symbols.sort() + + # ("" if info["type"] != "overlay" else "overlays/" + segment_dirname = ( + info["name"] if info["type"] not in ("boot", "code") else info["type"] + ) + os.makedirs(f"{DATA_OUT}/{segment_dirname}/", exist_ok=True) + + if info["type"] in ("boot", "code"): + sym_list = full_file_list[info["type"]] + else: + sym_list = full_file_list[info["name"]] + + file_syms = [] + syms = [] + file_name = "" + for i, sym in enumerate(section_symbols): + if i == 0: + if info["type"] == "overlay": + file_name = info["name"] + else: + file_name = sym_list[sym] + + if sym in sym_list: + new_file = sym_list[sym] + if file_name != new_file: + file_syms.append( + {"name": file_name, "first_sym": syms[0], "syms": syms} + ) + syms = [] + file_name = new_file + syms.append(sym) + if len(syms) > 0: + file_syms.append({"name": file_name, "first_sym": syms[0], "syms": syms}) + + for i, file in enumerate(file_syms): + if file["first_sym"] not in info["syms"]: + continue + + result = [asm_header(".bss")] + + for x, symbol in enumerate(file["syms"]): + if symbol >= end: + break + if x + 1 < len(file["syms"]): + next_symbol = file["syms"][x + 1] + elif i + 1 < len(file_syms): + next_symbol = file_syms[i + 1]["first_sym"] + else: + next_symbol = end + + result.append(f"\nglabel {proper_name(symbol, True)}\n") + result.append( + f"/* {symbol - vram:06X} {symbol:08X} */ .space 0x{next_symbol - symbol:X}\n" + ) + + if len(result) > 1: + with open( + f"{DATA_OUT}/{segment_dirname}/{file['name']}.bss.s", "w" + ) as outfile: + outfile.write("".join(result)) + def get_overlay_sections(vram, overlay): header_loc = len(overlay) - as_word_list(overlay)[-1] - text_size, data_size, rodata_size, bss_size, n_relocs = as_word_list(overlay[header_loc:header_loc + 0x14]) + text_size, data_size, rodata_size, bss_size, n_relocs = as_word_list( + overlay[header_loc : header_loc + 0x14] + ) text_vram = vram data_vram = vram + text_size rodata_vram = data_vram + data_size @@ -1084,153 +1864,66 @@ def get_overlay_sections(vram, overlay): bss_vram = vram + len(overlay) bss_end_vram = bss_vram + bss_size - reloc = as_word_list(overlay[header_loc + 0x14: header_loc + 0x14 + n_relocs * 4]) - reloc = [((rel >> 30) & ((1 << 2) - 1), (rel >> 24) & ((1 << 6) - 1), (rel) & ((1 << 24) - 1)) for rel in reloc] + reloc = as_word_list(overlay[header_loc + 0x14 : header_loc + 0x14 + n_relocs * 4]) + reloc = [ + ( + (rel >> 30) & ((1 << 2) - 1), + (rel >> 24) & ((1 << 6) - 1), + (rel) & ((1 << 24) - 1), + ) + for rel in reloc + ] rel_text = [r for r in reloc if r[0] == 1] rel_data = [r for r in reloc if r[0] == 2] rel_rodata = [r for r in reloc if r[0] == 3] rel_bss = [r for r in reloc if r[0] == 4] - return [[text_vram, data_vram, 'text', None, overlay[0:text_size], rel_text], \ - [data_vram, rodata_vram, 'data', None, overlay[text_size:text_size+data_size], rel_data], \ - [rodata_vram, bss_vram, 'rodata', None, overlay[text_size+data_size:text_size+data_size+rodata_size], rel_rodata], \ - [bss_vram, bss_end_vram, 'bss', None, None, rel_bss], \ - [bss_end_vram, bss_end_vram, 'reloc', None, overlay[header_loc:], None]] + return [ + [text_vram, data_vram, "text", None, overlay[0:text_size], rel_text], + [ + data_vram, + rodata_vram, + "data", + None, + overlay[text_size : text_size + data_size], + rel_data, + ], + [ + rodata_vram, + bss_vram, + "rodata", + None, + overlay[text_size + data_size : text_size + data_size + rodata_size], + rel_rodata, + ], + [bss_vram, bss_end_vram, "bss", None, None, rel_bss], + [bss_end_vram, bss_end_vram, "reloc", None, overlay[header_loc:], None], + ] -# -print("Setting Up") - -files_spec = None -with open("tools/disasm/files.txt", "r") as infile: - files_spec = ast.literal_eval(infile.read()) - -with open("tools/disasm/functions.txt", "r") as infile: - functions_ast = ast.literal_eval(infile.read()) - -with open("tools/disasm/variables.txt", "r") as infile: - variables_ast = ast.literal_eval(infile.read()) - -# Precompute variable addends for all variables, this uses a lot of memory but the lookups later are fast -for var in sorted(variables_ast.keys()): - for i in range(var, var + variables_ast[var][3], 1): - addend = i - var - assert addend >= 0 - vars_cache.update({i : f"{variables_ast[var][0]}" + (f" + 0x{addend:X}" if addend > 0 else "")}) - # also add to floats, doubles & strings - var_type = variables_ast[var][1] - - if var_type == "f64": - doubles.add(var) - elif var_type == "f32": - floats.add(var) - elif var_type == "char" and variables_ast[var][2].startswith("["): - strings.add(var) - -# Read in binary and relocation data for each segment -for segment in files_spec: - binary = None - with open(segment[1] + "/" + segment[0],"rb") as infile: - binary = bytes(infile.read()) - - if segment[2] == "overlay": - segment_start = list(segment[4])[0] # start addr of first file in segment - segment[3] = get_overlay_sections(segment_start, binary) - segment[4] = {} - for section in segment[3]: - segment[4].update({ section[0] : segment[0] }) - else: - segment_start = segment[3][0][0] # start addr of first section of segment's sections - # read section binary regions - for section in segment[3]: - if section[2] == 'bss': - continue - section.append(binary[section[0] - segment_start:section[1] - segment_start]) # section[4] - section.append(None) # section[5] - -print(f"Finding Symbols") - -for segment in files_spec: - if segment[2] == 'makerom': - continue - - print(f"Finding segment positions in {segment[0]}") - - # vram segment start - if segment[3][0][0] not in variables_ast: - variables_ast.update({segment[3][0][0] : (f"_{segment[0]}SegmentStart","u8","[]",0x1)}) - # vram segment end - if segment[3][-1][1] not in variables_ast: - variables_ast.update({segment[3][-1][1] : (f"_{segment[0]}SegmentEnd","u8","[]",0x1)}) - -pool = Pool(jobs) -# Find symbols for each segment -for segment in files_spec: - if segment[2] == 'makerom': - continue - - #print(f"Finding symbols from .text and .data in {segment[0]}") - - for section in segment[3]: - if section[2] == 'text': - data_regions = [] - if section[3] is not None: - for override_region in section[3]: - if override_region[2] == 'data': - data_regions.append((override_region[0], override_region[1])) - # try find a rodata section - for find_section in segment[3]: - if find_section[2] == 'rodata' and find_section[1] != find_section[0]: - rodata_section = find_section - break - else: - rodata_section = None - pool.apply_async(find_symbols_in_text, args=(section[4], rodata_section[4] if rodata_section is not None else None, - section[0], rodata_section[0] if rodata_section is not None else None, data_regions, section[5], segment[0]), callback=update_symbols_from_dict) - elif section[2] == 'data': - pool.apply_async(find_symbols_in_data, args=(section[4], section[0], section[1], section[5], segment[0]), callback=update_symbols_from_dict) - -pool.close() -pool.join() - -for segment in files_spec: - if segment[2] == 'makerom': - continue - - print(f"Finding symbols from .rodata and .dmadata in {segment[0]}") - - for section in segment[3]: - if section[2] == 'rodata': - find_symbols_in_rodata(section[4], section[0], section[1], section[5], segment) - elif section[2] == 'dmadata': - filenames = [] - with open("tools/disasm/dma_filenames.txt","r") as infile: - filenames = ast.literal_eval(infile.read()) - - dmadata = segment[3][0][4] - i = 0 - dmadata_entry = dmadata[i*0x10:(i+1)*0x10] - while any([word != 0 for word in as_word_list(dmadata_entry)]): - vrom_start,vrom_end,prom_start,prom_end = as_word_list(dmadata_entry) - # print(f"{vrom_start:08X},{vrom_end:08X},{prom_start:08X},{prom_end:08X} : {filenames[i]}") - vrom_variables.append(("_" + filenames[i] + "SegmentRomStart", vrom_start)) - vrom_variables.append(("_" + filenames[i] + "SegmentRomEnd", vrom_end)) - i += 1 - dmadata_entry = dmadata[i*0x10:(i+1)*0x10] - -def disassemble_makerom(segment): +def disassemble_makerom(section): os.makedirs(f"{ASM_OUT}/makerom/", exist_ok=True) - rom_header = segment[3][0][4] - ipl3 = segment[3][1][4] - entry = segment[3][2][4] - pi_dom1_reg, clockrate, entrypoint, revision, \ - chksum1, chksum2, pad1, pad2, \ - rom_name, pad3, cart, cart_id, \ - region, version = struct.unpack(">IIIIIIII20sII2s1sB", rom_header) + if section[2] == "rom_header": + ( + pi_dom1_reg, + clockrate, + entrypoint, + revision, + chksum1, + chksum2, + pad1, + pad2, + rom_name, + pad3, + cart, + cart_id, + region, + version, + ) = struct.unpack(">IIIIIIII20sII2s1sB", section[4]) - out = f"""/* + out = f"""/* * The Legend of Zelda: Majora's Mask ROM header */ @@ -1249,49 +1942,51 @@ def disassemble_makerom(segment): .ascii "{region.decode('ascii')}" /* Region */ .byte 0x{version:02X} /* Version */ """ - with open(ASM_OUT + "/makerom/rom_header.s", "w") as outfile: - outfile.write(out) + with open(ASM_OUT + "/makerom/rom_header.s", "w") as outfile: + outfile.write(out) - # TODO disassemble this eventually, low priority - out = f"{asm_header('.text')}\n.incbin \"baserom/makerom\", 0x40, 0xFC0\n" + elif section[-1]["type"] == "ipl3": + # TODO disassemble this eventually, low priority + out = f"{asm_header('.text')}\n.incbin \"baserom/makerom\", 0x40, 0xFC0\n" - with open(ASM_OUT + "/makerom/ipl3.s", "w") as outfile: - outfile.write(out) + with open(ASM_OUT + "/makerom/ipl3.s", "w") as outfile: + outfile.write(out) - # hack: add symbol relocations manually - entry_addr = 0x80080000 + elif section[-1]["type"] == "entry": + # hack: add symbol relocations manually + entry_addr = 0x80080000 - functions.add(entry_addr) - symbols.update({entry_addr + 0x00 : 0x80099500, - entry_addr + 0x04 : 0x80099500, - entry_addr + 0x20 : 0x80080060, - entry_addr + 0x24 : 0x80099EF0, - entry_addr + 0x28 : 0x80080060, - entry_addr + 0x30 : 0x80099EF0}) - branch_labels.add(entry_addr + 0xC) + functions.add(entry_addr) + symbols.update( + { + entry_addr + 0x00: 0x80099500, + entry_addr + 0x04: 0x80099500, + entry_addr + 0x20: 0x80080060, + entry_addr + 0x24: 0x80099EF0, + entry_addr + 0x28: 0x80080060, + entry_addr + 0x30: 0x80099EF0, + } + ) + branch_labels.add(entry_addr + 0xC) + disassemble_text(section[4], entry_addr, [], section[-1]) - disassemble_text(entry, entry_addr, [], segment) + # manually set boot bss size... + entry_asm = "" + with open(f"{ASM_OUT}/makerom/entry.text.s") as infile: + entry_asm = infile.read() - # manually set boot bss size... - entry_asm = "" - with open(f"{ASM_OUT}/makerom/entry.text.s") as infile: - entry_asm = infile.read() + entry_asm = entry_asm.replace("0x63b0", "%lo(_bootSegmentBssSize)") + with open(f"{ASM_OUT}/makerom/entry.s", "w") as outfile: + outfile.write(entry_asm) - entry_asm = entry_asm.replace("0x63b0", "%lo(_bootSegmentBssSize)") - with open(f"{ASM_OUT}/makerom/entry.s", "w") as outfile: - outfile.write(entry_asm) + os.remove(f"{ASM_OUT}/makerom/entry.text.s") - os.remove(f"{ASM_OUT}/makerom/entry.text.s") - #out = f"{asm_header('.text')}\n.incbin \"baserom/makerom\", 0x1000, 0x60\n" - - #with open(ASM_OUT + "/makerom/entry.s", "w") as outfile: - # outfile.write(out) - -def disassemble_segment(segment): - if segment[2] == 'dmadata': - os.makedirs(f"{ASM_OUT}/dmadata/", exist_ok=True) - out = f""".include "macro.inc" +def disassemble_dmadata(section): + if section[2] == "bss": + return + os.makedirs(f"{ASM_OUT}/dmadata/", exist_ok=True) + out = f""".include "macro.inc" .macro DMA_TABLE_ENTRY segment .4byte _\segment\()SegmentRomStart @@ -1309,137 +2004,132 @@ def disassemble_segment(segment): glabel {variables_ast[0x8009F8B0][0]} """ - filenames = [] - with open("tools/disasm/dma_filenames.txt","r") as infile: - filenames = ast.literal_eval(infile.read()) + filenames = [] + with open("tools/disasm/dma_filenames.txt", "r") as infile: + filenames = ast.literal_eval(infile.read()) - dmadata = segment[3][0][4] - i = 0 - dmadata_entry = dmadata[i*0x10:(i+1)*0x10] - while any([word != 0 for word in as_word_list(dmadata_entry)]): - vrom_start,vrom_end,prom_start,prom_end = as_word_list(dmadata_entry) - if prom_start == 0xFFFFFFFF and prom_end == 0xFFFFFFFF: - out += f"DMA_TABLE_ENTRY_UNSET {filenames[i]}\n" - else: - out += f"DMA_TABLE_ENTRY {filenames[i]}\n" - i += 1 - dmadata_entry = dmadata[i*0x10:(i+1)*0x10] + dmadata = section[4] + i = 0 + dmadata_entry = dmadata[i * 0x10 : (i + 1) * 0x10] + while any([word != 0 for word in as_word_list(dmadata_entry)]): + vrom_start, vrom_end, prom_start, prom_end = as_word_list(dmadata_entry) + if prom_start == 0xFFFFFFFF and prom_end == 0xFFFFFFFF: + out += f"DMA_TABLE_ENTRY_UNSET {filenames[i]}\n" + else: + out += f"DMA_TABLE_ENTRY {filenames[i]}\n" - out += """ + vrom_variables.append(("_" + filenames[i] + "SegmentRomStart", vrom_start)) + vrom_variables.append(("_" + filenames[i] + "SegmentRomEnd", vrom_end)) + + i += 1 + dmadata_entry = dmadata[i * 0x10 : (i + 1) * 0x10] + + out += """ .space 0x100 .section .bss .space 0x10 """ - with open(ASM_OUT + "/dmadata/dmadata.s", "w") as outfile: - outfile.write(out) + with open(ASM_OUT + "/dmadata/dmadata.s", "w") as outfile: + outfile.write(out) + + +def disassemble_segment(section): + if section[-1]["name"] == "[PADDING]": return - for section in segment[3]: - if (section[0] == section[1] and section[2] != 'reloc') or (section[2] != 'bss' and len(section[4]) == 0): - continue - print(f"Disassembling {segment[0]} .{section[2]}") - if section[2] == 'text': - data_regions = [] - if section[3] is not None: - for override_region in section[3]: - if override_region[2] == 'data': - data_regions.append((override_region[0], override_region[1])) + print(f"Disassembling {section[-1]['name']} .{section[2]}") - disassemble_text(section[4], section[0], data_regions, segment) - elif section[2] == 'data': - disassemble_data(section[4], section[0], section[1], segment) - elif section[2] == 'rodata': - disassemble_rodata(section[4], section[0], section[1], segment) - elif section[2] == 'bss': - disassemble_bss(section[0], section[1], segment) - elif section[2] == 'reloc': - words = as_word_list(section[4]) + if section[2] == "text": + fixup_text_symbols(section[4], section[0], data_regions, section[-1]) + elif section[2] == "data": + disassemble_data(section[4], section[0], section[1], section[-1]) + elif section[2] == "rodata": + disassemble_rodata(section[4], section[0], section[1], section[-1]) + elif section[2] == "bss": + disassemble_bss(section[0], section[1], section[-1]) + elif section[2] == "reloc": + words = as_word_list(section[4]) - # ("" if segment[2] != "overlay" else "overlays/") + - segment_dirname = segment[0] + segment_dirname = section[-1]["name"] - result = asm_header(".rodata") - result += f"\nglabel {segment[0]}_Reloc\n" + result = asm_header(".rodata") + result += f"\nglabel {section[-1]['name']}_Reloc\n" - lines = [words[i*8:(i+1)*8] for i in range(0, (len(words) // 8) + 1)] - for line in [line for line in lines if len(line) != 0]: - result += f" .word {', '.join([f'0x{word:08X}' for word in line])}\n" + lines = [words[i * 8 : (i + 1) * 8] for i in range(0, (len(words) // 8) + 1)] + for line in [line for line in lines if len(line) != 0]: + result += f" .word {', '.join([f'0x{word:08X}' for word in line])}\n" - os.makedirs(f"{DATA_OUT}/{segment_dirname}/", exist_ok=True) - with open(f"{DATA_OUT}/{segment_dirname}/{segment[0]}.reloc.s", "w") as outfile: - outfile.write(result) + os.makedirs(f"{DATA_OUT}/{segment_dirname}/", exist_ok=True) + with open( + f"{DATA_OUT}/{segment_dirname}/{section[-1]['name']}.reloc.s", "w" + ) as outfile: + outfile.write(result) -print("Disassembling Segments") - -disassemble_makerom(next(segment for segment in files_spec if segment[2] == 'makerom')) - -# Textual disassembly for each segment -with Pool(jobs) as p: - p.map(disassemble_segment, (segment for segment in files_spec if segment[2] != 'makerom')) - -print("Splitting text and migrating rodata") - -func_regex = re.compile(r'\n\nglabel \S+\n') -rodata_symbols_regex = re.compile(r'(?<=\n)glabel (.+)(?=\n)') -asm_symbols_regex = re.compile(r'%(?:lo|hi)\((.+?)\)') def rodata_block_size(block): def align(x, n): - while (x % n != 0): + while x % n != 0: x += 1 return x accumulator = 0 - for part in block.split(' */ .'): + for part in block.split(" */ ."): part = part.strip() - if part.startswith('# '): + if part.startswith("# "): continue - elif part.startswith('asciz '): - part = part[len('asciz '):] - string = part[1:-1].encode('utf-8', 'ignore').decode('unicode_escape') - accumulator += len(string.encode('euc-jp') + b'\x00') - elif part.startswith('ascii'): - part = part[len('ascii '):] - string = part[1:-1].encode('utf-8', 'ignore').decode('unicode_escape') - accumulator += len(string.encode('euc-jp')) - elif part.startswith('balign '): - part = part[len('balign '):] - accumulator = align(accumulator, int(part, 16 if part.startswith('0x') else 10)) - elif part.startswith('double '): - part = part[len('double '):] + elif part.startswith("asciz "): + part = part[len("asciz ") :] + string = part[1:-1].encode("utf-8", "ignore").decode("unicode_escape") + accumulator += len(string.encode("euc-jp") + b"\x00") + elif part.startswith("ascii"): + part = part[len("ascii ") :] + string = part[1:-1].encode("utf-8", "ignore").decode("unicode_escape") + accumulator += len(string.encode("euc-jp")) + elif part.startswith("balign "): + part = part[len("balign ") :] + accumulator = align( + accumulator, int(part, 16 if part.startswith("0x") else 10) + ) + elif part.startswith("double "): + part = part[len("double ") :] accumulator = align(accumulator, 8) - accumulator += 8 * (part.count(',') + 1) - elif part.startswith('float '): - part = part[len('float '):] + accumulator += 8 * (part.count(",") + 1) + elif part.startswith("float "): + part = part[len("float ") :] accumulator = align(accumulator, 4) - accumulator += 4 * (part.count(',') + 1) - elif part.startswith('word '): - part = part[len('word '):] + accumulator += 4 * (part.count(",") + 1) + elif part.startswith("word "): + part = part[len("word ") :] accumulator = align(accumulator, 4) - accumulator += 4 * (part.count(',') + 1) - elif part.startswith('half '): - part = part[len('half '):] + accumulator += 4 * (part.count(",") + 1) + elif part.startswith("half "): + part = part[len("half ") :] accumulator = align(accumulator, 2) - accumulator += 2 * (part.count(',') + 1) - elif part.startswith('byte '): - part = part[len('byte '):] - accumulator += 1 * (part.count(',') + 1) + accumulator += 2 * (part.count(",") + 1) + elif part.startswith("byte "): + part = part[len("byte ") :] + accumulator += 1 * (part.count(",") + 1) return accumulator + def late_rodata_size(blocks): return sum([rodata_block_size(block) for block in blocks]) + def text_block_size(asm): - return 4*len([line for line in asm.split("\n") if line.startswith("/*")]) + return 4 * len([line for line in asm.split("\n") if line.startswith("/*")]) + def rodata_syms(rodata): return re.findall(rodata_symbols_regex, rodata) + def rodata_blocks(rodata): return ["glabel" + b for b in rodata.split("glabel")[1:]] + def find_late_rodata_start(rodata): """ Returns the symbol that is the first late_rodata symbol, or None if there is no late_rodata @@ -1451,7 +2141,7 @@ def find_late_rodata_start(rodata): """ first = None - for sym,body in rodata: + for sym, body in rodata: if sym.startswith("jtbl_") and ".word L" in body: # jump tables are always late_rodata, so we can return early # floats and doubles are very rarely not late_rodata, this is mostly seen in libultra, so we cannot return early for those @@ -1463,25 +2153,281 @@ def find_late_rodata_start(rodata): # may be late_rodata, but we aren't sure yet # it is confirmed either by reaching the end or by finding a jumptable, and it is proven wrong if something that is not late_rodata occurs after it first = sym - elif (".asciz" in body or (".word " in body and ".float" not in body) or ".half " in body or ".byte " in body) and first is not None: + elif ( + ".asciz" in body + or (".word " in body and ".float" not in body) + or ".half " in body + or ".byte " in body + ) and first is not None: # reset first if something that is definitely not late_rodata is found # word and not float is due to some floats needing to be output as words either due to being a specific NaN value, or GAS can't convert it properly first = None # May still be None at this point, that just means there is no late_rodata return first + +# ==========================================# + +print("Setting Up") + +files_spec = None +with open("tools/disasm/files.txt", "r") as infile: + files_spec = ast.literal_eval(infile.read()) + +with open("tools/disasm/functions.txt", "r") as infile: + functions_ast = ast.literal_eval(infile.read()) + +with open("tools/disasm/variables.txt", "r") as infile: + variables_ast = ast.literal_eval(infile.read()) + +# We need to keep a full list of original file offsets to know where to split files later +full_file_list = {} +for segment in files_spec: + new = {} + for offset, name in segment[4].items(): + if name == "": + name = f"{segment[2]}_{offset:08X}" + new[offset] = name + full_file_list[segment[0]] = new + +if args.full: + for segment in files_spec: + for offset, name in segment[4].items(): + if name == "": + name = f"{segment[2]}_{offset:08X}" + segment[4][offset] = name +else: + # Prune + old_file_count = sum([len(f[4].keys()) for f in files_spec]) + + files_spec = discard_decomped_files(files_spec) + + new_file_count = sum([len(f[4].keys()) for f in files_spec]) + + pruned = old_file_count - new_file_count + print(f"Pruned {pruned}/{old_file_count} files ({pruned / old_file_count:.02%})") + +# Find floats, doubles, and strings +for var in sorted(variables_ast.keys()): + var_type = variables_ast[var][1] + + if var_type == "f64": + doubles.add(var) + elif var_type == "f32": + floats.add(var) + elif var_type == "char" and variables_ast[var][2].startswith("["): + strings.add(var) + +# Read in binary and relocation data for each segment +for seg, segment in enumerate(files_spec): + binary = None + with open(segment[1] + "/" + segment[0], "rb") as infile: + binary = bytes(infile.read()) + + if segment[2] == "overlay": + segment_start = list(segment[4])[0] # start addr of first file in segment + segment[3] = get_overlay_sections(segment_start, binary) + segment[4] = {} + for section in segment[3]: + segment[4].update({section[0]: segment[0]}) + else: + # start addr of first section of segment's sections + segment_start = segment[3][0][0] + # read section binary regions + for i, section in enumerate(segment[3]): + if section[2] == "bss": + continue + # section[4] + section.append( + binary[section[0] - segment_start : section[1] - segment_start] + ) + section.append(None) # section[5] + +print(f"Finding segment positions") + +for segment in files_spec: + if segment[2] == "makerom": + continue + + print(f"Finding segment positions in {segment[0]}") + + # vram segment start + if segment[3][0][0] not in variables_ast: + variables_ast.update( + {segment[3][0][0]: (f"_{segment[0]}SegmentStart", "u8", "[]", 0x1)} + ) + # vram segment end + if segment[3][-2][1] not in variables_ast: + variables_ast.update( + {segment[3][-2][1]: (f"_{segment[0]}SegmentEnd", "u8", "[]", 0x1)} + ) + +# Construct variable_addrs, now that variable_addrs is fully constructed +variable_addrs = sorted(variables_ast.keys()) + +# Flatten out files_spec so we can process everything evenly +# Otherwise the entire code and boot sections are done by a single thread +all_sections = [] +for segment in files_spec: + if segment[0] == "boot" or segment[0] == "code": + file_list = list(full_file_list[segment[0]]) + section_starts = [x[0] for x in segment[3]] + + for off, name in segment[4].items(): + # loop over the vram starts for this segment's sections to find where it belongs (text, data, etc) + for i, s in enumerate(section_starts): + if off < s: + break + else: + i = len(section_starts) + i -= 1 + + # Calculate the offset and size of this section relative to the section + data_offset = off - segment[3][i][0] + full_index = file_list.index(off) + if segment[0] == "code" and name == "buffers" and segment[3][i][2] == "bss": + # This is the end of code, hardcode it + data_size = 0x80800000 - file_list[full_index] + elif segment[0] == "boot" and name == "vimgr" and segment[3][i][2] == "bss": + # This is the end of boot, hardcode it + data_size = 0x800A5AC0 - file_list[full_index] + else: + data_size = file_list[full_index + 1] - file_list[full_index] + + # Create the section entry for this file + new_entry = [ + off, + off + data_size, + segment[3][i][2], + None, + segment[3][i][4][data_offset : data_offset + data_size] + if segment[3][i][2] not in ("bss") + else None, + None if segment[3][i][2] in ["text", "reloc", "data"] else [], + { + "name": name, + "type": segment[2], + "base": segment[3][0][0], + "syms": { + x: name for x in segment[4] if x >= off and x < off + data_size + }, + }, + ] + + all_sections.append(new_entry) + + # I don't remember what this is for but it's still needed + for i, entry in enumerate(segment[3]): + if segment[0] == "makerom" and i == 1: + segment[2] = "ipl3" + elif segment[0] == "makerom" and i == 2: + segment[2] = "entry" + entry.append( + { + "name": segment[0], + "type": segment[2], + "base": segment[3][0][0], + "syms": segment[4], + } + ) + + all_sections.extend(segment[3]) + +del files_spec[:] + +pool = get_context("fork").Pool(jobs) +# Find symbols for each segment +for section in all_sections: + if section[-1]["name"] == "makerom": + continue + + if section[2] == "text": + data_regions = [] + if section[3] is not None: + for override_region in section[3]: + if override_region[2] == "data": + data_regions.append((override_region[0], override_region[1])) + # try find a rodata section + for s in all_sections: + if ( + s[-1]["name"] == section[-1]["name"] + and s[2] == "rodata" + and s[0] != s[1] + ): + rodata_section = s + break + else: + rodata_section = None + pool.apply_async( + find_symbols_in_text, + args=(section, rodata_section if rodata_section else None, data_regions), + callback=update_symbols_from_dict, + ) + elif section[2] == "data": + pool.apply_async( + find_symbols_in_data, args=(section), callback=update_symbols_from_dict + ) + +pool.close() +pool.join() + +pool = get_context("fork").Pool(jobs) +for section in all_sections: + if section[-1]["type"] == "makerom": + continue + + if section[2] == "rodata": + pool.apply_async( + find_symbols_in_rodata, args=(section), callback=update_symbols_from_dict + ) + +pool.close() +pool.join() + +for section in all_sections: + if section[-1]["name"] == "makerom": + print(f"Disassembling makerom") + disassemble_makerom(section) + elif section[-1]["name"] == "dmadata": + print(f"Disassembling dmadata") + disassemble_dmadata(section) + +# Construct vrom_addrs, now that vrom_variables is fully constructed +vrom_addrs = {addr for _, addr in vrom_variables} + +# Textual disassembly for each segment +with get_context("fork").Pool(jobs) as p: + p.map( + disassemble_segment, + [ + sec + for sec in all_sections + if sec[-1]["name"] not in ("boot", "code", "makerom", "dmadata") + ], + ) + +print("Splitting text and migrating rodata") + +func_regex = re.compile(r"\n\nglabel \S+\n") +rodata_symbols_regex = re.compile(r"(?<=\n)glabel (.+)(?=\n)") +asm_symbols_regex = re.compile(r"%(?:lo|hi)\((.+?)\)") + # Split files and migrate rodata that should be migrated -for root,dirs,files in os.walk(ASM_OUT): +for root, dirs, files in os.walk(ASM_OUT): for f in files: if "non_matchings" in root: continue - asm_path = os.path.join(root,f) - rodata_path = asm_path.replace(ASM_OUT + "overlays/", DATA_OUT).replace(ASM_OUT, DATA_OUT).replace(".text.s", ".rodata.s") + asm_path = os.path.join(root, f) + rodata_path = ( + asm_path.replace(ASM_OUT + "overlays/", DATA_OUT) + .replace(ASM_OUT, DATA_OUT) + .replace(".text.s", ".rodata.s") + ) print(asm_path) asm = "" - with open(asm_path,"r") as infile: + with open(asm_path, "r") as infile: asm = infile.read() rodata = "" @@ -1496,15 +2442,21 @@ for root,dirs,files in os.walk(ASM_OUT): first_late_rodata = find_late_rodata_start(rodata_info) rdata_info = [] late_rodata_info = [] - target = rdata_info # first populate rdata - for sym,block in rodata_info: - if sym == first_late_rodata: # now populate late_rodata, if there is any + target = rdata_info # first populate rdata + for sym, block in rodata_info: + # now populate late_rodata, if there is any + if sym == first_late_rodata: target = late_rodata_info - target.append((sym,block)) + target.append((sym, block)) # print([(sym,block.split("\n")[1:]) for sym,block in zip(rdata_syms,rdata_blocks)]) - function_info = list(zip([s.replace("glabel","").strip() for s in func_regex.findall(asm)], func_regex.split(asm)[1:])) + function_info = list( + zip( + [s.replace("glabel", "").strip() for s in func_regex.findall(asm)], + func_regex.split(asm)[1:], + ) + ) rdata_map = {} late_rodata_map = {} @@ -1513,18 +2465,20 @@ for root,dirs,files in os.walk(ASM_OUT): if rodata != "": last_fn = None - referenced_in = {} # key=rodata label , value=function label + referenced_in = {} # key=rodata label , value=function label - for sym,_ in rodata_info: - all_refs = [label for label,body in function_info if "%lo(" + sym + ")" in body] + for sym, _ in rodata_info: + all_refs = [ + label for label, body in function_info if "%lo(" + sym + ")" in body + ] # ignore multiple refs, take only the first - referenced_in.update({ sym : all_refs[0] if len(all_refs) != 0 else None }) + referenced_in.update({sym: all_refs[0] if len(all_refs) != 0 else None}) def do_splits(out_dict, info): first = True last_ref = None cr = None - for sym,block in info: + for sym, block in info: ref = referenced_in[sym] if first: cr = ref or sym @@ -1536,11 +2490,11 @@ for root,dirs,files in os.walk(ASM_OUT): elif last_ref is not None: # new GLOBAL_ASM cr = sym - + # add to output if cr not in out_dict.keys(): - out_dict.update({cr : []}) - out_dict[cr].append((sym,block)) + out_dict.update({cr: []}) + out_dict[cr].append((sym, block)) # setup next iter last_ref = ref @@ -1550,7 +2504,9 @@ for root,dirs,files in os.walk(ASM_OUT): do_splits(late_rodata_map, late_rodata_info) # all output files, order is irrelevant at this point - all_output = set([label for label,_ in function_info]).union(set(rdata_map.keys()),set(late_rodata_map.keys())) + all_output = set([label for label, _ in function_info]).union( + set(rdata_map.keys()), set(late_rodata_map.keys()) + ) # pass 2 to output splits for label in all_output: @@ -1558,7 +2514,7 @@ for root,dirs,files in os.walk(ASM_OUT): text_out = "" rodata_out = "" - + if fn_body is not None: text_out = "glabel " + label.strip() + "\n" + fn_body.strip() + "\n" @@ -1569,43 +2525,81 @@ for root,dirs,files in os.walk(ASM_OUT): # check for late_rodata_alignment late_rodata_alignment = "" if fn_body is not None and late_rodata is not None: - ratio = late_rodata_size([block for _,block in late_rodata]) / text_block_size(fn_body) - if ratio > 1./3: + ratio = late_rodata_size( + [block for _, block in late_rodata] + ) / text_block_size(fn_body) + if ratio > 1.0 / 3: # print(f"{label} : {ratio}") # TODO hack: getting the address from a comment first_block_split = late_rodata[0][1].split(" */ .") vaddr = None - if first_block_split[1].startswith("float") or first_block_split[1].startswith("double"): + if first_block_split[1].startswith( + "float" + ) or first_block_split[1].startswith("double"): vaddr = first_block_split[0].split(" ")[-2] else: vaddr = first_block_split[0].split(" ")[-1] assert vaddr is not None - vaddr = int(vaddr,16) - if vaddr not in [0x801E0E28, 0x80C1C2B0, 0x80AA7820, 0x80AA3CC0, - 0x80AA418C, 0x80BE0160, 0x80B591D8, 0x80B59610, - 0x80B59780, 0x80964E00, 0x80964F10, 0x80BB40A0, - 0x80952038, 0x80AFB920, 0x80AFBBFC, 0x80AFBE28, - 0x80983320]: # hacks for especially badly behaved rodata, TODO these are ALL jumptables associated with - # comparatively tiny functions, can we swat these programmatically? + vaddr = int(vaddr, 16) + if vaddr not in [ + 0x801E0E28, + 0x80C1C2B0, + 0x80AA7820, + 0x80AA3CC0, + 0x80AA418C, + 0x80BE0160, + 0x80B591D8, + 0x80B59610, + 0x80B59780, + 0x80964E00, + 0x80964F10, + 0x80BB40A0, + 0x80952038, + 0x80AFB920, + 0x80AFBBFC, + 0x80AFBE28, + 0x80983320, + ]: + # hacks for especially badly behaved rodata, TODO these are ALL jumptables associated with + # comparatively tiny functions, can we swat these programmatically? late_rodata_alignment = f".late_rodata_alignment {'8' if vaddr % 8 == 0 else '4'}\n" rdata_out = "" if rdata is not None: - rdata_out = ".rdata\n" + "".join([block for _,block in rdata]) + rdata_out = ".rdata\n" + "".join([block for _, block in rdata]) late_rodata_out = "" if late_rodata is not None: - late_rodata_out = ".late_rodata\n" + late_rodata_alignment + "".join([block for _,block in late_rodata]) + late_rodata_out = ( + ".late_rodata\n" + + late_rodata_alignment + + "".join([block for _, block in late_rodata]) + ) - rodata_out = rdata_out + late_rodata_out + ("\n.text\n" if ((rdata is not None or late_rodata is not None) and fn_body is not None) else "") + rodata_out = ( + rdata_out + + late_rodata_out + + ( + "\n.text\n" + if ( + (rdata is not None or late_rodata is not None) + and fn_body is not None + ) + else "" + ) + ) all_out = rodata_out + text_out # write it out - out_path = root.replace(ASM_OUT, f"{ASM_OUT}/non_matchings/") + "/" + ((f.replace(".text.s","") + "/") if "overlays" not in root else "") + out_path = ( + root.replace(ASM_OUT, f"{ASM_OUT}/non_matchings/") + + "/" + + ((f.replace(".text.s", "") + "/") if "overlays" not in root else "") + ) os.makedirs(out_path, exist_ok=True) with open(out_path + label + ".s", "w") as outfile: outfile.write(all_out.strip() + "\n") - + # remove rodata and unsplit file # TODO diff --git a/tools/disasm/dma_filenames.txt b/tools/disasm/dma_filenames.txt index ecd43c82b..e9a743615 100644 --- a/tools/disasm/dma_filenames.txt +++ b/tools/disasm/dma_filenames.txt @@ -37,7 +37,7 @@ 'ovl_file_choose', 'ovl_daytelop', 'ovl_kaleido_scope', - 'ovl_Player_Actor', + 'ovl_player_actor', 'ovl_En_Test', 'ovl_En_GirlA', 'ovl_En_Part', diff --git a/tools/disasm/files.txt b/tools/disasm/files.txt index 86f3f7f74..04e4a5f39 100644 --- a/tools/disasm/files.txt +++ b/tools/disasm/files.txt @@ -380,7 +380,7 @@ 0x800EFE60 : "z_eff_footmark", 0x800F0390 : "code_800F0390", 0x800F05C0 : "z_elf_message", - 0x800F07C0 : "code_800F07C0", + 0x800F07C0 : "z_en_hy", 0x800F1250 : "z_face_reaction", 0x800F12D0 : "z_env_flags", 0x800F1460 : "z_eventmgr", @@ -483,7 +483,7 @@ 0x8018B0F0 : "audio_heap", 0x8018EB60 : "audio_load", 0x80192BE0 : "code_80192BE0", - 0x80194710 : "code_80194710", + 0x80194710 : "audio_dcache", 0x80194790 : "code_80194790", 0x80194930 : "audio_playback", 0x80196A00 : "audio_effects", @@ -511,6 +511,7 @@ 0x801AE330 : "", 0x801AE3A0 : "z_effect_soft_sprite", 0x801AE3B0 : "z_effect_soft_sprite_old_init", + 0x801AE4A0 : "z_effect_soft_sprite_dlftbls", 0x801AE8F0 : "flg_set_table", 0x801AEC70 : "flg_set", 0x801AEC80 : "z_actor", @@ -556,8 +557,7 @@ 0x801C5D10 : "z_sub_s", 0x801C5DD0 : "z_vimode", 0x801C5E30 : "z_vr_box", - 0x801C5FC0 : "z_vr_box_draw", - 0x801C67B0 : "z_sram_NES", + 0x801C5FC0 : "z_sram_NES", 0x801D0470 : "z_message_nes", 0x801D0B50 : "", 0x801D0B70 : "z_kaleido_manager", @@ -576,6 +576,7 @@ 0x801D15B0 : "", 0x801D15D0 : "sys_math_atan", 0x801D1DE0 : "sys_matrix", + 0x801D1E60 : "sys_ucode", 0x801D1E70 : "", 0x801D2E80 : "audio_data", 0x801D5FB0 : "audio_synthesis", @@ -678,6 +679,7 @@ # .bss section 0x801E3FA0 : "code_801E3FA0", 0x801E3FB0 : "z_effect", + 0x801ED890 : "flg_set", 0x801ED8A0 : "z_actor", 0x801ED930 : "z_actor_dlftbls", 0x801ED950 : "z_bgcheck", @@ -740,7 +742,7 @@ ['ovl_file_choose', 'baserom/', 'overlay', [], { 0x80804010 : "ovl_file_choose" }], ['ovl_daytelop', 'baserom/', 'overlay', [], { 0x80814EB0 : "ovl_daytelop" }], ['ovl_kaleido_scope', 'baserom/', 'overlay', [], { 0x808160A0 : "ovl_kaleido_scope" }], - ['ovl_Player_Actor', 'baserom/', 'overlay', [], { 0x8082DA90 : "ovl_Player_Actor" }], + ['ovl_player_actor', 'baserom/', 'overlay', [], { 0x8082DA90 : "ovl_player_actor" }], ['ovl_En_Test', 'baserom/', 'overlay', [], { 0x80862B70 : "ovl_En_Test" }], ['ovl_En_GirlA', 'baserom/', 'overlay', [], { 0x80863870 : "ovl_En_GirlA" }], ['ovl_En_Part', 'baserom/', 'overlay', [], { 0x80865370 : "ovl_En_Part" }], diff --git a/tools/disasm/functions.txt b/tools/disasm/functions.txt index b54a82733..b8023a3e9 100644 --- a/tools/disasm/functions.txt +++ b/tools/disasm/functions.txt @@ -511,28 +511,28 @@ 0x800A8150:("func_800A8150",), 0x800A817C:("func_800A817C",), 0x800A81A4:("func_800A81A4",), - 0x800A81F0:("func_800A81F0",), - 0x800A8514:("func_800A8514",), - 0x800A8558:("EffectBlure_Initcommon",), + 0x800A81F0:("EffectBlure_AddVertex",), + 0x800A8514:("EffectBlure_AddSpace",), + 0x800A8558:("EffectBlure_InitElements",), 0x800A8610:("EffectBlure_Init1",), 0x800A8720:("EffectBlure_Init2",), 0x800A8854:("EffectBlure_Destroy",), 0x800A8860:("EffectBlure_Update",), - 0x800A8C78:("func_800A8C78",), - 0x800A8DE8:("func_800A8DE8",), - 0x800A92FC:("func_800A92FC",), - 0x800A9330:("func_800A9330",), - 0x800A9804:("func_800A9804",), - 0x800AA190:("func_800AA190",), - 0x800AA460:("func_800AA460",), - 0x800AA498:("func_800AA498",), - 0x800AA700:("func_800AA700",), - 0x800AABE0:("func_800AABE0",), + 0x800A8C78:("EffectBlure_UpdateFlags",), + 0x800A8DE8:("EffectBlure_GetComputedValues",), + 0x800A92FC:("EffectBlure_SetupSmooth",), + 0x800A9330:("EffectBlure_DrawElemNoInterpolation",), + 0x800A9804:("EffectBlure_DrawElemHermiteInterpolation",), + 0x800AA190:("EffectBlure_DrawSmooth",), + 0x800AA460:("EffectBlure_SetupSimple",), + 0x800AA498:("EffectBlure_SetupSimpleAlt",), + 0x800AA700:("EffectBlure_DrawSimpleVertices",), + 0x800AABE0:("EffectBlure_DrawSimple",), 0x800AB0EC:("EffectBlure_Draw",), 0x800AB5D0:("EffectShieldParticle_Init",), 0x800AB808:("EffectShieldParticle_Destroy",), 0x800AB894:("EffectShieldParticle_Update",), - 0x800AB9F8:("EffectShieldParticle_CalculateColors",), + 0x800AB9F8:("EffectShieldParticle_GetColors",), 0x800AC718:("EffectShieldParticle_Draw",), 0x800ACBF0:("EffectSpark_Init",), 0x800ACFCC:("EffectSpark_Destroy",), @@ -546,15 +546,15 @@ 0x800AE8EC:("func_800AE8EC",), 0x800AE930:("func_800AE930",), 0x800AEF44:("func_800AEF44",), - 0x800AEF70:("EffectTireMark_InitParticle",), + 0x800AEF70:("EffectTireMark_InitElement",), 0x800AEFA0:("EffectTireMark_Init",), 0x800AF044:("EffectTireMark_Destroy",), 0x800AF050:("EffectTireMark_Update",), - 0x800AF284:("EffectTireMark_InitVertices",), + 0x800AF284:("EffectTireMark_SetVertices",), 0x800AF310:("EffectTireMark_Draw",), - 0x800AF710:("Effect_GetContext",), - 0x800AF720:("Effect_GetParams",), - 0x800AF87C:("Effect_InitCommon",), + 0x800AF710:("Effect_GetGlobalCtx",), + 0x800AF720:("Effect_GetByIndex",), + 0x800AF87C:("Effect_InitStatus",), 0x800AF890:("Effect_Init",), 0x800AF960:("Effect_Add",), 0x800AFB24:("Effect_DrawAll",), @@ -1615,22 +1615,22 @@ 0x800F048C:("func_800F048C",), 0x800F0568:("Audio_PlaySoundAtPosition",), 0x800F0590:("func_800F0590",), - 0x800F05C0:("func_800F05C0",), - 0x800F07C0:("func_800F07C0",), - 0x800F0888:("func_800F0888",), - 0x800F0944:("func_800F0944",), - 0x800F09B4:("func_800F09B4",), - 0x800F0A20:("func_800F0A20",), - 0x800F0A94:("func_800F0A94",), + 0x800F05C0:("ElfMessage_GetFirstCycleHint",), + 0x800F07C0:("EnHy_ChangeAnim",), + 0x800F0888:("EnHy_FindNearestDoor",), + 0x800F0944:("EnHy_ChangeObjectAndAnim",), + 0x800F09B4:("EnHy_UpdateSkelAnime",), + 0x800F0A20:("EnHy_Blink",), + 0x800F0A94:("EnHy_Init",), 0x800F0BB4:("func_800F0BB4",), 0x800F0CE4:("func_800F0CE4",), 0x800F0DD4:("func_800F0DD4",), - 0x800F0E94:("func_800F0E94",), - 0x800F0EEC:("func_800F0EEC",), - 0x800F0F28:("func_800F0F28",), - 0x800F0FF0:("func_800F0FF0",), - 0x800F10AC:("func_800F10AC",), - 0x800F112C:("func_800F112C",), + 0x800F0E94:("EnHy_SetPointFowards",), + 0x800F0EEC:("EnHy_SetPointBackwards",), + 0x800F0F28:("EnHy_MoveForwards",), + 0x800F0FF0:("EnHy_MoveBackwards",), + 0x800F10AC:("EnHy_UpdateCollider",), + 0x800F112C:("EnHy_PlayWalkingSound",), 0x800F1250:("Text_GetFaceReaction",), 0x800F12D0:("EnvFlags_UnsetAll",), 0x800F1304:("EnvFlags_Set",), @@ -1700,8 +1700,8 @@ 0x800F470C:("Jpeg_Decode",), 0x800F4A10:("func_800F4A10",), 0x800F4C0C:("func_800F4C0C",), - 0x800F4E20:("func_800F4E20",), - 0x800F4F28:("func_800F4F28",), + 0x800F4E20:("KaleidoSetup_Init",), + 0x800F4F28:("KaleidoSetup_Destroy",), 0x800F4F40:("Font_LoadChar",), 0x800F4F54:("Font_LoadCharNES",), 0x800F4FC0:("Font_LoadMessageBoxEndIcon",), @@ -2170,8 +2170,8 @@ 0x801224E0:("Path_GetByIndex",), 0x80122524:("Path_OrientAndGetDistSq",), 0x801225CC:("Path_CopyLastPoint",), - 0x80122660:("func_80122660",), - 0x80122670:("func_80122670",), + 0x80122660:("FrameAdvance_Init",), + 0x80122670:("FrameAdvance_Update",), 0x801226E0:("func_801226E0",), 0x80122744:("func_80122744",), 0x80122760:("func_80122760",), @@ -2655,7 +2655,7 @@ 0x8013A4C4:("func_8013A4C4",), 0x8013A504:("func_8013A504",), 0x8013A530:("func_8013A530",), - 0x8013A7C0:("func_8013A7C0",), + 0x8013A7C0:("SubS_FindDoor",), 0x8013A860:("func_8013A860",), 0x8013AB00:("func_8013AB00",), 0x8013AD6C:("func_8013AD6C",), @@ -2668,7 +2668,7 @@ 0x8013B6B0:("func_8013B6B0",), 0x8013B878:("func_8013B878",), 0x8013BB34:("func_8013BB34",), - 0x8013BB7C:("func_8013BB7C",), + 0x8013BB7C:("SubS_FindNearestActor",), 0x8013BC6C:("func_8013BC6C",), 0x8013BD40:("func_8013BD40",), 0x8013BEDC:("func_8013BEDC",), @@ -2689,7 +2689,7 @@ 0x8013D83C:("func_8013D83C",), 0x8013D8DC:("func_8013D8DC",), 0x8013D924:("func_8013D924",), - 0x8013D960:("func_ActorCategoryIterateById",), + 0x8013D960:("SubS_FindActor",), 0x8013D9C8:("func_8013D9C8",), 0x8013DB90:("func_8013DB90",), 0x8013DC40:("func_8013DC40",), @@ -2705,7 +2705,7 @@ 0x8013E3B8:("func_8013E3B8",), 0x8013E4B0:("func_8013E4B0",), 0x8013E5CC:("func_8013E5CC",), - 0x8013E640:("func_8013E640",), + 0x8013E640:("SubS_FindActorCustom",), 0x8013E748:("func_8013E748",), 0x8013E7C0:("func_8013E7C0",), 0x8013E8F8:("func_8013E8F8",), @@ -2783,10 +2783,10 @@ 0x801431E8:("func_801431E8",), 0x80143324:("func_80143324",), 0x801434E4:("func_801434E4",), - 0x801435A0:("func_801435A0",), - 0x80143624:("func_80143624",), - 0x80143668:("func_80143668",), - 0x80143A04:("func_80143A04",), + 0x801435A0:("SkyboxDraw_UpdateMatrix",), + 0x80143624:("SkyboxDraw_SetColors",), + 0x80143668:("SkyboxDraw_Draw",), + 0x80143A04:("SkyboxDraw_Noop",), 0x80143A10:("func_80143A10",), 0x80143A54:("func_80143A54",), 0x80143AC4:("func_80143AC4",), @@ -2925,17 +2925,17 @@ 0x801631DC:("func_801631DC",), 0x80163334:("func_80163334",), 0x80163660:("func_80163660",), - 0x80163700:("func_80163700",), - 0x80163758:("func_80163758",), - 0x801637B4:("func_801637B4",), - 0x80163804:("func_80163804",), - 0x8016388C:("func_8016388C",), - 0x801638D8:("func_801638D8",), - 0x801639A0:("func_801639A0",), - 0x801639EC:("func_801639EC",), - 0x80163A38:("func_80163A38",), - 0x80163A58:("func_80163A58",), - 0x80163C0C:("func_80163C0C",), + 0x80163700:("KaleidoManager_FaultAddrConvFunc",), + 0x80163758:("KaleidoManager_LoadOvl",), + 0x801637B4:("KaleidoManager_ClearOvl",), + 0x80163804:("KaleidoManager_Init",), + 0x8016388C:("KaleidoManager_Destroy",), + 0x801638D8:("KaleidoManager_GetRamAddr",), + 0x801639A0:("KaleidoScopeCall_LoadPlayer",), + 0x801639EC:("KaleidoScopeCall_Init",), + 0x80163A38:("KaleidoScopeCall_Destroy",), + 0x80163A58:("KaleidoScopeCall_Update",), + 0x80163C0C:("KaleidoScopeCall_Draw",), 0x80163C90:("func_80163C90",), 0x80163D80:("func_80163D80",), 0x80163DC0:("func_80163DC0",), @@ -2995,7 +2995,7 @@ 0x80167814:("func_80167814",), 0x80167DE4:("func_80167DE4",), 0x80167F0C:("func_80167F0C",), - 0x80168090:("func_80168090",), + 0x80168090:("Play_Draw",), 0x80168DAC:("func_80168DAC",), 0x80168F64:("Play_Update",), 0x801690CC:("func_801690CC",), @@ -3720,8 +3720,8 @@ 0x80194568:("func_80194568",), 0x80194668:("func_80194668",), 0x801946E4:("func_801946E4",), - 0x80194710:("func_80194710",), - 0x80194750:("func_80194750",), + 0x80194710:("Audio_InvalDCache",), + 0x80194750:("Audio_WritebackDCache",), 0x80194790:("func_80194790",), 0x80194804:("func_80194804",), 0x80194840:("func_80194840",), @@ -4240,10 +4240,10 @@ 0x808274DC:("func_808274DC",), 0x80827A8C:("func_80827A8C",), 0x80827E08:("func_80827E08",), - 0x808283D8:("func_808283D8",), + 0x808283D8:("KaleidoScope_Draw",), 0x808286D8:("func_808286D8",), 0x80828788:("func_80828788",), - 0x8082895C:("func_8082895C",), + 0x8082895C:("KaleidoScope_Update",), 0x8082DA90:("func_8082DA90",), 0x8082DABC:("func_8082DABC",), 0x8082DAD4:("func_8082DAD4",), @@ -4991,8 +4991,8 @@ 0x80869D90:("EnPametfrog_Init",), 0x80869F90:("EnPametfrog_Destroy",), 0x80869FBC:("EnPametfrog_Vec3fNormalize",), - 0x8086A024:("EnPametfrog_ChangeColliderFreeze",), - 0x8086A068:("EnPametfrog_ChangeColliderThaw",), + 0x8086A024:("EnPametfrog_Freeze",), + 0x8086A068:("EnPametfrog_Thaw",), 0x8086A0F4:("EnPametfrog_JumpWaterEffects",), 0x8086A1A0:("EnPametfrog_IdleWaterEffects",), 0x8086A238:("func_8086A238",), @@ -5419,7 +5419,7 @@ 0x8088FE64:("func_8088FE64",), 0x8089010C:("func_8089010C",), 0x80890438:("EnElf_Update",), - 0x80890494:("func_80890494",), + 0x80890494:("EnElf_OverrideLimbDraw",), 0x808905B8:("EnElf_Draw",), 0x808908D0:("func_808908D0",), 0x80891060:("EnNiw_Init",), @@ -5527,8 +5527,8 @@ 0x808986A4:("func_808986A4",), 0x8089874C:("func_8089874C",), 0x80898A28:("EnPeehat_Update",), - 0x80898E74:("func_80898E74",), - 0x80899024:("func_80899024",), + 0x80898E74:("EnPeehat_OverrideLimbDraw",), + 0x80899024:("EnPeehat_PostLimbDraw",), 0x80899218:("EnPeehat_Draw",), 0x80899960:("EnHoll_SetupAction",), 0x808999B0:("EnHoll_SetPlayerSide",), @@ -5736,7 +5736,7 @@ 0x808A7138:("EnSt_Init",), 0x808A71D0:("EnSt_Destroy",), 0x808A7230:("EnSt_Update",), - 0x808A73E8:("func_808A73E8",), + 0x808A73E8:("EnSt_OverrideLimbDraw",), 0x808A7478:("func_808A7478",), 0x808A7930:("ObjWturn_Init",), 0x808A7954:("func_808A7954",), @@ -6401,21 +6401,21 @@ 0x808D7928:("func_808D7928",), 0x808D7954:("ObjMure_Init",), 0x808D7A04:("ObjMure_Destroy",), - 0x808D7A14:("func_808D7A14",), - 0x808D7A40:("func_808D7A40",), - 0x808D7A68:("func_808D7A68",), - 0x808D7C64:("func_808D7C64",), - 0x808D7DC4:("func_808D7DC4",), - 0x808D7E14:("func_808D7E14",), - 0x808D7F0C:("func_808D7F0C",), - 0x808D7F2C:("func_808D7F2C",), - 0x808D7FFC:("func_808D7FFC",), - 0x808D8014:("func_808D8014",), - 0x808D8074:("func_808D8074",), - 0x808D814C:("func_808D814C",), - 0x808D82CC:("func_808D82CC",), - 0x808D84F4:("func_808D84F4",), - 0x808D8678:("func_808D8678",), + 0x808D7A14:("ObjMure_GetMaxChildSpawns",), + 0x808D7A40:("ObjMure_GetSpawnPos",), + 0x808D7A68:("ObjMure_SpawnActors0",), + 0x808D7C64:("ObjMure_SpawnActors1",), + 0x808D7DC4:("ObjMure_SpawnActors",), + 0x808D7E14:("ObjMure_KillActorsImpl",), + 0x808D7F0C:("ObjMure_KillActors",), + 0x808D7F2C:("ObjMure_CheckChildren",), + 0x808D7FFC:("ObjMure_InitialAction",), + 0x808D8014:("ObjMure_CulledState",), + 0x808D8074:("ObjMure_SetFollowTargets",), + 0x808D814C:("ObjMure_SetChildToFollowPlayer",), + 0x808D82CC:("ObjMure_GroupBehavior0",), + 0x808D84F4:("ObjMure_GroupBehavior1",), + 0x808D8678:("ObjMure_ActiveState",), 0x808D8720:("ObjMure_Update",), 0x808D8940:("func_808D8940",), 0x808D8B58:("func_808D8B58",), @@ -6671,7 +6671,7 @@ 0x808EC990:("func_808EC990",), 0x808ECD14:("func_808ECD14",), 0x808ED07C:("func_808ED07C",), - 0x808ED138:("EnBigslime_Draw",), + 0x808ED138:("EnBigslime_DrawGekko",), 0x808ED3F4:("func_808ED3F4",), 0x808F1200:("EnKarebaba_Init",), 0x808F1334:("EnKarebaba_Destroy",), @@ -6818,52 +6818,52 @@ 0x808FC550:("EnFr_Init",), 0x808FC5AC:("EnFr_Destroy",), 0x808FC5BC:("EnFr_Update",), - 0x808FC6C0:("func_808FC6C0",), - 0x808FC770:("func_808FC770",), - 0x808FC790:("func_808FC790",), - 0x808FC8B8:("func_808FC8B8",), - 0x808FC964:("func_808FC964",), - 0x808FCABC:("func_808FCABC",), - 0x808FCC0C:("func_808FCC0C",), - 0x808FCDBC:("func_808FCDBC",), - 0x808FCF60:("func_808FCF60",), - 0x808FD054:("func_808FD054",), + 0x808FC6C0:("EnFishing_SetColliderElement",), + 0x808FC770:("EnFishing_SeedRand",), + 0x808FC790:("EnFishing_RandZeroOne",), + 0x808FC8B8:("EnFishing_SmoothStepToS",), + 0x808FC964:("EnFishing_SpawnRipple",), + 0x808FCABC:("EnFishing_SpawnDustSplash",), + 0x808FCC0C:("EnFishing_SpawnWaterDust",), + 0x808FCDBC:("EnFishing_SpawnBubble",), + 0x808FCF60:("EnFishing_SpawnRainDrop",), + 0x808FD054:("EnFishing_InitPondProps",), 0x808FD368:("EnFishing_Init",), 0x808FDC64:("EnFishing_Destroy",), - 0x808FDCDC:("func_808FDCDC",), - 0x808FE3F8:("func_808FE3F8",), - 0x808FEE1C:("func_808FEE1C",), + 0x808FDCDC:("EnFishing_UpdateEffects",), + 0x808FE3F8:("EnFishing_DrawEffects",), + 0x808FEE1C:("EnFishing_DrawStreamSplash",), 0x808FEF70:("func_808FEF70",), - 0x808FF064:("func_808FF064",), - 0x808FF5E0:("func_808FF5E0",), - 0x808FF750:("func_808FF750",), - 0x808FFC44:("func_808FFC44",), - 0x808FFF3C:("func_808FFF3C",), - 0x80900228:("func_80900228",), - 0x80900A04:("func_80900A04",), - 0x80901480:("func_80901480",), + 0x808FF064:("EnFishing_UpdateLine",), + 0x808FF5E0:("EnFishing_UpdateLinePos",), + 0x808FF750:("EnFishing_DrawLureHook",), + 0x808FFC44:("EnFishing_UpdateSinkingLure",), + 0x808FFF3C:("EnFishing_DrawSinkingLure",), + 0x80900228:("EnFishing_DrawLureAndLine",), + 0x80900A04:("EnFishing_DrawRod",), + 0x80901480:("EnFishing_UpdateLure",), 0x809033F0:("func_809033F0",), 0x809036BC:("func_809036BC",), 0x809038A4:("func_809038A4",), 0x80903C60:("func_80903C60",), - 0x80903E20:("func_80903E20",), - 0x80903FE0:("EnFishing_Update",), - 0x80908554:("func_80908554",), - 0x80908674:("func_80908674",), - 0x809086B4:("func_809086B4",), - 0x80908734:("func_80908734",), - 0x80908774:("EnFishing_Draw",), - 0x809089B8:("func_809089B8",), - 0x80908A64:("func_80908A64",), - 0x80908B4C:("func_80908B4C",), - 0x80908E08:("func_80908E08",), - 0x80909234:("func_80909234",), - 0x80909AD0:("func_80909AD0",), - 0x80909CC0:("func_80909CC0",), - 0x8090AB6C:("func_8090AB6C",), - 0x8090C884:("func_8090C884",), - 0x8090C8BC:("func_8090C8BC",), - 0x8090C96C:("func_8090C96C",), + 0x80903E20:("EnFishing_HandleAquariumDialog",), + 0x80903FE0:("EnFishing_UpdateFish",), + 0x80908554:("EnFishing_FishOverrideLimbDraw",), + 0x80908674:("EnFishing_FishPostLimbDraw",), + 0x809086B4:("EnFishing_LoachOverrideLimbDraw",), + 0x80908734:("EnFishing_LoachPostLimbDraw",), + 0x80908774:("EnFishing_DrawFish",), + 0x809089B8:("EnFishing_HandleReedContact",), + 0x80908A64:("EnFishing_HandleLilyPadContact",), + 0x80908B4C:("EnFishing_UpdatePondProps",), + 0x80908E08:("EnFishing_DrawPondProps",), + 0x80909234:("EnFishing_UpdateGroupFishes",), + 0x80909AD0:("EnFishing_DrawGroupFishes",), + 0x80909CC0:("EnFishing_HandleOwnerDialog",), + 0x8090AB6C:("EnFishing_UpdateOwner",), + 0x8090C884:("EnFishing_OwnerOverrideLimbDraw",), + 0x8090C8BC:("EnFishing_OwnerPostLimbDraw",), + 0x8090C96C:("EnFishing_DrawOwner",), 0x80917290:("func_80917290",), 0x809172E4:("func_809172E4",), 0x8091734C:("func_8091734C",), @@ -7631,10 +7631,10 @@ 0x80951748:("EnGm_Draw",), 0x80952620:("EnMs_Init",), 0x80952708:("EnMs_Destroy",), - 0x80952734:("func_80952734",), - 0x809527F8:("func_809527F8",), - 0x809529AC:("func_809529AC",), - 0x80952A1C:("func_80952A1C",), + 0x80952734:("EnMs_Wait",), + 0x809527F8:("EnMs_Talk",), + 0x809529AC:("EnMs_Sell",), + 0x80952A1C:("EnMs_TalkAfterPurchase",), 0x80952A8C:("EnMs_Update",), 0x80952B24:("EnMs_Draw",), 0x80952C50:("func_80952C50",), @@ -7888,9 +7888,9 @@ 0x80965650:("EnStream_SetupAction",), 0x8096565C:("EnStream_Init",), 0x809656C4:("EnStream_Destroy",), - 0x809656D4:("func_809656D4",), - 0x809657F4:("func_809657F4",), - 0x8096597C:("func_8096597C",), + 0x809656D4:("EnStream_PlayerIsInRange",), + 0x809657F4:("EnStream_SuckPlayer",), + 0x8096597C:("EnStream_WaitForPlayer",), 0x809659D0:("EnStream_Update",), 0x80965A04:("EnStream_Draw",), 0x80965BB0:("EnMm_SetupAction",), @@ -8077,51 +8077,51 @@ 0x80973DE0:("func_80973DE0",), 0x80973E60:("ObjRoomtimer_Update",), 0x80973EF0:("EnSsh_SetupAction",), - 0x80973EFC:("func_80973EFC",), - 0x80973F84:("func_80973F84",), - 0x80974080:("func_80974080",), - 0x80974118:("func_80974118",), - 0x80974220:("func_80974220",), - 0x8097424C:("func_8097424C",), - 0x80974374:("func_80974374",), - 0x809744A8:("func_809744A8",), - 0x809744C8:("func_809744C8",), - 0x809744FC:("func_809744FC",), - 0x80974540:("func_80974540",), - 0x80974590:("func_80974590",), - 0x809745BC:("func_809745BC",), - 0x80974730:("func_80974730",), - 0x8097480C:("func_8097480C",), - 0x809748DC:("func_809748DC",), - 0x8097497C:("func_8097497C",), - 0x809749B8:("func_809749B8",), - 0x80974A24:("func_80974A24",), - 0x80974B0C:("func_80974B0C",), - 0x80974B44:("func_80974B44",), - 0x80974B84:("func_80974B84",), - 0x80974CC8:("func_80974CC8",), - 0x80974D3C:("func_80974D3C",), - 0x80974E44:("func_80974E44",), - 0x80974EA0:("func_80974EA0",), - 0x80974F78:("func_80974F78",), - 0x8097502C:("func_8097502C",), - 0x80975070:("func_80975070",), - 0x80975128:("func_80975128",), - 0x80975300:("func_80975300",), + 0x80973EFC:("EnSsh_SpawnShockwave",), + 0x80973F84:("EnSsh_CreateBlureEffect",), + 0x80974080:("EnSsh_CheckCeilingPos",), + 0x80974118:("EnSsh_AddBlureVertex",), + 0x80974220:("EnSsh_AddBlureSpace",), + 0x8097424C:("EnSsh_InitColliders",), + 0x80974374:("EnSsh_SetAnimation",), + 0x809744A8:("EnSsh_SetWaitAnimation",), + 0x809744C8:("EnSsh_SetReturnAnimation",), + 0x809744FC:("EnSsh_SetLandAnimation",), + 0x80974540:("EnSsh_SetDropAnimation",), + 0x80974590:("EnSsh_SetStunned",), + 0x809745BC:("EnSsh_SetColliderScale",), + 0x80974730:("EnSsh_Damaged",), + 0x8097480C:("EnSsh_Turn",), + 0x809748DC:("EnSsh_Stunned",), + 0x8097497C:("EnSsh_UpdateYaw",), + 0x809749B8:("EnSsh_Bob",), + 0x80974A24:("EnSsh_IsCloseToLink",), + 0x80974B0C:("EnSsh_IsCloseToHome",), + 0x80974B44:("EnSsh_IsCloseToGround",), + 0x80974B84:("EnSsh_Sway",), + 0x80974CC8:("EnSsh_CheckBodyStickHit",), + 0x80974D3C:("EnSsh_CheckHitPlayer",), + 0x80974E44:("EnSsh_CheckHitFront",), + 0x80974EA0:("EnSsh_CheckHitBack",), + 0x80974F78:("EnSsh_CollisionCheck",), + 0x8097502C:("EnSsh_SetBodyCylinderAC",), + 0x80975070:("EnSsh_SetLegsCylinderAC",), + 0x80975128:("EnSsh_SetCylinderOC",), + 0x80975300:("EnSsh_SetColliders",), 0x809753C8:("EnSsh_Init",), 0x80975540:("EnSsh_Destroy",), - 0x809755C0:("func_809755C0",), - 0x8097561C:("func_8097561C",), + 0x809755C0:("EnSsh_Wait",), + 0x8097561C:("EnSsh_Talk",), 0x809756D0:("func_809756D0",), - 0x80975720:("func_80975720",), - 0x809758B0:("func_809758B0",), - 0x80975998:("func_80975998",), - 0x80975A98:("func_80975A98",), - 0x80975B6C:("func_80975B6C",), - 0x80975C14:("func_80975C14",), + 0x80975720:("EnSsh_Idle",), + 0x809758B0:("EnSsh_Land",), + 0x80975998:("EnSsh_Drop",), + 0x80975A98:("EnSsh_Return",), + 0x80975B6C:("EnSsh_UpdateColliderScale",), + 0x80975C14:("EnSsh_Start",), 0x80975C9C:("EnSsh_Update",), - 0x80975DBC:("func_80975DBC",), - 0x80975EB8:("func_80975EB8",), + 0x80975DBC:("EnSsh_OverrideLimbDraw",), + 0x80975EB8:("EnSsh_PostLimbDraw",), 0x80975F38:("EnSsh_Draw",), 0x809764B0:("OceffWipe_Init",), 0x8097650C:("OceffWipe_Destroy",), @@ -8678,8 +8678,8 @@ 0x809A1E60:("EnZl4_Draw",), 0x809A2030:("EnMm2_Init",), 0x809A2070:("EnMm2_Destroy",), - 0x809A2080:("func_809A2080",), - 0x809A20FC:("func_809A20FC",), + 0x809A2080:("EnMm2_Reading",), + 0x809A20FC:("EnMm2_WaitForRead",), 0x809A2194:("EnMm2_Update",), 0x809A21B8:("EnMm2_Draw",), 0x809A2B60:("DoorSpiral_SetupAction",), @@ -9031,9 +9031,9 @@ 0x809C3190:("EnAob01_Init",), 0x809C3350:("EnAob01_Destroy",), 0x809C339C:("EnAob01_Update",), - 0x809C33D8:("func_809C33D8",), - 0x809C35B4:("func_809C35B4",), - 0x809C35F4:("func_809C35F4",), + 0x809C33D8:("EnAob01_OverrideLimbDraw",), + 0x809C35B4:("EnAob01_PostLimbDraw",), + 0x809C35F4:("EnAob01_UnkDraw",), 0x809C3608:("EnAob01_Draw",), 0x809C3D80:("EnBoj01_Init",), 0x809C3D90:("EnBoj01_Destroy",), @@ -9375,8 +9375,8 @@ 0x809ED45C:("func_809ED45C",), 0x809ED50C:("func_809ED50C",), 0x809ED8BC:("Boss04_Update",), - 0x809EDCCC:("func_809EDCCC",), - 0x809EDECC:("func_809EDECC",), + 0x809EDCCC:("Boss04_OverrideLimbDraw",), + 0x809EDECC:("Boss04_PostLimbDraw",), 0x809EDF58:("Boss04_Draw",), 0x809EE4E0:("func_809EE4E0",), 0x809EE668:("func_809EE668",), @@ -9742,8 +9742,8 @@ 0x80A15960:("EnGo_Destroy",), 0x80A159B0:("EnGo_Update",), 0x80A15B80:("func_80A15B80",), - 0x80A15D04:("func_80A15D04",), - 0x80A15E38:("func_80A15E38",), + 0x80A15D04:("EnGo_OverrideLimbDraw",), + 0x80A15E38:("EnGo_UnkDraw",), 0x80A15FEC:("func_80A15FEC",), 0x80A16D40:("func_80A16D40",), 0x80A16D6C:("func_80A16D6C",), @@ -10907,37 +10907,37 @@ 0x80A6B0D8:("func_80A6B0D8",), 0x80A6B3F8:("EnMushi2_Update",), 0x80A6B8D0:("EnMushi2_Draw",), - 0x80A6BF90:("func_80A6BF90",), - 0x80A6C1DC:("func_80A6C1DC",), + 0x80A6BF90:("EnFall_Moon_AdjustScaleAndPosition",), + 0x80A6C1DC:("EnFall_RisingDebris_ResetParticles",), 0x80A6C22C:("EnFall_Init",), 0x80A6C39C:("EnFall_Destroy",), - 0x80A6C3AC:("func_80A6C3AC",), - 0x80A6C3FC:("func_80A6C3FC",), - 0x80A6C7C0:("func_80A6C7C0",), - 0x80A6C9A8:("func_80A6C9A8",), - 0x80A6CA9C:("func_80A6CA9C",), - 0x80A6CB74:("func_80A6CB74",), - 0x80A6CD38:("func_80A6CD38",), - 0x80A6CD74:("func_80A6CD74",), - 0x80A6CECC:("func_80A6CECC",), - 0x80A6CF60:("func_80A6CF60",), - 0x80A6CF70:("func_80A6CF70",), + 0x80A6C3AC:("EnFall_MoonsTear_GetTerminaFieldMoon",), + 0x80A6C3FC:("EnFall_Setup",), + 0x80A6C7C0:("EnFall_CrashingMoon_HandleGiantsCutscene",), + 0x80A6C9A8:("EnFall_CrashingMoon_PerformCutsceneActions",), + 0x80A6CA9C:("EnFall_StoppedOpenMouthMoon_PerformCutsceneActions",), + 0x80A6CB74:("EnFall_StoppedClosedMouthMoon_PerformCutsceneActions",), + 0x80A6CD38:("EnFall_ClockTowerOrTitleScreenMoon_PerformCutsceneActions",), + 0x80A6CD74:("EnFall_Moon_PerformDefaultActions",), + 0x80A6CECC:("EnFall_MoonsTear_Initialize",), + 0x80A6CF60:("EnFall_DoNothing",), + 0x80A6CF70:("EnFall_MoonsTear_Fall",), 0x80A6D0DC:("EnFall_Update",), - 0x80A6D100:("func_80A6D100",), - 0x80A6D220:("func_80A6D220",), - 0x80A6D444:("func_80A6D444",), - 0x80A6D504:("func_80A6D504",), - 0x80A6D698:("func_80A6D698",), - 0x80A6D75C:("func_80A6D75C",), - 0x80A6D88C:("func_80A6D88C",), - 0x80A6D98C:("func_80A6D98C",), - 0x80A6DA7C:("func_80A6DA7C",), - 0x80A6DC20:("func_80A6DC20",), - 0x80A6DC40:("func_80A6DC40",), - 0x80A6DD3C:("func_80A6DD3C",), - 0x80A6E07C:("func_80A6E07C",), - 0x80A6E214:("func_80A6E214",), - 0x80A6E37C:("func_80A6E37C",), + 0x80A6D100:("EnFall_FireBall_SetPerVertexAlpha",), + 0x80A6D220:("EnFall_FireBall_Update",), + 0x80A6D444:("EnFall_RisingDebris_UpdateParticles",), + 0x80A6D504:("EnFall_RisingDebris_InitializeParticles",), + 0x80A6D698:("EnFall_RisingDebris_Update",), + 0x80A6D75C:("EnFall_FireRing_Update",), + 0x80A6D88C:("EnFall_Moon_Draw",), + 0x80A6D98C:("EnFall_OpenMouthMoon_Draw",), + 0x80A6DA7C:("EnFall_LodMoon_Draw",), + 0x80A6DC20:("EnFall_LodMoon_DrawWithoutLerp",), + 0x80A6DC40:("EnFall_LodMoon_DrawWithLerp",), + 0x80A6DD3C:("EnFall_FireBall_Draw",), + 0x80A6E07C:("EnFall_RisingDebris_Draw",), + 0x80A6E214:("EnFall_FireRing_Draw",), + 0x80A6E37C:("EnFall_MoonsTear_Draw",), 0x80A6F0A0:("EnMm3_Init",), 0x80A6F1EC:("EnMm3_Destroy",), 0x80A6F22C:("func_80A6F22C",), @@ -11100,10 +11100,10 @@ 0x80A7BC70:("ObjEtcetera_Init",), 0x80A7BD80:("ObjEtcetera_Destroy",), 0x80A7BDC8:("ObjEtcetera_DoNormalOscillation",), - 0x80A7BE8C:("ObjEtcetera_StartSmallFlutterAnimation",), + 0x80A7BE8C:("ObjEtcetera_StartRustleAnimation",), 0x80A7BF08:("ObjEtcetera_Idle",), - 0x80A7C168:("ObjEtcetera_PlaySmallFlutterAnimation",), - 0x80A7C1F0:("ObjEtcetera_DoIntenseOscillation",), + 0x80A7C168:("ObjEtcetera_PlayRustleAnimation",), + 0x80A7C1F0:("ObjEtcetera_DoBounceOscillation",), 0x80A7C308:("ObjEtcetera_Setup",), 0x80A7C5EC:("ObjEtcetera_Update",), 0x80A7C690:("ObjEtcetera_DrawIdle",), @@ -11247,8 +11247,8 @@ 0x80A88334:("EnTru_Init",), 0x80A884BC:("EnTru_Destroy",), 0x80A884E8:("EnTru_Update",), - 0x80A885B8:("func_80A885B8",), - 0x80A88698:("func_80A88698",), + 0x80A885B8:("EnTru_OverrideLimbDraw",), + 0x80A88698:("EnTru_PostLimbDraw",), 0x80A886D4:("func_80A886D4",), 0x80A887E4:("EnTru_Draw",), 0x80A8B770:("EnTrt_ChangeAnim",), @@ -11336,7 +11336,7 @@ 0x80A903B0:("EnTest5_SetupAction",), 0x80A903BC:("EnTest5_Init",), 0x80A90468:("EnTest5_Destroy",), - 0x80A90478:("func_80A90478",), + 0x80A90478:("EnTest5_HandleBottleAction",), 0x80A905A4:("EnTest5_Update",), 0x80A90730:("func_80A90730",), 0x80A90C08:("func_80A90C08",), @@ -11502,9 +11502,9 @@ 0x80AA2720:("func_80AA2720",), 0x80AA27EC:("func_80AA27EC",), 0x80AA2884:("DmStk_Update",), - 0x80AA2B14:("func_80AA2B14",), - 0x80AA2BC0:("func_80AA2BC0",), - 0x80AA33A4:("func_80AA33A4",), + 0x80AA2B14:("DmStk_OverrideLimbDraw",), + 0x80AA2BC0:("DmStk_PostLimbDraw2",), + 0x80AA33A4:("DmStk_PostLimbDraw",), 0x80AA33CC:("DmStk_Draw",), 0x80AA5580:("func_80AA5580",), 0x80AA561C:("func_80AA561C",), @@ -11667,45 +11667,45 @@ 0x80AB2544:("DmChar09_Update",), 0x80AB25D8:("func_80AB25D8",), 0x80AB261C:("DmChar09_Draw",), - 0x80AB2790:("func_80AB2790",), - 0x80AB27B4:("func_80AB27B4",), - 0x80AB2834:("func_80AB2834",), - 0x80AB28C8:("func_80AB28C8",), - 0x80AB29F8:("func_80AB29F8",), - 0x80AB2BBC:("func_80AB2BBC",), + 0x80AB2790:("ObjTokeidai_GetTargetSunMoonDiskRotation",), + 0x80AB27B4:("ObjTokeidai_SetupClockOrGear",), + 0x80AB2834:("ObjTokeidai_Clock_Init",), + 0x80AB28C8:("ObjTokeidai_TowerGear_Init",), + 0x80AB29F8:("ObjTokeidai_TowerClock_Init",), + 0x80AB2BBC:("ObjTokeidai_Counterweight_Init",), 0x80AB2DEC:("ObjTokeidai_Init",), 0x80AB3000:("ObjTokeidai_Destroy",), - 0x80AB3010:("func_80AB3010",), - 0x80AB319C:("func_80AB319C",), - 0x80AB3240:("func_80AB3240",), - 0x80AB32F0:("func_80AB32F0",), - 0x80AB3370:("func_80AB3370",), - 0x80AB34CC:("func_80AB34CC",), - 0x80AB3544:("func_80AB3544",), - 0x80AB3598:("func_80AB3598",), - 0x80AB363C:("func_80AB363C",), - 0x80AB365C:("func_80AB365C",), - 0x80AB36C4:("func_80AB36C4",), - 0x80AB3808:("func_80AB3808",), - 0x80AB3880:("func_80AB3880",), - 0x80AB38B0:("func_80AB38B0",), - 0x80AB39BC:("func_80AB39BC",), - 0x80AB3A7C:("func_80AB3A7C",), - 0x80AB3B34:("func_80AB3B34",), - 0x80AB3BB0:("func_80AB3BB0",), - 0x80AB3BD8:("func_80AB3BD8",), - 0x80AB3BE8:("func_80AB3BE8",), - 0x80AB3C50:("func_80AB3C50",), - 0x80AB3CCC:("func_80AB3CCC",), - 0x80AB3ED0:("func_80AB3ED0",), - 0x80AB4040:("func_80AB4040",), - 0x80AB4080:("func_80AB4080",), - 0x80AB4160:("func_80AB4160",), + 0x80AB3010:("ObjTokeidai_RotateOnMinuteChange",), + 0x80AB319C:("ObjTokeidai_TowerGear_Collapse",), + 0x80AB3240:("ObjTokeidai_TowerGear_OpenedIdle",), + 0x80AB32F0:("ObjTokeidai_TowerClock_Fall",), + 0x80AB3370:("ObjTokeidai_TowerClock_SlideOff",), + 0x80AB34CC:("ObjTokeidai_TowerClock_OpenedIdle",), + 0x80AB3544:("ObjTokeidai_Counterweight_Collapse",), + 0x80AB3598:("ObjTokeidai_Counterweight_OpenedIdle",), + 0x80AB363C:("ObjTokeidai_Walls_Collapse",), + 0x80AB365C:("ObjTokeidai_Walls_Idle",), + 0x80AB36C4:("ObjTokeidai_TowerTransformation_EndCutscene",), + 0x80AB3808:("ObjTokeidai_TowerOpening_FinishOpening",), + 0x80AB3880:("ObjTokeidai_TowerOpening_Wait",), + 0x80AB38B0:("ObjTokeidai_TowerOpening_DropCounterweight",), + 0x80AB39BC:("ObjTokeidai_TowerOpening_FinishRaise",), + 0x80AB3A7C:("ObjTokeidai_TowerOpening_RaiseTower",), + 0x80AB3B34:("ObjTokeidai_TowerOpening_Start",), + 0x80AB3BB0:("ObjTokeidai_SetupTowerOpening",), + 0x80AB3BD8:("ObjTokeidai_DoNothing",), + 0x80AB3BE8:("ObjTokeidai_StaircaseIntoTower_Idle",), + 0x80AB3C50:("ObjTokeidai_IsPostFirstCycleFinalHours",), + 0x80AB3CCC:("ObjTokeidai_RotateOnHourChange",), + 0x80AB3ED0:("ObjTokeidai_TowerClock_Idle",), + 0x80AB4040:("ObjTokeidai_WallClock_Idle",), + 0x80AB4080:("ObjTokeidai_TowerGear_Idle",), + 0x80AB4160:("ObjTokeidai_Counterweight_Idle",), 0x80AB4278:("ObjTokeidai_Update",), 0x80AB429C:("ObjTokeidai_Draw",), - 0x80AB4394:("func_80AB4394",), - 0x80AB4664:("func_80AB4664",), - 0x80AB4894:("func_80AB4894",), + 0x80AB4394:("ObjTokeidai_Clock_Draw",), + 0x80AB4664:("ObjTokeidai_Counterweight_Draw",), + 0x80AB4894:("ObjTokeidai_TowerGear_Draw",), 0x80AB4D10:("func_80AB4D10",), 0x80AB4E34:("func_80AB4E34",), 0x80AB4E58:("func_80AB4E58",), @@ -12276,7 +12276,7 @@ 0x80AD8A48:("func_80AD8A48",), 0x80AD8AF8:("func_80AD8AF8",), 0x80AD8BC0:("EnKame_Draw",), - 0x80AD8CEC:("func_80AD8CEC",), + 0x80AD8CEC:("Enkame_OverrideLimbDraw",), 0x80AD8D64:("func_80AD8D64",), 0x80AD9240:("func_80AD9240",), 0x80AD92FC:("func_80AD92FC",), @@ -12805,7 +12805,7 @@ 0x80AFDD34:("EnColMan_Destroy",), 0x80AFDD60:("func_80AFDD60",), 0x80AFDE00:("func_80AFDE00",), - 0x80AFDF00:("func_80AFDF00",), + 0x80AFDF00:("EnColMan_SetHeartPieceCollectedAndKill",), 0x80AFDF60:("func_80AFDF60",), 0x80AFDFB4:("func_80AFDFB4",), 0x80AFE234:("func_80AFE234",), @@ -12817,53 +12817,53 @@ 0x80AFE650:("func_80AFE650",), 0x80AFE8A0:("EnTalkGibud_Init",), 0x80AFEB0C:("EnTalkGibud_Destroy",), - 0x80AFEB38:("func_80AFEB38",), - 0x80AFEB7C:("func_80AFEB7C",), - 0x80AFEC08:("func_80AFEC08",), - 0x80AFEC4C:("func_80AFEC4C",), - 0x80AFED08:("func_80AFED08",), - 0x80AFED7C:("func_80AFED7C",), - 0x80AFEFD4:("func_80AFEFD4",), - 0x80AFF030:("func_80AFF030",), - 0x80AFF22C:("func_80AFF22C",), - 0x80AFF288:("func_80AFF288",), - 0x80AFF330:("func_80AFF330",), - 0x80AFF378:("func_80AFF378",), - 0x80AFF45C:("func_80AFF45C",), - 0x80AFF4AC:("func_80AFF4AC",), - 0x80AFF618:("func_80AFF618",), - 0x80AFF6A0:("func_80AFF6A0",), - 0x80AFF700:("func_80AFF700",), - 0x80AFF76C:("func_80AFF76C",), - 0x80AFF880:("func_80AFF880",), - 0x80AFF8E4:("func_80AFF8E4",), - 0x80AFF9CC:("func_80AFF9CC",), - 0x80AFFA68:("func_80AFFA68",), - 0x80AFFAB0:("func_80AFFAB0",), - 0x80AFFC10:("func_80AFFC10",), - 0x80AFFC9C:("func_80AFFC9C",), - 0x80AFFD3C:("func_80AFFD3C",), - 0x80AFFE3C:("func_80AFFE3C",), - 0x80AFFE94:("func_80AFFE94",), - 0x80AFFFA4:("func_80AFFFA4",), - 0x80AFFFBC:("func_80AFFFBC",), - 0x80B000FC:("func_80B000FC",), - 0x80B00158:("func_80B00158",), - 0x80B00384:("func_80B00384",), - 0x80B0040C:("func_80B0040C",), - 0x80B00484:("func_80B00484",), - 0x80B004D0:("func_80B004D0",), - 0x80B005EC:("func_80B005EC",), - 0x80B00760:("func_80B00760",), - 0x80B008BC:("func_80B008BC",), - 0x80B008FC:("func_80B008FC",), - 0x80B0094C:("func_80B0094C",), - 0x80B00B8C:("func_80B00B8C",), - 0x80B00C94:("func_80B00C94",), - 0x80B00D9C:("func_80B00D9C",), + 0x80AFEB38:("EnTalkGibud_SetupIdle",), + 0x80AFEB7C:("EnTalkGibud_Idle",), + 0x80AFEC08:("EnTalkGibud_SetupAttemptPlayerStun",), + 0x80AFEC4C:("EnTalkGibud_AttemptStun",), + 0x80AFED08:("EnTalkGibud_SetupWalkToPlayer",), + 0x80AFED7C:("EnTalkGibud_WalkToPlayer",), + 0x80AFEFD4:("EnTalkGibud_SetupGrab",), + 0x80AFF030:("EnTalkGibud_Grab",), + 0x80AFF22C:("EnTalkGibud_SetupGrabFail",), + 0x80AFF288:("EnTalkGibud_GrabFail",), + 0x80AFF330:("EnTalkGibud_SetupTurnAwayAndShakeHead",), + 0x80AFF378:("EnTalkGibud_TurnAwayAndShakeHead",), + 0x80AFF45C:("EnTalkGibud_SetupWalkToHome",), + 0x80AFF4AC:("EnTalkGibud_WalkToHome",), + 0x80AFF618:("EnTalkGibud_SetupStunned",), + 0x80AFF6A0:("EnTalkGibud_Stunned",), + 0x80AFF700:("EnTalkGibud_SetupDamage",), + 0x80AFF76C:("EnTalkGibud_Damage",), + 0x80AFF880:("EnTalkGibud_SetupDead",), + 0x80AFF8E4:("EnTalkGibud_Dead",), + 0x80AFF9CC:("EnTalkGibud_SetupRevive",), + 0x80AFFA68:("EnTalkGibud_Revive",), + 0x80AFFAB0:("EnTalkGibud_GetTextIdForRequestedItem",), + 0x80AFFC10:("EnTalkGibud_GetNextTextBoxId",), + 0x80AFFC9C:("EnTalkGibud_PresentedItemMatchesRequest",), + 0x80AFFD3C:("EnTalkGibud_CheckPresentedItem",), + 0x80AFFE3C:("EnTalkGibud_SetupPassiveIdle",), + 0x80AFFE94:("EnTalkGibud_PassiveIdle",), + 0x80AFFFA4:("EnTalkGibud_SetupTalk",), + 0x80AFFFBC:("EnTalkGibud_Talk",), + 0x80B000FC:("EnTalkGibud_SetupDisappear",), + 0x80B00158:("EnTalkGibud_Disappear",), + 0x80B00384:("EnTalkGibud_FacePlayerWhenTalking",), + 0x80B0040C:("EnTalkGibud_PlayerInRangeWithCorrectState",), + 0x80B00484:("EnTalkGibud_PlayerOutOfRange",), + 0x80B004D0:("EnTalkGibud_CheckForGibdoMask",), + 0x80B005EC:("EnTalkGibud_TurnTowardsPlayer",), + 0x80B00760:("EnTalkGibud_MoveToIdealGrabPositionAndRotation",), + 0x80B008BC:("EnTalkGibud_PlayAnimation",), + 0x80B008FC:("EnTalkGibud_MoveWithGravity",), + 0x80B0094C:("EnTalkGibud_CheckDamageEffect",), + 0x80B00B8C:("EnTalkGibud_CheckCollision",), + 0x80B00C94:("EnTalkGibud_MoveGrabbedPlayerAwayFromWall",), + 0x80B00D9C:("EnTalkGibud_UpdateEffect",), 0x80B00E48:("EnTalkGibud_Update",), - 0x80B00F08:("func_80B00F08",), - 0x80B00F64:("func_80B00F64",), + 0x80B00F08:("EnTalkGibud_OverrideLimbDraw",), + 0x80B00F64:("EnTalkGibud_PostLimbDraw",), 0x80B01040:("EnTalkGibud_Draw",), 0x80B01990:("EnGiant_ChangeAnimation",), 0x80B01A74:("EnGiant_IsImprisoned",), @@ -13021,8 +13021,8 @@ 0x80B1137C:("EnGb2_Init",), 0x80B116E4:("EnGb2_Destroy",), 0x80B11710:("EnGb2_Update",), - 0x80B1179C:("func_80B1179C",), - 0x80B117FC:("func_80B117FC",), + 0x80B1179C:("EnGb2_OverrideLimbDraw",), + 0x80B117FC:("EnGb2_PostLimbDraw",), 0x80B11858:("EnGb2_Draw",), 0x80B11E60:("EnOnpuman_Init",), 0x80B11F18:("EnOnpuman_Destroy",), @@ -14161,7 +14161,7 @@ 0x80B610B8:("ObjDora_Draw",), 0x80B615E0:("EnBigpo_Init",), 0x80B6186C:("EnBigpo_Destroy",), - 0x80B61914:("func_80B61914",), + 0x80B61914:("EnBigpo_RotateSpawnCutsceneFires",), 0x80B619B4:("func_80B619B4",), 0x80B619FC:("func_80B619FC",), 0x80B61AC8:("EnBigPo_InitWellBigPo",), @@ -14404,8 +14404,8 @@ 0x80B72880:("func_80B72880",), 0x80B72970:("func_80B72970",), 0x80B72DBC:("EnRailSkb_Update",), - 0x80B72E88:("func_80B72E88",), - 0x80B7302C:("func_80B7302C",), + 0x80B72E88:("EnRailSkb_OverrideLimbDraw",), + 0x80B7302C:("EnRailSkb_PostLimbDraw",), 0x80B731EC:("EnRailSkb_Draw",), 0x80B73A90:("func_80B73A90",), 0x80B73AE4:("func_80B73AE4",), @@ -14941,11 +14941,11 @@ 0x80B99798:("EnZot_Draw",), 0x80B9A0B0:("ObjTree_Init",), 0x80B9A1BC:("ObjTree_Destroy",), - 0x80B9A20C:("func_80B9A20C",), - 0x80B9A220:("func_80B9A220",), - 0x80B9A230:("func_80B9A230",), - 0x80B9A27C:("func_80B9A27C",), - 0x80B9A348:("func_80B9A348",), + 0x80B9A20C:("ObTree_SetupDoNothing",), + 0x80B9A220:("ObTree_DoNothing",), + 0x80B9A230:("ObTree_SetupSway",), + 0x80B9A27C:("ObTree_Sway",), + 0x80B9A348:("ObTree_UpdateCollision",), 0x80B9A3E8:("ObjTree_Update",), 0x80B9A424:("ObjTree_Draw",), 0x80B9A650:("ObjY2lift_Init",), @@ -15324,9 +15324,9 @@ 0x80BB3650:("EnGeg_Destroy",), 0x80BB36A0:("EnGeg_Update",), 0x80BB3728:("func_80BB3728",), - 0x80BB3860:("func_80BB3860",), - 0x80BB387C:("func_80BB387C",), - 0x80BB39F8:("func_80BB39F8",), + 0x80BB3860:("EnGeg_OverrideLimbDraw",), + 0x80BB387C:("EnGeg_PostLimbDraw",), + 0x80BB39F8:("EnGeg_UnkDraw",), 0x80BB3BE0:("func_80BB3BE0",), 0x80BB3CB4:("func_80BB3CB4",), 0x80BB3E0C:("EnGeg_Draw",), @@ -15360,17 +15360,17 @@ 0x80BB7800:("EnTanron2_Update",), 0x80BB7B90:("func_80BB7B90",), 0x80BB7C14:("EnTanron2_Draw",), - 0x80BB85A0:("func_80BB85A0",), + 0x80BB85A0:("EnTanron3_CreateEffect",), 0x80BB86BC:("EnTanron3_Init",), 0x80BB87B0:("EnTanron3_Destroy",), - 0x80BB87D4:("func_80BB87D4",), - 0x80BB897C:("func_80BB897C",), - 0x80BB8A48:("func_80BB8A48",), - 0x80BB91D4:("func_80BB91D4",), - 0x80BB9288:("func_80BB9288",), - 0x80BB9308:("func_80BB9308",), + 0x80BB87D4:("EnTanron3_SpawnBubbles",), + 0x80BB897C:("EnTanron3_SetupLive",), + 0x80BB8A48:("EnTanron3_Live",), + 0x80BB91D4:("EnTanron3_SetupDie",), + 0x80BB9288:("EnTanron3_Die",), + 0x80BB9308:("EnTanron3_CheckCollisions",), 0x80BB93EC:("EnTanron3_Update",), - 0x80BB95FC:("func_80BB95FC",), + 0x80BB95FC:("EnTanron3_OverrideLimbDraw",), 0x80BB9670:("EnTanron3_Draw",), 0x80BB98E0:("ObjChan_Init",), 0x80BB99F0:("ObjChan_Destroy",), @@ -16068,7 +16068,7 @@ 0x80BE1E9C:("EnNimotsu_Draw",), 0x80BE2030:("EnHitTag_Init",), 0x80BE20BC:("EnHitTag_Destroy",), - 0x80BE20E8:("func_80BE20E8",), + 0x80BE20E8:("EnHitTag_WaitForHit",), 0x80BE21A0:("EnHitTag_Update",), 0x80BE2260:("func_80BE2260",), 0x80BE2330:("func_80BE2330",), @@ -16272,9 +16272,9 @@ 0x80BEFD98:("EnAkindonuts_Init",), 0x80BEFF08:("EnAkindonuts_Destroy",), 0x80BEFF34:("EnAkindonuts_Update",), - 0x80BEFFB4:("func_80BEFFB4",), - 0x80BF0178:("func_80BF0178",), - 0x80BF0190:("func_80BF0190",), + 0x80BEFFB4:("EnAkindonuts_OverrideLimbDraw",), + 0x80BF0178:("EnAkindonuts_PostLimbDraw",), + 0x80BF0190:("EnAkindonuts_UnkActorDraw",), 0x80BF0258:("EnAkindonuts_Draw",), 0x80BF0D90:("EffStk_Init",), 0x80BF0DD0:("EffStk_Destroy",), @@ -16483,7 +16483,7 @@ 0x80C00234:("func_80C00234",), 0x80C00284:("func_80C00284",), 0x80C00644:("EnBomjima_Update",), - 0x80C007F4:("func_80C007F4",), + 0x80C007F4:("EnBomjima_OverrideLimbDraw",), 0x80C008B4:("EnBomjima_Draw",), 0x80C00EA0:("EnBomjimb_Init",), 0x80C01110:("EnBomjimb_Destroy",), @@ -16515,7 +16515,7 @@ 0x80C02CA4:("func_80C02CA4",), 0x80C02DAC:("func_80C02DAC",), 0x80C02DC4:("EnBomjimb_Update",), - 0x80C02FA8:("func_80C02FA8",), + 0x80C02FA8:("EnBomjimb_OverrideLimbDraw",), 0x80C03034:("EnBomjimb_Draw",), 0x80C03530:("EnBombers_Init",), 0x80C037F8:("EnBombers_Destroy",), @@ -16738,14 +16738,14 @@ 0x80C0F758:("func_80C0F758",), 0x80C0FFD0:("EnRecepgirl_Init",), 0x80C100CC:("EnRecepgirl_Destroy",), - 0x80C100DC:("func_80C100DC",), - 0x80C10148:("func_80C10148",), - 0x80C1019C:("func_80C1019C",), - 0x80C10290:("func_80C10290",), - 0x80C102D4:("func_80C102D4",), + 0x80C100DC:("EnRecepgirl_UpdateEyes",), + 0x80C10148:("EnRecepgirl_SetupWait",), + 0x80C1019C:("EnRecepgirl_Wait",), + 0x80C10290:("EnRecepgirl_SetupTalk",), + 0x80C102D4:("EnRecepgirl_Talk",), 0x80C104E8:("EnRecepgirl_Update",), - 0x80C10558:("func_80C10558",), - 0x80C10590:("func_80C10590",), + 0x80C10558:("EnRecepgirl_OverrideLimbDraw",), + 0x80C10590:("EnRecepgirl_UnkLimbDraw",), 0x80C105EC:("EnRecepgirl_Draw",), 0x80C10770:("EnThiefbird_Init",), 0x80C10958:("EnThiefbird_Destroy",), diff --git a/tools/disasm/variables.txt b/tools/disasm/variables.txt index cd7fa52ff..14414e00f 100644 --- a/tools/disasm/variables.txt +++ b/tools/disasm/variables.txt @@ -10,7 +10,7 @@ 0x8000031C:("osAppNmiBuffer","s32","[0x10]",0x40), 0x80000500:("gFramebuffer1","u16","[SCREEN_HEIGHT][SCREEN_WIDTH]",0x25800), 0x80025D00:("D_80025D00","u8","[]",0x1), # TODO size - 0x800969C0:("D_800969C0","UNK_TYPE1","",0x1), + 0x800969C0:("rspbootTextStart","u64","[]",0x160), 0x80096B20:("D_80096B20","u8","",0x1), 0x80096B24:("gViConfigUseDefault","vu8","",0x1), 0x80096B28:("gViConfigAdditionalScanLines","u8","",0x1), @@ -397,8 +397,8 @@ 0x801AE2CC:("D_801AE2CC","UNK_TYPE4","",0x4), 0x801AE2DC:("D_801AE2DC","UNK_TYPE4","",0x4), 0x801AE2F0:("sEffectShieldParticleVertices","F3DVertex","[4]",0x40), - 0x801AE330:("sEffInfoTable","EffInfo","[5]",0x64), - 0x801AE3A0:("EffectSS2Info","EffectSsInfo","",0xc), + 0x801AE330:("sEffectInfoTable","EffectInfo","[5]",0x64), + 0x801AE3A0:("sEffectSsInfo","EffectSsInfo","",0xc), 0x801AE3B0:("D_801AE3B0","Color_RGBA8","",0x4), 0x801AE3B4:("D_801AE3B4","Color_RGBA8","",0x4), 0x801AE3B8:("D_801AE3B8","Color_RGBA8","",0x4), @@ -419,11 +419,9 @@ 0x801AE480:("D_801AE480","Color_RGBA8","",0x4), 0x801AE484:("D_801AE484","Color_RGBA8","",0x4), 0x801AE488:("D_801AE488","Color_RGBA8","",0x4), - 0x801AE489:("D_801AE489","UNK_TYPE1","",0x1), - 0x801AE48A:("D_801AE48A","UNK_TYPE1","",0x1), 0x801AE48C:("D_801AE48C","Color_RGBA8","",0x4), 0x801AE490:("D_801AE490","Color_RGBA8","[4]",0x10), - 0x801AE4A0:("particleOverlayTable","EffectSsOverlay","[39]",0x444), + 0x801AE4A0:("gParticleOverlayTable","EffectSsOverlay","[39]",0x444), 0x801AE8F0:("sFlagEntries","FlagSetEntry","[112]",0x8), 0x801AEC70:("sEntryIndex","s32","",0x4), 0x801AEC74:("sCurrentBit","u32","",0x4), @@ -882,8 +880,8 @@ 0x801BA484:("defaultColChkInfo","CollisionCheckInfo","",0x1c), 0x801BA4A0:("sApplyDamageFuncs","ColChkApplyFunc","",0x14), 0x801BA4B4:("sOCLineCheckFuncs","ColChkLineFunc","",0x14), - 0x801BA4C8:("shieldParticleInitMetal","EffShieldParticleInit","",0x40), - 0x801BA508:("shieldParticleInitWood","EffShieldParticleInit","",0x40), + 0x801BA4C8:("shieldParticleInitMetal","EffectShieldParticleInit","",0x40), + 0x801BA508:("shieldParticleInitWood","EffectShieldParticleInit","",0x40), 0x801BA550:("D_801BA550","UNK_TYPE1","",0x1), 0x801BA750:("D_801BA750","UNK_TYPE1","",0x1), 0x801BA790:("sDebugDisplay1DL","UNK_TYPE1","",0x1), @@ -923,7 +921,7 @@ 0x801BC2A0:("D_801BC2A0","UNK_TYPE1","",0x1), 0x801BC3F0:("D_801BC3F0","UNK_TYPE1","",0x1), 0x801BC400:("D_801BC400","UNK_TYPE1","",0x1), - 0x801BC410:("D_801BC410","UNK_TYPE1","",0x1), + 0x801BC410:("D_801BC410","s32",[],0x10), 0x801BC420:("sReactionTextIds","u16","[]",0x140A), 0x801BD830:("actorCutscenesGlobalCutscenes","ActorCutscene","[8]",0x80), 0x801BD8B0:("actorCutsceneCurrent","s16","",0x2), @@ -2169,9 +2167,9 @@ 0x801D08E8:("D_801D08E8","UNK_TYPE1","",0x1), 0x801D0900:("D_801D0900","UNK_TYPE1","",0x1), 0x801D0B50:("Player_InitVars","ActorInit","",0x20), - 0x801D0B70:("D_801D0B70","UNK_TYPE1","",0x38), - 0x801D0BA8:("D_801D0BA8","UNK_TYPE4","",0x4), - 0x801D0BAC:("D_801D0BAC","UNK_TYPE4","",0x4), + 0x801D0B70:("gKaleidoMgrOverlayTable","KaleidoMgrOverlay","",0x38), + 0x801D0BA8:("sKaleidoAreaPtr","void*","",0x4), + 0x801D0BAC:("gKaleidoMgrCurOvl","KaleidoMgrOverlay*","",0x4), 0x801D0BB0:("D_801D0BB0","UNK_TYPE4","",0x4), 0x801D0C80:("D_801D0C80","UNK_TYPE1","",0x1), 0x801D0CB0:("D_801D0CB0","UNK_TYPE1","",0x1), @@ -2245,13 +2243,13 @@ 0x801D1538:("D_801D1538","UNK_TYPE4","",0x4), 0x801D1540:("D_801D1540","UNK_PTR","",0x4), 0x801D1570:("D_801D1570","f32","[13]",0x34), - 0x801D15B0:("D_801D15B0","Vec3f","",0xC), - 0x801D15BC:("D_801D15BC","UNK_TYPE4","",0x4), + 0x801D15B0:("gZeroVec3f","Vec3f","",0xC), + 0x801D15BC:("gZeroVec3s","Vec3s","",0x6), 0x801D15D0:("sATan2Tbl","s16","[1025]",0x802), - 0x801D1DE0:("D_801D1DE0","Mtx","",0x40), - 0x801D1E20:("D_801D1E20","MtxF","",0x40), - 0x801D1E60:("D_801D1E60","UNK_PTR","",0x4), - 0x801D1E64:("D_801D1E64","UNK_PTR","",0x4), + 0x801D1DE0:("gIdentityMtx","Mtx","",0x40), + 0x801D1E20:("gIdentityMtxF","MtxF","",0x40), + 0x801D1E60:("initialgspUcodeText","UNK_PTR","",0x4), + 0x801D1E64:("initialgspUcodeData","UNK_PTR","",0x4), 0x801D1E70:("D_801D1E70","UNK_TYPE1","",0x1), 0x801D2E80:("D_801D2E80","UNK_TYPE1","",0x1), 0x801D2F80:("D_801D2F80","UNK_TYPE1","",0x1), @@ -2433,14 +2431,14 @@ 0x801D8E48:("D_801D8E48","UNK_TYPE1","",0x1), 0x801D8E50:("D_801D8E50","UNK_TYPE1","",0x1), 0x801D8F70:("D_801D8F70","UNK_TYPE1","",0x1), - 0x801D9090:("D_801D9090","UNK_TYPE1","",0x1), - 0x801D9C10:("D_801D9C10","UNK_TYPE1","",0x1), - 0x801DA350:("D_801DA350","UNK_TYPE1","",0x1), - 0x801DA510:("D_801DA510","UNK_TYPE1","",0x1), - 0x801DAC50:("D_801DAC50","UNK_TYPE1","",0x1), - 0x801DADD0:("D_801DADD0","UNK_TYPE1","",0x1), - 0x801DAE10:("D_801DAE10","UNK_TYPE1","",0x1), - 0x801DB450:("D_801DB450","UNK_PTR","",0x4), + 0x801D9090:("sEnemyBankParams","UNK_TYPE1","",0x1), + 0x801D9C10:("sPlayerBankParams","UNK_TYPE1","",0x1), + 0x801DA350:("sItemBankParams","UNK_TYPE1","",0x1), + 0x801DA510:("sEnvBankParams","UNK_TYPE1","",0x1), + 0x801DAC50:("sSystemBankParams","UNK_TYPE1","",0x1), + 0x801DADD0:("sOcarinaBankParams","UNK_TYPE1","",0x1), + 0x801DAE10:("sVoiceBankParams","UNK_TYPE1","",0x1), + 0x801DB450:("gSfxParams","UNK_PTR","",0x4), 0x801DB470:("D_801DB470","UNK_TYPE1","",0x1), 0x801DB474:("D_801DB474","UNK_TYPE1","",0x1), 0x801DB478:("D_801DB478","UNK_PTR","[7]",0x1c), @@ -3691,7 +3689,7 @@ 0x801E0148:("D_801E0148","f32","",0x4), 0x801E014C:("D_801E014C","f32","",0x4), 0x801E0150:("Math3D_UnitNormalVector_min_length","f32","",0x4), - 0x801E0154:("Math3D_NormalizedDistanceFromPlane_min_length","f32","",0x4), + 0x801E0154:("Math3D_UDistPlaneToPos_min_length","f32","",0x4), 0x801E0158:("D_801E0158","f32","",0x4), 0x801E015C:("D_801E015C","f32","",0x4), 0x801E0160:("D_801E0160","f32","",0x4), @@ -3873,11 +3871,8 @@ 0x801E1070:("jtbl_801E1070","UNK_PTR","",0x4), 0x801E10B0:("jtbl_801E10B0","UNK_PTR","",0x4), 0x801E10C4:("jtbl_801E10C4","UNK_PTR","",0x4), - 0x801E1100:("D_801E1100","UNK_TYPE2","",0x2), - 0x801E1102:("D_801E1102","UNK_TYPE2","",0x2), - 0x801E1104:("D_801E1104","UNK_TYPE4","",0x4), - 0x801E1108:("D_801E1108","UNK_TYPE4","",0x4), - 0x801E110C:("D_801E110C","UNK_TYPE4","",0x4), + 0x801E1100:("gAudioTatumInit","s16","[2]",0x4), + 0x801E1104:("gAudioContextInitSizes","AudioContextInitSizes","",0xC), 0x801E1110:("sGameOverTimer","UNK_TYPE2","",0x2), 0x801E1120:("jtbl_801E1120","UNK_PTR","",0x4), 0x801E1180:("D_801E1180","UNK_TYPE2","",0x2), @@ -3885,18 +3880,12 @@ 0x801E1630:("D_801E1630","UNK_TYPE2","",0x2), 0x801E1E40:("D_801E1E40","UNK_TYPE1","",0x1), 0x801E1E80:("D_801E1E80","UNK_TYPE1","",0x1), - 0x801E2160:("D_801E2160","UNK_TYPE1","",0x1), - 0x801E3790:("D_801E3790","UNK_TYPE1","",0x1), + 0x801E2160:("gspF3DEX2_NoN_fifoTextStart","UNK_TYPE1","",0x1), + 0x801E3790:("gspF3DEX2_NoN_fifoDataStart","UNK_TYPE1","",0x1), 0x801E3BB0:("D_801E3BB0","UNK_TYPE1","",0x1), 0x801E3F40:("gJpegUCodeData","UNK_TYPE1","",0x1), 0x801E3FA0:("D_801E3FA0","UNK_TYPE1","",0x1), - 0x801E3FB0:("sEffTable","EffTables","",0x98e0), - 0x801E4514:("D_801E4514","UNK_TYPE1","",0x1), - 0x801E4E08:("D_801E4E08","UNK_TYPE1","",0x1), - 0x801E531C:("D_801E531C","UNK_TYPE1","",0x1), - 0x801E69E0:("D_801E69E0","UNK_TYPE1","",0x1), - 0x801E9AA0:("D_801E9AA0","UNK_TYPE1","",0x1), - 0x801ED4C0:("D_801ED4C0","UNK_TYPE1","",0x1), + 0x801E3FB0:("sEffectContext","EffectContext","",0x98E0), 0x801ED890:("D_801ED890","UNK_TYPE1","",0x1), 0x801ED894:("D_801ED894","UNK_TYPE1","",0x1), 0x801ED8A0:("D_801ED8A0","UNK_TYPE1","",0x1), @@ -3981,12 +3970,12 @@ 0x801EE1D0:("D_801EE1D0","Vec3f","",0xc), 0x801EE1E0:("D_801EE1E0","Vec3f","",0xc), 0x801EE1F0:("D_801EE1F0","Vec3f","",0xc), - 0x801EE200:("D_801EE200","EffSparkParams","",0x4c4), + 0x801EE200:("D_801EE200","EffectSparkInit","",0x4c4), 0x801EE6C8:("D_801EE6C8","TriNorm","",0x34), 0x801EE700:("D_801EE700","TriNorm","",0x34), - 0x801EE738:("D_801EE738","EffSparkParams","",0x4c4), - 0x801EEC00:("D_801EEC00","EffSparkParams","",0x4c4), - 0x801EF0C8:("D_801EF0C8","EffSparkParams","",0x4c4), + 0x801EE738:("D_801EE738","EffectSparkInit","",0x4c4), + 0x801EEC00:("D_801EEC00","EffectSparkInit","",0x4c4), + 0x801EF0C8:("D_801EF0C8","EffectSparkInit","",0x4c4), 0x801EF590:("D_801EF590","UNK_TYPE1","",0x1), 0x801EF5C8:("D_801EF5C8","UNK_TYPE1","",0x1), 0x801EF600:("D_801EF600","TriNorm","",0x34), @@ -4100,7 +4089,7 @@ 0x801F6AD4:("D_801F6AD4","UNK_TYPE1","",0x1), 0x801F6AD5:("D_801F6AD5","UNK_TYPE1","",0x1), 0x801F6ADA:("D_801F6ADA","UNK_TYPE1","",0x1), - 0x801F6AE0:("D_801F6AE0","UNK_TYPE1","",0x1), + 0x801F6AE0:("sSkyboxDrawMatrix","Mtx*","",0x4), 0x801F6AF0:("D_801F6AF0","UNK_TYPE1","",0x1), 0x801F6AF2:("D_801F6AF2","UNK_TYPE1","",0x1), 0x801F6B00:("D_801F6B00","UNK_TYPE4","",0x4), @@ -4126,9 +4115,9 @@ 0x801F6B44:("gShrinkWindowContextPtr","ShrinkWindowContext*","",0x4), 0x801F6B50:("D_801F6B50","UNK_TYPE4","",0x4), 0x801F6B58:("D_801F6B58","UNK_TYPE1","",0x1), - 0x801F6BF0:("D_801F6BF0","UNK_TYPE1","",0x1), - 0x801F6C00:("D_801F6C00","UNK_TYPE1","",0x1), - 0x801F6C04:("D_801F6C04","UNK_TYPE1","",0x1), + 0x801F6BF0:("sKaleidoAreaFaultClient","FaultAddrConvClient","",0xC), + 0x801F6C00:("sKaleidoScopeUpdateFunc","void*","",0x4), + 0x801F6C04:("sKaleidoScopeDrawFunc","void*","",0x4), 0x801F6C10:("D_801F6C10","UNK_TYPE1","",0x1), 0x801F6C18:("D_801F6C18","Input","",0x18), 0x801F6C30:("D_801F6C30","UNK_TYPE1","",0x1), @@ -4234,8 +4223,8 @@ 0x801FBC46:("D_801FBC46","UNK_TYPE1","",0x1), 0x801FBC48:("D_801FBC48","UNK_TYPE1","",0x1), 0x801FBC58:("D_801FBC58","UNK_TYPE1","",0x1), - 0x801FBC68:("Math3D_NormalVector_temp1","Vec3f","",0xc), - 0x801FBC78:("Math3D_NormalVector_temp2","Vec3f","",0xc), + 0x801FBC68:("Math3D_SurfaceNorm_temp1","Vec3f","",0xc), + 0x801FBC78:("Math3D_SurfaceNorm_temp2","Vec3f","",0xc), 0x801FBC8C:("D_801FBC8C","f32","",0x4), 0x801FBC90:("D_801FBC90","f32","",0x4), 0x801FBC98:("D_801FBC98","f32","",0x4), @@ -5329,8 +5318,8 @@ 0x8085D2C0:("D_8085D2C0","ActorInitVar","",0x4), 0x8085D2C4:("D_8085D2C4","UNK_TYPE4","",0x4), 0x8085D2CC:("D_8085D2CC","UNK_PTR","",0x4), - 0x8085D30C:("D_8085D30C","EffBlureInit2","",0x24), - 0x8085D330:("D_8085D330","EffTireMarkInit","",0x8), + 0x8085D30C:("D_8085D30C","EffectBlureInit2","",0x24), + 0x8085D330:("D_8085D330","EffectTireMarkInit","",0x8), 0x8085D338:("D_8085D338","UNK_TYPE4","",0x4), 0x8085D33C:("D_8085D33C","UNK_TYPE4","",0x4), 0x8085D340:("D_8085D340","UNK_TYPE1","",0x1), @@ -5980,7 +5969,7 @@ 0x808792D4:("D_808792D4","UNK_TYPE1","",0x1), 0x808792F4:("D_808792F4","UNK_TYPE1","",0x1), 0x808792FC:("D_808792FC","UNK_TYPE1","",0x1), - 0x80879308:("D_80879308","EffBlureInit2","",0x24), + 0x80879308:("D_80879308","EffectBlureInit2","",0x24), 0x8087932C:("D_8087932C","UNK_TYPE1","",0x1), 0x80879330:("D_80879330","UNK_TYPE1","",0x1), 0x80879334:("D_80879334","UNK_TYPE1","",0x1), @@ -6205,10 +6194,10 @@ 0x8088C1C0:("En_Arrow_InitVars","UNK_TYPE1","",0x1), 0x8088C1E0:("D_8088C1E0","UNK_TYPE1","",0x1), 0x8088C230:("D_8088C230","UNK_TYPE1","",0x1), - 0x8088C234:("D_8088C234","EffBlureInit2","",0x24), - 0x8088C258:("D_8088C258","EffBlureInit2","",0x24), - 0x8088C27C:("D_8088C27C","EffBlureInit2","",0x24), - 0x8088C2A0:("D_8088C2A0","EffBlureInit2","",0x24), + 0x8088C234:("D_8088C234","EffectBlureInit2","",0x24), + 0x8088C258:("D_8088C258","EffectBlureInit2","",0x24), + 0x8088C27C:("D_8088C27C","EffectBlureInit2","",0x24), + 0x8088C2A0:("D_8088C2A0","EffectBlureInit2","",0x24), 0x8088C2C4:("D_8088C2C4","UNK_TYPE4","",0x4), 0x8088C2CC:("D_8088C2CC","UNK_TYPE1","",0x1), 0x8088C2D8:("D_8088C2D8","UNK_TYPE1","",0x1), @@ -6417,7 +6406,7 @@ 0x8089E350:("D_8089E350","UNK_TYPE4","",0x4), 0x8089E354:("D_8089E354","UNK_TYPE1","",0x1), 0x8089E364:("D_8089E364","UNK_TYPE4","",0x4), - 0x8089E368:("D_8089E368","EffBlureInit2","",0x24), + 0x8089E368:("D_8089E368","EffectBlureInit2","",0x24), 0x8089E38C:("D_8089E38C","UNK_TYPE1","",0x1), 0x8089E398:("D_8089E398","UNK_TYPE1","",0x1), 0x8089E3A4:("D_8089E3A4","UNK_TYPE1","",0x1), @@ -6743,10 +6732,8 @@ 0x808BBB20:("Door_Warp1_InitVars","UNK_TYPE1","",0x1), 0x808BBB40:("D_808BBB40","UNK_TYPE1","",0x1), 0x808BBB50:("D_808BBB50","UNK_TYPE4","",0x4), - 0x808BBB5C:("D_808BBB5C","f32","",0x4), - 0x808BBB64:("D_808BBB64","f32","",0x4), - 0x808BBB68:("D_808BBB68","UNK_TYPE1","",0x1), - 0x808BBB6C:("D_808BBB6C","f32","",0x4), + 0x808BBB5C:("D_808BBB5C","Vec3f","",0xC), + 0x808BBB68:("D_808BBB68","Vec3f","",0xC), 0x808BBB80:("jtbl_808BBB80","UNK_PTR","",0x4), 0x808BBB98:("jtbl_808BBB98","UNK_PTR","",0x4), 0x808BBBB4:("D_808BBBB4","f32","",0x4), @@ -6906,7 +6893,7 @@ 0x808C99C0:("D_808C99C0","UNK_TYPE1","",0x1), 0x808C9A10:("D_808C9A10","UNK_TYPE1","",0x1), 0x808C9A30:("D_808C9A30","UNK_TYPE1","",0x1), - 0x808C9A3C:("D_808C9A3C","EffBlureInit2","",0x24), + 0x808C9A3C:("D_808C9A3C","EffectBlureInit2","",0x24), 0x808C9A60:("D_808C9A60","UNK_TYPE1","",0x1), 0x808C9A70:("D_808C9A70","UNK_TYPE1","",0x1), 0x808C9A7C:("D_808C9A7C","UNK_TYPE1","",0x1), @@ -7129,7 +7116,6 @@ 0x808D784C:("D_808D784C","f32","",0x4), 0x808D7850:("D_808D7850","f32","",0x4), 0x808D8760:("Obj_Mure_InitVars","UNK_TYPE1","",0x1), - 0x808D8780:("D_808D8780","UNK_TYPE1","",0x1), 0x808DB9C0:("En_Sw_InitVars","UNK_TYPE1","",0x1), 0x808DB9E0:("D_808DB9E0","UNK_TYPE1","",0x1), 0x808DBA0C:("D_808DBA0C","UNK_PTR","",0x4), @@ -7482,7 +7468,7 @@ 0x808F88C0:("En_Bom_Chu_InitVars","UNK_TYPE1","",0x1), 0x808F88E0:("D_808F88E0","UNK_TYPE1","",0x1), 0x808F8908:("D_808F8908","UNK_TYPE2","",0x2), - 0x808F8914:("D_808F8914","EffBlureInit2","",0x24), + 0x808F8914:("D_808F8914","EffectBlureInit2","",0x24), 0x808F8938:("D_808F8938","UNK_TYPE1","",0x1), 0x808F8944:("D_808F8944","UNK_TYPE1","",0x1), 0x808F8950:("D_808F8950","UNK_TYPE1","",0x1), @@ -7558,12 +7544,11 @@ 0x808FC670:("En_Fr_InitVars","UNK_TYPE1","",0x1), 0x8090CCB0:("En_Fishing_InitVars","UNK_TYPE1","",0x1), 0x8090CCD0:("D_8090CCD0","f32","",0x4), - 0x8090CCD4:("D_8090CCD4","UNK_TYPE1","",0x1), + 0x8090CCD4:("D_8090CCD4","u8","",0x1), 0x8090CCD8:("D_8090CCD8","f32","",0x4), - 0x8090CCDC:("D_8090CCDC","UNK_TYPE1","",0x1), - 0x8090CCE4:("D_8090CCE4","UNK_TYPE4","",0x4), - 0x8090CCE8:("D_8090CCE8","UNK_TYPE4","",0x4), - 0x8090CCEC:("D_8090CCEC","UNK_TYPE1","",0x1), + 0x8090CCDC:("D_8090CCDC","Vec3f","",0xC), + 0x8090CCE8:("D_8090CCE8","f32","",0x4), + 0x8090CCEC:("sSinkingLureLocation","u8","",0x1), 0x8090CCF0:("D_8090CCF0","f32","",0x4), 0x8090CCF4:("D_8090CCF4","UNK_TYPE1","",0x1), 0x8090CCF8:("D_8090CCF8","UNK_TYPE2","",0x2), @@ -7574,18 +7559,17 @@ 0x8090CD0C:("D_8090CD0C","UNK_TYPE1","",0x1), 0x8090CD10:("D_8090CD10","UNK_TYPE1","",0x1), 0x8090CD14:("D_8090CD14","UNK_TYPE2","",0x2), - 0x8090CD18:("D_8090CD18","UNK_TYPE1","",0x1), - 0x8090CD1C:("D_8090CD1C","f32","",0x4), + 0x8090CD18:("sFishMouthOffset","Vec3f","",0xC), 0x8090CD24:("D_8090CD24","UNK_TYPE1","",0x1), 0x8090CD28:("D_8090CD28","f32","",0x4), 0x8090CD2C:("D_8090CD2C","f32","",0x4), 0x8090CD30:("D_8090CD30","f32","",0x4), 0x8090CD34:("D_8090CD34","f32","",0x4), - 0x8090CD38:("D_8090CD38","UNK_TYPE4","",0x4), + 0x8090CD38:("D_8090CD38","f32","",0x4), 0x8090CD3C:("D_8090CD3C","f32","",0x4), 0x8090CD40:("D_8090CD40","f32","",0x4), - 0x8090CD44:("D_8090CD44","UNK_TYPE2","",0x2), - 0x8090CD48:("D_8090CD48","UNK_TYPE2","",0x2), + 0x8090CD44:("D_8090CD44","s16","",0x2), + 0x8090CD48:("D_8090CD48","s16","",0x2), 0x8090CD4C:("D_8090CD4C","UNK_TYPE1","",0x1), 0x8090CD50:("D_8090CD50","UNK_TYPE1","",0x1), 0x8090CD54:("D_8090CD54","UNK_TYPE1","",0x1), @@ -7595,7 +7579,8 @@ 0x8090CD8C:("D_8090CD8C","UNK_TYPE1","",0x1), 0x8090CF08:("D_8090CF08","UNK_TYPE1","",0x1), 0x8090CF18:("D_8090CF18","UNK_TYPE1","",0x1), - 0x8090CF1C:("D_8090CF1C","UNK_TYPE4","",0x4), + 0x8090CF1C:("sZeroVec","Vec3f","",0xC), + 0x8090CF28:("D_8090CF28","Vec3f","",0xC), 0x8090CF34:("D_8090CF34","UNK_TYPE4","",0x4), 0x8090CF40:("D_8090CF40","UNK_TYPE4","",0x4), 0x8090CF4C:("D_8090CF4C","UNK_TYPE4","",0x4), @@ -7609,14 +7594,14 @@ 0x8090D508:("D_8090D508","UNK_TYPE1","",0x1), 0x8090D558:("D_8090D558","UNK_TYPE1","",0x1), 0x8090D5B0:("D_8090D5B0","UNK_TYPE4","",0x4), - 0x8090D608:("D_8090D608","UNK_TYPE1","",0x1), - 0x8090D614:("D_8090D614","UNK_TYPE1","",0x1), - 0x8090D620:("D_8090D620","UNK_TYPE4","",0x4), + 0x8090D608:("sRodTipOffset","Vec3f","",0xC), + 0x8090D614:("D_8090D614","Vec3f","",0xC), + 0x8090D620:("D_8090D620","Vec3f","",0xC), 0x8090D62C:("D_8090D62C","UNK_TYPE1","",0x1), 0x8090D638:("D_8090D638","UNK_TYPE1","",0x1), - 0x8090D644:("D_8090D644","UNK_TYPE1","",0x1), - 0x8090D650:("D_8090D650","UNK_TYPE1","",0x1), - 0x8090D65C:("D_8090D65C","UNK_TYPE1","",0x1), + 0x8090D644:("D_8090D644","s16","[5]",0xA), + 0x8090D650:("sStreamSoundPos","Vec3f","",0xC), + 0x8090D65C:("sSinkingLureLocationPos","Vec3s","[4]",0x18), 0x8090D674:("D_8090D674","UNK_TYPE1","",0x1), 0x8090D680:("D_8090D680","f32","",0x4), 0x8090D684:("D_8090D684","f32","",0x4), @@ -7902,46 +7887,37 @@ 0x809101C8:("D_809101C8","f32","",0x4), 0x809101CC:("D_809101CC","UNK_TYPE1","",0x1), 0x809101D0:("D_809101D0","UNK_TYPE1","",0x1), - 0x809101D8:("D_809101D8","UNK_TYPE1","",0x1), - 0x809101E8:("D_809101E8","UNK_TYPE1","",0x1), - 0x80910B3C:("D_80910B3C","f32","",0x4), - 0x80910B40:("D_80910B40","f32","",0x4), - 0x80910B44:("D_80910B44","f32","",0x4), - 0x80910B48:("D_80910B48","UNK_TYPE1","",0x1), - 0x809114A8:("D_809114A8","UNK_TYPE1","",0x1), - 0x80911E08:("D_80911E08","UNK_TYPE1","",0x1), - 0x80911E14:("D_80911E14","UNK_TYPE1","",0x1), - 0x80911E20:("D_80911E20","UNK_TYPE1","",0x1), + 0x809101D8:("sRodTipPos","Vec3f","",0xC), + 0x809101E8:("sReelLinePos","Vec3f","[200]",0x960), + 0x80910B48:("sReelLineRot","Vec3f","[200]",0x960), + 0x809114A8:("sReelLineUnk","Vec3f","[200]",0x960), + 0x80911E08:("sLureHookRefPos","Vec3f","[2]",0x18), + 0x80911E20:("sLureHookRotY","f32","[2]",0x8), 0x80911E28:("D_80911E28","UNK_TYPE1","",0x1), - 0x80911E30:("D_80911E30","UNK_TYPE1","",0x1), - 0x80911E3C:("D_80911E3C","UNK_TYPE1","",0x1), + 0x80911E30:("sSinkingLurePos","Vec3f","[20]",0xF0), 0x80911F20:("D_80911F20","UNK_TYPE1","",0x1), - 0x80911F24:("D_80911F24","UNK_TYPE1","",0x1), - 0x80911F28:("D_80911F28","f32","",0x4), - 0x80911F2C:("D_80911F2C","f32","",0x4), - 0x80911F30:("D_80911F30","UNK_TYPE1","",0x1), - 0x80911F38:("D_80911F38","f32","",0x4), - 0x80911F3C:("D_80911F3C","f32","",0x4), - 0x80911F40:("D_80911F40","f32","",0x4), - 0x80911F44:("D_80911F44","UNK_TYPE1","",0x1), + 0x80911F24:("sProjectedW","f32","",0x4), + 0x80911F28:("sCameraEye","Vec3f","",0xC), + 0x80911F38:("sCameraAt","Vec3f","",0xC), + 0x80911F44:("sCameraId","s32","",0x4), 0x80911F48:("D_80911F48","f32","",0x4), 0x80911F4C:("D_80911F4C","f32","",0x4), 0x80911F50:("D_80911F50","UNK_TYPE1","",0x1), - 0x80911F58:("D_80911F58","UNK_TYPE1","",0x1), + 0x80911F58:("sSinkingLureBasePos","Vec3f","",0xC), 0x80911F64:("D_80911F64","f32","",0x4), - 0x80911F68:("D_80911F68","UNK_TYPE1","",0x1), - 0x80911F6C:("D_80911F6C","UNK_TYPE1","",0x1), - 0x80911F70:("D_80911F70","UNK_TYPE1","",0x1), - 0x80911F78:("D_80911F78","UNK_TYPE1","",0x1), - 0x80914048:("D_80914048","UNK_TYPE1","",0x1), - 0x80915128:("D_80915128","f32","",0x4), - 0x8091512C:("D_8091512C","f32","",0x4), - 0x80915130:("D_80915130","UNK_TYPE1","",0x1), - 0x80915138:("D_80915138","UNK_TYPE1","",0x1), - 0x809171B8:("D_809171B8","UNK_TYPE1","",0x1), - 0x809171C4:("D_809171C4","UNK_TYPE1","",0x1), + 0x80911F68:("sRandSeed0","s32","",0x4), + 0x80911F6C:("sRandSeed1","s32","",0x4), + 0x80911F70:("sRandSeed2","s32","",0x4), + 0x80911F78:("sPondProps","UNK_TYPE1","[140]",0x20D0), + 0x80914048:("sGroupFishes","UNK_TYPE1","[60]",0x10E0), + 0x80915128:("sFishGroupAngle1","f32","",0x4), + 0x8091512C:("sFishGroupAngle2","f32","",0x4), + 0x80915130:("sFishGroupAngle3","f32","",0x4), + 0x80915138:("sFishingEffects","UNK_TYPE1","[130]",0x2080), + 0x809171B8:("sStreamSoundProjectedPos","Vec3f","",0xC), + 0x809171C4:("sFishingMain","UNK_TYPE","",0x4), 0x809171C8:("D_809171C8","UNK_TYPE1","",0x1), - 0x809171C9:("D_809171C9","UNK_TYPE1","",0x1), + 0x809171C9:("sLinkAge","UNK_TYPE1","",0x1), 0x809171CA:("D_809171CA","UNK_TYPE1","",0x1), 0x809171CB:("D_809171CB","UNK_TYPE1","",0x1), 0x809171CC:("D_809171CC","f32","",0x4), @@ -7953,29 +7929,23 @@ 0x809171D8:("D_809171D8","UNK_TYPE1","",0x1), 0x809171DA:("D_809171DA","UNK_TYPE1","",0x1), 0x809171DC:("D_809171DC","UNK_TYPE1","",0x1), - 0x809171E0:("D_809171E0","UNK_TYPE1","",0x1), - 0x809171EC:("D_809171EC","UNK_TYPE1","",0x1), - 0x809171EE:("D_809171EE","UNK_TYPE1","",0x1), - 0x809171F0:("D_809171F0","UNK_TYPE1","",0x1), + 0x809171E0:("sOwnerHeadPos","Vec3f","",0xC), + 0x809171EC:("sEffOwnerHatRot","Vec3s","",0x6), 0x809171F2:("D_809171F2","UNK_TYPE1","",0x1), 0x809171F4:("D_809171F4","UNK_TYPE1","",0x1), 0x809171F6:("D_809171F6","UNK_TYPE1","",0x1), - 0x809171F8:("D_809171F8","UNK_TYPE1","",0x1), + 0x809171F8:("sFishingHookedFish","UNK_TYPE","",0x4), 0x809171FC:("D_809171FC","UNK_TYPE1","",0x1), 0x809171FE:("D_809171FE","UNK_TYPE1","",0x1), 0x80917200:("D_80917200","UNK_TYPE1","",0x1), 0x80917202:("D_80917202","UNK_TYPE1","",0x1), 0x80917204:("D_80917204","UNK_TYPE1","",0x1), 0x80917206:("D_80917206","UNK_TYPE1","",0x1), - 0x80917208:("D_80917208","f32","",0x4), - 0x8091720C:("D_8091720C","f32","",0x4), - 0x80917210:("D_80917210","UNK_TYPE1","",0x1), + 0x80917208:("sLurePos","Vec3f","",0xC), 0x80917218:("D_80917218","UNK_TYPE1","",0x1), - 0x80917228:("D_80917228","UNK_TYPE1","",0x1), - 0x8091722C:("D_8091722C","UNK_TYPE1","",0x1), - 0x80917238:("D_80917238","UNK_TYPE1","",0x1), - 0x8091723C:("D_8091723C","UNK_TYPE1","",0x1), - 0x80917248:("D_80917248","UNK_TYPE1","",0x1), + 0x80917228:("sLureRot","Vec3f","",0xC), + 0x80917238:("D_80917238","Vec3f","",0xC), + 0x80917248:("D_80917248","Vec3f","",0xC), 0x80917254:("D_80917254","f32","",0x4), 0x80917258:("D_80917258","UNK_TYPE1","",0x1), 0x8091725C:("D_8091725C","f32","",0x4), @@ -7987,8 +7957,7 @@ 0x80917270:("D_80917270","UNK_TYPE1","",0x1), 0x80917272:("D_80917272","UNK_TYPE1","",0x1), 0x80917274:("D_80917274","UNK_TYPE1","",0x1), - 0x80917278:("D_80917278","UNK_TYPE1","",0x1), - 0x8091727C:("D_8091727C","UNK_TYPE1","",0x1), + 0x80917278:("D_80917278","Vec3f","",0xC), 0x80918830:("Obj_Oshihiki_InitVars","UNK_TYPE1","",0x1), 0x80918850:("D_80918850","UNK_TYPE1","",0x1), 0x80918868:("D_80918868","UNK_TYPE1","",0x1), @@ -8291,7 +8260,7 @@ 0x8092C140:("D_8092C140","UNK_TYPE1","",0x1), 0x8092C160:("D_8092C160","UNK_TYPE1","",0x1), 0x8092C168:("D_8092C168","UNK_TYPE1","",0x1), - 0x8092C174:("D_8092C174","EffBlureInit2","",0x24), + 0x8092C174:("D_8092C174","EffectBlureInit2","",0x24), 0x8092C198:("D_8092C198","UNK_TYPE4","",0x4), 0x8092C19C:("D_8092C19C","UNK_TYPE1","",0x1), 0x8092C1A8:("D_8092C1A8","UNK_TYPE1","",0x1), @@ -8603,7 +8572,7 @@ 0x80942E60:("D_80942E60","UNK_TYPE1","",0x1), 0x80942E6C:("D_80942E6C","UNK_TYPE1","",0x1), 0x80942E78:("D_80942E78","UNK_TYPE1","",0x1), - 0x80942E8C:("D_80942E8C","EffTireMarkInit","",0x8), + 0x80942E8C:("D_80942E8C","EffectTireMarkInit","",0x8), 0x80942E94:("D_80942E94","UNK_TYPE1","",0x1), 0x80942E9C:("D_80942E9C","UNK_TYPE1","",0x1), 0x80942EAC:("D_80942EAC","UNK_TYPE1","",0x1), @@ -10709,8 +10678,8 @@ 0x80A07F0C:("D_80A07F0C","UNK_TYPE1","",0x1), 0x80A07F3C:("D_80A07F3C","UNK_TYPE1","",0x1), 0x80A07F54:("D_80A07F54","UNK_TYPE2","",0x2), - 0x80A07F5C:("D_80A07F5C","EffTireMarkInit","",0x8), - 0x80A07F64:("D_80A07F64","EffTireMarkInit","",0x8), + 0x80A07F5C:("D_80A07F5C","EffectTireMarkInit","",0x8), + 0x80A07F64:("D_80A07F64","EffectTireMarkInit","",0x8), 0x80A07F6C:("D_80A07F6C","UNK_TYPE4","",0x4), 0x80A07FA8:("D_80A07FA8","UNK_TYPE4","",0x4), 0x80A07FB4:("D_80A07FB4","UNK_TYPE4","",0x4), @@ -11033,7 +11002,7 @@ 0x80A166B0:("D_80A166B0","UNK_TYPE1","",0x1), 0x80A166BC:("D_80A166BC","UNK_TYPE1","",0x1), 0x80A166D4:("D_80A166D4","UNK_TYPE1","",0x1), - 0x80A166DC:("D_80A166DC","EffTireMarkInit","",0x8), + 0x80A166DC:("D_80A166DC","EffectTireMarkInit","",0x8), 0x80A166E4:("D_80A166E4","UNK_TYPE4","",0x4), 0x80A16704:("D_80A16704","UNK_TYPE1","",0x1), 0x80A1670C:("D_80A1670C","UNK_TYPE1","",0x1), @@ -11694,8 +11663,8 @@ 0x80A4169C:("D_80A4169C","UNK_PTR","",0x4), 0x80A416C0:("D_80A416C0","UNK_PTR","",0x4), 0x80A416E0:("D_80A416E0","UNK_TYPE1","",0x1), - 0x80A417BC:("D_80A417BC","EffBlureInit2","",0x24), - 0x80A417E0:("D_80A417E0","EffTireMarkInit","",0x8), + 0x80A417BC:("D_80A417BC","EffectBlureInit2","",0x24), + 0x80A417E0:("D_80A417E0","EffectTireMarkInit","",0x8), 0x80A417E8:("D_80A417E8","UNK_TYPE1","",0x1), 0x80A417EC:("D_80A417EC","UNK_PTR","",0x4), 0x80A41828:("D_80A41828","UNK_TYPE1","",0x1), @@ -12001,7 +11970,7 @@ 0x80A5844C:("D_80A5844C","UNK_TYPE1","",0x1), 0x80A58454:("D_80A58454","UNK_TYPE4","",0x4), 0x80A58464:("D_80A58464","UNK_TYPE1","",0x1), - 0x80A58470:("D_80A58470","EffBlureInit2","",0x24), + 0x80A58470:("D_80A58470","EffectBlureInit2","",0x24), 0x80A58494:("D_80A58494","UNK_TYPE4","",0x4), 0x80A58498:("D_80A58498","UNK_TYPE1","",0x1), 0x80A584A4:("D_80A584A4","UNK_TYPE1","",0x1), @@ -12062,10 +12031,8 @@ 0x80A5EAFE:("D_80A5EAFE","UNK_TYPE2","",0x2), 0x80A5EB00:("D_80A5EB00","UNK_TYPE2","",0x2), 0x80A5EB04:("D_80A5EB04","UNK_TYPE2","",0x2), - 0x80A5EB0C:("D_80A5EB0C","f32","",0x4), - 0x80A5EB14:("D_80A5EB14","f32","",0x4), - 0x80A5EB18:("D_80A5EB18","f32","",0x4), - 0x80A5EB20:("D_80A5EB20","f32","",0x4), + 0x80A5EB0C:("D_80A5EB0C","Vec3f","",0xC), + 0x80A5EB18:("D_80A5EB18","Vec3f","",0xC), 0x80A5EB24:("D_80A5EB24","UNK_TYPE1","",0x1), 0x80A5EB48:("D_80A5EB48","UNK_TYPE4","",0x4), 0x80A5EB4C:("D_80A5EB4C","UNK_TYPE1","",0x1), @@ -12311,10 +12278,7 @@ 0x80A6BB00:("D_80A6BB00","f32","",0x4), 0x80A6E490:("En_Fall_InitVars","UNK_TYPE1","",0x1), 0x80A6E4B0:("D_80A6E4B0","UNK_TYPE4","",0x4), - 0x80A6E4B4:("D_80A6E4B4","UNK_TYPE1","",0x1), - 0x80A6E4B5:("D_80A6E4B5","UNK_TYPE1","",0x1), - 0x80A6E584:("D_80A6E584","UNK_TYPE1","",0x1), - 0x80A6E585:("D_80A6E585","UNK_TYPE1","",0x1), + 0x80A6E4B4:("D_80A6E4B4","s8","[0xD1]",0xD0), 0x80A6E588:("D_80A6E588","UNK_TYPE1","",0x1), 0x80A6E594:("D_80A6E594","UNK_TYPE1","",0x1), 0x80A6E5A0:("D_80A6E5A0","f32","",0x4), @@ -12346,8 +12310,6 @@ 0x80A6E650:("D_80A6E650","f32","",0x4), 0x80A6E654:("D_80A6E654","f32","",0x4), 0x80A6E990:("D_80A6E990","UNK_TYPE1","",0x1), - 0x80A6E9B4:("D_80A6E9B4","UNK_TYPE1","",0x1), - 0x80A6E9D8:("D_80A6E9D8","UNK_TYPE1","",0x1), 0x80A6F098:("D_80A6F098","UNK_TYPE1","",0x1), 0x80A703D0:("En_Mm3_InitVars","UNK_TYPE1","",0x1), 0x80A703F0:("D_80A703F0","UNK_TYPE1","",0x1), @@ -12602,8 +12564,7 @@ 0x80A8A188:("D_80A8A188","UNK_TYPE1","",0x1), 0x80A8B188:("D_80A8B188","UNK_TYPE1","",0x1), 0x80A8B250:("D_80A8B250","UNK_TYPE4","",0x4), - 0x80A8B25C:("D_80A8B25C","UNK_TYPE1","",0x1), - 0x80A8B268:("D_80A8B268","UNK_TYPE1","",0x1), + 0x80A8B25C:("D_80A8B25C","Color_RGBA8","[6]",0x18), 0x80A8B280:("D_80A8B280","UNK_TYPE1","",0x1), 0x80A8B2A0:("D_80A8B2A0","UNK_TYPE1","",0x1), 0x80A8B2CC:("D_80A8B2CC","UNK_TYPE1","",0x1), @@ -14595,7 +14556,7 @@ 0x80B40780:("D_80B40780","UNK_TYPE1","",0x1), 0x80B43250:("En_Kgy_InitVars","UNK_TYPE1","",0x1), 0x80B43270:("D_80B43270","UNK_TYPE1","",0x1), - 0x80B43298:("D_80B43298","EffShieldParticleInit","",0x40), + 0x80B43298:("D_80B43298","EffectShieldParticleInit","",0x40), 0x80B432C6:("D_80B432C6","UNK_TYPE1","",0x1), 0x80B432C8:("D_80B432C8","UNK_TYPE1","",0x1), 0x80B432CA:("D_80B432CA","UNK_TYPE1","",0x1), @@ -15807,7 +15768,7 @@ 0x80BB3ED4:("D_80BB3ED4","UNK_TYPE1","",0x1), 0x80BB3EF4:("D_80BB3EF4","UNK_TYPE1","",0x1), 0x80BB4044:("D_80BB4044","UNK_TYPE1","",0x1), - 0x80BB405C:("D_80BB405C","EffTireMarkInit","",0x8), + 0x80BB405C:("D_80BB405C","EffectTireMarkInit","",0x8), 0x80BB4064:("D_80BB4064","UNK_TYPE4","",0x4), 0x80BB4070:("D_80BB4070","UNK_TYPE4","",0x4), 0x80BB407C:("D_80BB407C","UNK_TYPE1","",0x1), @@ -16459,7 +16420,7 @@ 0x80BF5954:("D_80BF5954","UNK_TYPE1","",0x1), 0x80BF5960:("D_80BF5960","UNK_TYPE1","",0x1), 0x80BF596C:("D_80BF596C","UNK_TYPE1","",0x1), - 0x80BF59F0:("D_80BF59F0","EffTireMarkInit","",0x8), + 0x80BF59F0:("D_80BF59F0","EffectTireMarkInit","",0x8), 0x80BF59F8:("D_80BF59F8","UNK_TYPE1","",0x1), 0x80BF5A10:("D_80BF5A10","f32","",0x4), 0x80BF5A14:("D_80BF5A14","f32","",0x4), diff --git a/tools/extract_baserom.py b/tools/extract_baserom.py index a2734d900..bf9829bcb 100755 --- a/tools/extract_baserom.py +++ b/tools/extract_baserom.py @@ -44,7 +44,7 @@ FILE_NAMES = [ 'ovl_file_choose', 'ovl_daytelop', 'ovl_kaleido_scope', - 'ovl_Player_Actor', + 'ovl_player_actor', 'ovl_En_Test', 'ovl_En_GirlA', 'ovl_En_Part', diff --git a/tools/filelists/mm.us.rev1/all.csv b/tools/filelists/mm.us.rev1/all.csv index b722e4938..b76d241e1 100644 --- a/tools/filelists/mm.us.rev1/all.csv +++ b/tools/filelists/mm.us.rev1/all.csv @@ -36,7 +36,7 @@ 35,ovl_file_choose 36,ovl_daytelop 37,ovl_kaleido_scope -38,ovl_Player_Actor +38,ovl_player_actor 39,ovl_En_Test 40,ovl_En_GirlA 41,ovl_En_Part @@ -1537,3 +1537,16 @@ 1536,KAKUSIANA_room_13 1537,KAKUSIANA_room_14 1538,bump_texture_static +1539,anime_model_1_static +1540,anime_model_2_static +1541,anime_model_3_static +1542,anime_model_4_static +1543,anime_model_5_static +1544,anime_model_6_static +1545,anime_texture_1_static +1546,anime_texture_2_static +1547,anime_texture_3_static +1548,anime_texture_4_static +1549,anime_texture_5_static +1550,anime_texture_6_static +1551,softsprite_matrix_static diff --git a/tools/filelists/mm.us.rev1/archives.csv b/tools/filelists/mm.us.rev1/archives.csv new file mode 100644 index 000000000..a0b758dfd --- /dev/null +++ b/tools/filelists/mm.us.rev1/archives.csv @@ -0,0 +1,7 @@ +15,map_i_static +16,map_grand_static +17,item_name_static +18,map_name_static +19,icon_item_static_test +20,icon_item_24_static_test +22,schedule_dma_static_test diff --git a/tools/filelists/mm.us.rev1/asm.csv b/tools/filelists/mm.us.rev1/asm.csv index f3364252f..0bc9311e9 100644 --- a/tools/filelists/mm.us.rev1/asm.csv +++ b/tools/filelists/mm.us.rev1/asm.csv @@ -2,3 +2,5 @@ 1,boot 2,dmadata 31,code +1135,elf_message_field +1136,elf_message_ydan diff --git a/tools/filelists/mm.us.rev1/deleted.csv b/tools/filelists/mm.us.rev1/deleted.csv new file mode 100644 index 000000000..12e60f6ee --- /dev/null +++ b/tools/filelists/mm.us.rev1/deleted.csv @@ -0,0 +1,3 @@ +8,icon_item_static_old +9,icon_item_24_static_old +21,schedule_dma_static_old diff --git a/tools/filelists/mm.us.rev1/interface.csv b/tools/filelists/mm.us.rev1/interface.csv new file mode 100644 index 000000000..726df5467 --- /dev/null +++ b/tools/filelists/mm.us.rev1/interface.csv @@ -0,0 +1,13 @@ +6,kanji +10,icon_item_field_static +11,icon_item_dungeon_static +12,icon_item_gameover_static +13,icon_item_jpn_static +14,icon_item_vtx_static +23,schedule_static +25,do_action_static +26,message_static +27,message_texture_static +28,nes_font_static +1126,parameter_static +1127,week_static diff --git a/tools/filelists/mm.us.rev1/misc.csv b/tools/filelists/mm.us.rev1/misc.csv index 60a33ac1b..1d2c8bfa3 100644 --- a/tools/filelists/mm.us.rev1/misc.csv +++ b/tools/filelists/mm.us.rev1/misc.csv @@ -1,6 +1,21 @@ 7,link_animetion +24,story_static +1114,scene_texture_01 +1115,scene_texture_02 +1116,scene_texture_03 +1117,scene_texture_04 +1118,scene_texture_05 +1119,scene_texture_06 +1120,scene_texture_07 +1121,scene_texture_08 1122,nintendo_rogo_static +1123,title_static 1124,memerrmsg 1125,locerrmsg -1135,elf_message_field -1136,elf_message_ydan +1128,daytelop_static +1129,ger_daytelop_static +1130,fra_daytelop_static +1131,esp_daytelop_static +1132,d2_fine_static +1133,d2_cloud_static +1134,d2_fine_pal_static diff --git a/tools/filelists/mm.us.rev1/object.csv b/tools/filelists/mm.us.rev1/objects.csv similarity index 99% rename from tools/filelists/mm.us.rev1/object.csv rename to tools/filelists/mm.us.rev1/objects.csv index 15d1f4ac2..187ec1c11 100644 --- a/tools/filelists/mm.us.rev1/object.csv +++ b/tools/filelists/mm.us.rev1/objects.csv @@ -1,7 +1,6 @@ 649,gameplay_keep 650,gameplay_field_keep 651,gameplay_dangeon_keep -652,gameplay_object_exchange_static 653,object_link_boy 654,object_link_child 655,object_link_goron diff --git a/tools/filelists/mm.us.rev1/overlay.csv b/tools/filelists/mm.us.rev1/overlay.csv index 84943c794..a0ec8a58d 100644 --- a/tools/filelists/mm.us.rev1/overlay.csv +++ b/tools/filelists/mm.us.rev1/overlay.csv @@ -4,7 +4,7 @@ 35,ovl_file_choose 36,ovl_daytelop 37,ovl_kaleido_scope -38,ovl_Player_Actor +38,ovl_player_actor 39,ovl_En_Test 40,ovl_En_GirlA 41,ovl_En_Part diff --git a/tools/filelists/mm.us.rev1/scene.csv b/tools/filelists/mm.us.rev1/scenes.csv similarity index 100% rename from tools/filelists/mm.us.rev1/scene.csv rename to tools/filelists/mm.us.rev1/scenes.csv diff --git a/tools/filelists/mm.us.rev1/segments.csv b/tools/filelists/mm.us.rev1/segments.csv new file mode 100644 index 000000000..4362b8db6 --- /dev/null +++ b/tools/filelists/mm.us.rev1/segments.csv @@ -0,0 +1,15 @@ +652,gameplay_object_exchange_static +1538,bump_texture_static +1539,anime_model_1_static +1540,anime_model_2_static +1541,anime_model_3_static +1542,anime_model_4_static +1543,anime_model_5_static +1544,anime_model_6_static +1545,anime_texture_1_static +1546,anime_texture_2_static +1547,anime_texture_3_static +1548,anime_texture_4_static +1549,anime_texture_5_static +1550,anime_texture_6_static +1551,softsprite_matrix_static diff --git a/tools/filelists/mm.us.rev1/text.csv b/tools/filelists/mm.us.rev1/text.csv new file mode 100644 index 000000000..82e09e4dd --- /dev/null +++ b/tools/filelists/mm.us.rev1/text.csv @@ -0,0 +1,2 @@ +29,message_data_static +30,staff_message_data_static diff --git a/tools/filelists/mm.us.rev1/texture.csv b/tools/filelists/mm.us.rev1/texture.csv deleted file mode 100644 index 17e4a9cf7..000000000 --- a/tools/filelists/mm.us.rev1/texture.csv +++ /dev/null @@ -1,43 +0,0 @@ -6,kanji -8,icon_item_static_old -9,icon_item_24_static_old -10,icon_item_field_static -11,icon_item_dungeon_static -12,icon_item_gameover_static -13,icon_item_jpn_static -14,icon_item_vtx_static -15,map_i_static -16,map_grand_static -17,item_name_static -18,map_name_static -19,icon_item_static_test -20,icon_item_24_static_test -21,schedule_dma_static_old -22,schedule_dma_static_test -23,schedule_static -24,story_static -25,do_action_static -26,message_static -27,message_texture_static -28,nes_font_static -29,message_data_static -30,staff_message_data_static -1114,scene_texture_01 -1115,scene_texture_02 -1116,scene_texture_03 -1117,scene_texture_04 -1118,scene_texture_05 -1119,scene_texture_06 -1120,scene_texture_07 -1121,scene_texture_08 -1123,title_static -1126,parameter_static -1127,week_static -1128,daytelop_static -1129,ger_daytelop_static -1130,fra_daytelop_static -1131,esp_daytelop_static -1132,d2_fine_static -1133,d2_cloud_static -1134,d2_fine_pal_static -1538,bump_texture_static diff --git a/tools/ido_recomp/linux/5.3/as1 b/tools/ido_recomp/linux/5.3/as1 index 17ff2aa7c..41c2545af 100755 Binary files a/tools/ido_recomp/linux/5.3/as1 and b/tools/ido_recomp/linux/5.3/as1 differ diff --git a/tools/ido_recomp/linux/5.3/cc b/tools/ido_recomp/linux/5.3/cc index 6dbb85eb1..3dcc53798 100755 Binary files a/tools/ido_recomp/linux/5.3/cc and b/tools/ido_recomp/linux/5.3/cc differ diff --git a/tools/ido_recomp/linux/5.3/cfe b/tools/ido_recomp/linux/5.3/cfe index d742f7b2e..e9594fafc 100755 Binary files a/tools/ido_recomp/linux/5.3/cfe and b/tools/ido_recomp/linux/5.3/cfe differ diff --git a/tools/ido_recomp/linux/5.3/ugen b/tools/ido_recomp/linux/5.3/ugen index 692086f0c..b2b662f1d 100755 Binary files a/tools/ido_recomp/linux/5.3/ugen and b/tools/ido_recomp/linux/5.3/ugen differ diff --git a/tools/ido_recomp/linux/5.3/ujoin b/tools/ido_recomp/linux/5.3/ujoin new file mode 100644 index 000000000..f9c90b8be Binary files /dev/null and b/tools/ido_recomp/linux/5.3/ujoin differ diff --git a/tools/ido_recomp/linux/5.3/uld b/tools/ido_recomp/linux/5.3/uld new file mode 100644 index 000000000..f227222bc Binary files /dev/null and b/tools/ido_recomp/linux/5.3/uld differ diff --git a/tools/ido_recomp/linux/5.3/umerge b/tools/ido_recomp/linux/5.3/umerge new file mode 100644 index 000000000..00a8281d2 Binary files /dev/null and b/tools/ido_recomp/linux/5.3/umerge differ diff --git a/tools/ido_recomp/linux/5.3/uopt b/tools/ido_recomp/linux/5.3/uopt index 49558be9f..5afe7a11c 100755 Binary files a/tools/ido_recomp/linux/5.3/uopt and b/tools/ido_recomp/linux/5.3/uopt differ diff --git a/tools/ido_recomp/linux/5.3/usplit b/tools/ido_recomp/linux/5.3/usplit new file mode 100644 index 000000000..a1c5ebad6 Binary files /dev/null and b/tools/ido_recomp/linux/5.3/usplit differ diff --git a/tools/ido_recomp/linux/7.1/as1 b/tools/ido_recomp/linux/7.1/as1 index a7bb3adc3..01dbc6f6b 100755 Binary files a/tools/ido_recomp/linux/7.1/as1 and b/tools/ido_recomp/linux/7.1/as1 differ diff --git a/tools/ido_recomp/linux/7.1/cc b/tools/ido_recomp/linux/7.1/cc index e926b545e..a7f06afa8 100755 Binary files a/tools/ido_recomp/linux/7.1/cc and b/tools/ido_recomp/linux/7.1/cc differ diff --git a/tools/ido_recomp/linux/7.1/cfe b/tools/ido_recomp/linux/7.1/cfe index 3a3e98313..2c6767e69 100755 Binary files a/tools/ido_recomp/linux/7.1/cfe and b/tools/ido_recomp/linux/7.1/cfe differ diff --git a/tools/ido_recomp/linux/7.1/ugen b/tools/ido_recomp/linux/7.1/ugen index e8e875635..f5c1a2e20 100755 Binary files a/tools/ido_recomp/linux/7.1/ugen and b/tools/ido_recomp/linux/7.1/ugen differ diff --git a/tools/ido_recomp/linux/7.1/umerge b/tools/ido_recomp/linux/7.1/umerge new file mode 100644 index 000000000..b0c8c1778 Binary files /dev/null and b/tools/ido_recomp/linux/7.1/umerge differ diff --git a/tools/ido_recomp/linux/7.1/uopt b/tools/ido_recomp/linux/7.1/uopt index fd93d2dc5..ecf7eab72 100755 Binary files a/tools/ido_recomp/linux/7.1/uopt and b/tools/ido_recomp/linux/7.1/uopt differ diff --git a/tools/ido_recomp/macos/5.3/acpp b/tools/ido_recomp/macos/5.3/acpp new file mode 100755 index 000000000..043162770 Binary files /dev/null and b/tools/ido_recomp/macos/5.3/acpp differ diff --git a/tools/ido_recomp/macos/5.3/as0 b/tools/ido_recomp/macos/5.3/as0 new file mode 100755 index 000000000..9cff1dcd7 Binary files /dev/null and b/tools/ido_recomp/macos/5.3/as0 differ diff --git a/tools/ido_recomp/macos/5.3/as1 b/tools/ido_recomp/macos/5.3/as1 index 692fe600c..df0142e86 100755 Binary files a/tools/ido_recomp/macos/5.3/as1 and b/tools/ido_recomp/macos/5.3/as1 differ diff --git a/tools/ido_recomp/macos/5.3/cc b/tools/ido_recomp/macos/5.3/cc index 90ffc7409..e9b599bda 100755 Binary files a/tools/ido_recomp/macos/5.3/cc and b/tools/ido_recomp/macos/5.3/cc differ diff --git a/tools/ido_recomp/macos/5.3/cfe b/tools/ido_recomp/macos/5.3/cfe index 753be0d6c..30e514947 100755 Binary files a/tools/ido_recomp/macos/5.3/cfe and b/tools/ido_recomp/macos/5.3/cfe differ diff --git a/tools/ido_recomp/macos/5.3/copt b/tools/ido_recomp/macos/5.3/copt new file mode 100755 index 000000000..243c37a29 Binary files /dev/null and b/tools/ido_recomp/macos/5.3/copt differ diff --git a/tools/ido_recomp/macos/5.3/err.english.cc b/tools/ido_recomp/macos/5.3/err.english.cc old mode 100755 new mode 100644 diff --git a/tools/ido_recomp/macos/5.3/ugen b/tools/ido_recomp/macos/5.3/ugen index c7020aa49..7f18bf44b 100755 Binary files a/tools/ido_recomp/macos/5.3/ugen and b/tools/ido_recomp/macos/5.3/ugen differ diff --git a/tools/ido_recomp/macos/5.3/ujoin b/tools/ido_recomp/macos/5.3/ujoin new file mode 100755 index 000000000..30503f95d Binary files /dev/null and b/tools/ido_recomp/macos/5.3/ujoin differ diff --git a/tools/ido_recomp/macos/5.3/uld b/tools/ido_recomp/macos/5.3/uld new file mode 100755 index 000000000..13aa261f5 Binary files /dev/null and b/tools/ido_recomp/macos/5.3/uld differ diff --git a/tools/ido_recomp/macos/5.3/umerge b/tools/ido_recomp/macos/5.3/umerge new file mode 100755 index 000000000..c31c866d5 Binary files /dev/null and b/tools/ido_recomp/macos/5.3/umerge differ diff --git a/tools/ido_recomp/macos/5.3/uopt b/tools/ido_recomp/macos/5.3/uopt index e23f6beda..7bbaac298 100755 Binary files a/tools/ido_recomp/macos/5.3/uopt and b/tools/ido_recomp/macos/5.3/uopt differ diff --git a/tools/ido_recomp/macos/5.3/usplit b/tools/ido_recomp/macos/5.3/usplit new file mode 100755 index 000000000..a95984803 Binary files /dev/null and b/tools/ido_recomp/macos/5.3/usplit differ diff --git a/tools/ido_recomp/macos/7.1/as1 b/tools/ido_recomp/macos/7.1/as1 index 358712e33..88b9f1f7e 100755 Binary files a/tools/ido_recomp/macos/7.1/as1 and b/tools/ido_recomp/macos/7.1/as1 differ diff --git a/tools/ido_recomp/macos/7.1/cc b/tools/ido_recomp/macos/7.1/cc index fb6810347..ae54cdbcd 100755 Binary files a/tools/ido_recomp/macos/7.1/cc and b/tools/ido_recomp/macos/7.1/cc differ diff --git a/tools/ido_recomp/macos/7.1/cfe b/tools/ido_recomp/macos/7.1/cfe index 1e1322862..6c468c336 100755 Binary files a/tools/ido_recomp/macos/7.1/cfe and b/tools/ido_recomp/macos/7.1/cfe differ diff --git a/tools/ido_recomp/macos/7.1/err.english.cc b/tools/ido_recomp/macos/7.1/err.english.cc old mode 100755 new mode 100644 diff --git a/tools/ido_recomp/macos/7.1/ugen b/tools/ido_recomp/macos/7.1/ugen index fe90904a4..3fa7d48fc 100755 Binary files a/tools/ido_recomp/macos/7.1/ugen and b/tools/ido_recomp/macos/7.1/ugen differ diff --git a/tools/ido_recomp/macos/7.1/umerge b/tools/ido_recomp/macos/7.1/umerge new file mode 100755 index 000000000..3a9d5440c Binary files /dev/null and b/tools/ido_recomp/macos/7.1/umerge differ diff --git a/tools/ido_recomp/macos/7.1/uopt b/tools/ido_recomp/macos/7.1/uopt index bb68f5d53..b025fa2c5 100755 Binary files a/tools/ido_recomp/macos/7.1/uopt and b/tools/ido_recomp/macos/7.1/uopt differ diff --git a/tools/overlayhelpers/actor_symbols.py b/tools/overlayhelpers/actor_symbols.py index 88aa8aa40..e3f079ad9 100755 --- a/tools/overlayhelpers/actor_symbols.py +++ b/tools/overlayhelpers/actor_symbols.py @@ -3,7 +3,7 @@ import argparse, os, struct actor_names = [ - "ovl_Player_Actor", + "ovl_player_actor", "ovl_En_Test", "ovl_En_GirlA", "ovl_En_Part", @@ -719,7 +719,7 @@ def read_actor_ovl_tbl(): actortbl.append((actor_names[i], entry[0], entry[1], entry[2], entry[3])) entry = as_word_list(codefile.read(0x20)) i += 1 - actortbl[0] = ['ovl_Player_Actor', 0xCA7F00, 0xCDCF60, 0x8082DA90, 0x80862B70 ] + actortbl[0] = ['ovl_player_actor', 0xCA7F00, 0xCDCF60, 0x8082DA90, 0x80862B70 ] return actortbl actor_tbl = read_actor_ovl_tbl() diff --git a/tools/progress.py b/tools/progress.py index a5068f792..dccd743d7 100755 --- a/tools/progress.py +++ b/tools/progress.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -import argparse, csv, git, json, os, re +import argparse, csv, git, json, os, re, sys parser = argparse.ArgumentParser() @@ -12,9 +12,18 @@ args = parser.parse_args() NON_MATCHING_PATTERN = r'#ifdef\s+NON_MATCHING.*?#pragma\s+GLOBAL_ASM\s*\(\s*"(.*?)"\s*\).*?#endif' NOT_ATTEMPTED_PATTERN = r'#pragma\s+GLOBAL_ASM\s*\(\s*"(.*?)"\s*\)' +# This is the format ZAPD uses to autogenerate variable names +# It should not be used for properly documented variables +AUTOGENERATED_ASSET_NAME = re.compile(r".+0[0-9A-Fa-f]{5}") + +ASM_JMP_LABEL = re.compile(r"^(?PL[0-9A-F]{8})$") + # TODO: consider making this a parameter of this script GAME_VERSION = "mm.us.rev1" +def eprint(*args, **kwargs): + print(*args, file=sys.stderr, **kwargs) + def GetFunctionsByPattern(pattern, files): functions = [] @@ -46,31 +55,69 @@ def GetCsvFilelist(version, filelist): with open(path, newline='') as f: return list(csv.reader(f, delimiter=',')) -def GetRemovableSize(functions_to_count): +def GetRemovableSize(functionSizes, functions_to_count): size = 0 - for asm_file_path in functions_to_count: - if "//" in asm_file_path: - raise RuntimeError(f"Invalid file path: {asm_file_path}") - file_size = 0 - asm_lines = ReadAllLines(asm_file_path) - shouldCount = True - - for asm_line in asm_lines: - if asm_line[0] == ".": - if asm_line.startswith(".text") or asm_line.startswith(".section .text"): - shouldCount = True - elif ".rdata" in asm_line or ".late_rodata" in asm_line: - shouldCount = False - - if shouldCount: - if (asm_line[0:2] == "/*" and asm_line[28:30] == "*/"): - file_size += 4 - - size += file_size + for func in functions_to_count: + if func in functionSizes: + size += functionSizes[func] return size +def CalculateMapSizes(mapFileList): + for mapFile in mapFileList: + accumulatedSize = 0 + + symbolCount = len(mapFile["symbols"]) + if symbolCount == 0: + continue + + # Calculate size of each symbol + for index in range(symbolCount - 1): + symbol = mapFile["symbols"][index] + nextSymbol = mapFile["symbols"][index+1] + + size = nextSymbol["vram"] - symbol["vram"] + accumulatedSize += size + + mapFile["symbols"][index]["size"] = size + + # Calculate size of last symbol of the file + symbol = mapFile["symbols"][-1] + size = mapFile["size"] - accumulatedSize + mapFile["symbols"][-1]["size"] = size + return mapFileList + +def GetFunctionSizes(mapFileList): + functionSizes = dict() + + for mapFile in mapFileList: + if mapFile["section"] != ".text": + continue + + for symbol in mapFile["symbols"]: + symbolName = symbol["name"] + functionSizes[symbolName] = symbol["size"] + + return functionSizes + +def CalculateNonNamedAssets(mapFileList, assetsTracker): + for mapFile in mapFileList: + if mapFile["section"] != ".data": + continue + if not mapFile["name"].startswith("build/assets/"): + continue + + assetCat = mapFile["name"].split("/")[2] + + for symbol in mapFile["symbols"]: + symbolName = symbol["name"] + if AUTOGENERATED_ASSET_NAME.search(symbolName) is not None: + if assetCat in assetsTracker: + assetsTracker[assetCat]["removableSize"] += symbol["size"] + return assetsTracker + + map_file = ReadAllLines('build/mm.map') # Get list of Non-Matchings @@ -86,91 +133,146 @@ not_attempted_functions = list(set(not_attempted_functions).difference(non_match if not args.matching: non_matching_functions = [] -# Get asset files -audio_files = GetCsvFilelist(GAME_VERSION, "audio.csv") -misc_files = GetCsvFilelist(GAME_VERSION, "misc.csv") -object_files = GetCsvFilelist(GAME_VERSION, "object.csv") -scene_files = GetCsvFilelist(GAME_VERSION, "scene.csv") -texture_files = GetCsvFilelist(GAME_VERSION, "texture.csv") +# The order of this list should not change to prevent breaking the graph of the website +# New stuff shall be appended at the end of the list +assetsCategories = [ + "archives", + "audio", + "interface", + "misc", + "objects", + "scenes", + "text", + # "deleted", + # "segments", +] +assetsTracker = dict() + +# Manual fixer for files that would be counted in wrong categories +# "filename": "correctSection" +fileSectionFixer = { + "osFlash": "code" # Currently in `src/libultra` (would be counted as boot) +} + +for assetCat in assetsCategories: + assetsTracker[assetCat] = dict() + # Get asset files + assetsTracker[assetCat]["files"] = GetCsvFilelist(GAME_VERSION, f"{assetCat}.csv") + assetsTracker[assetCat]["currentSize"] = 0 + assetsTracker[assetCat]["removableSize"] = 0 + assetsTracker[assetCat]["totalSize"] = 0 + assetsTracker[assetCat]["percent"] = 0 + # Initialize all the code values -src = 0 -src_code = 0 -src_boot = 0 -src_ovl = 0 -src_libultra = 0 -asm = 0 -asm_code = 0 -asm_boot = 0 -asm_ovl = 0 -asm_libultra = 0 -audio = 0 -misc = 0 -object_ = 0 -scene = 0 -texture = 0 +srcCategories = [ + "boot", + "libultra", + "code", + "overlays", +] + +srcCategoriesFixer = { + "boot_O2": "boot", + "boot_O2_g3": "boot", +} + +srcTracker = dict() +asmTracker = dict() + +for srcCat in srcCategories: + srcTracker[srcCat] = dict() + srcTracker[srcCat]["currentSize"] = 0 + srcTracker[srcCat]["totalSize"] = 0 + srcTracker[srcCat]["percent"] = 0 + + asmTracker[srcCat] = dict() + asmTracker[srcCat]["currentSize"] = 0 + asmTracker[srcCat]["totalSize"] = 0 + asmTracker[srcCat]["percent"] = 0 + +mapFileList = [] for line in map_file: line_split = list(filter(None, line.split(" "))) if (len(line_split) == 4 and line_split[0].startswith(".")): section = line_split[0] + obj_vram = int(line_split[1], 16) file_size = int(line_split[2], 16) - obj_file = line_split[3] + obj_file = line_split[3].strip() + objFileSplit = obj_file.split("/") + + fileData = {"name": obj_file, "vram": obj_vram, "size": file_size, "section": section, "symbols": []} + mapFileList.append(fileData) if (section == ".text"): - if (obj_file.startswith("build/src")): - if (obj_file.startswith("build/src/code")): - src_code += file_size - elif (obj_file.startswith("build/src/libultra")): - src_libultra += file_size - elif (obj_file.startswith("build/src/boot")): - src_boot += file_size - elif (obj_file.startswith("build/src/overlays")): - src_ovl += file_size + objFileName = objFileSplit[-1].split(".o")[0] + srcCat = obj_file.split("/")[2] + if srcCat in srcCategoriesFixer: + srcCat = srcCategoriesFixer[srcCat] + + if objFileName in fileSectionFixer: + correctSection = fileSectionFixer[objFileName] + if correctSection in srcTracker: + srcTracker[correctSection]["totalSize"] += file_size + elif obj_file.startswith("build/src"): + if srcCat in srcTracker: + srcTracker[srcCat]["totalSize"] += file_size elif (obj_file.startswith("build/asm")): - if (obj_file.startswith("build/asm/code")): - asm_code += file_size - elif (obj_file.startswith("build/asm/libultra")): - asm_libultra += file_size - elif (obj_file.startswith("build/asm/boot")): - asm_boot += file_size - elif (obj_file.startswith("build/asm/overlays")): - asm_ovl += file_size + if srcCat in asmTracker: + asmTracker[srcCat]["totalSize"] += file_size + + if section == ".data": + if obj_file.startswith("build/assets/"): + assetCat = obj_file.split("/")[2] + if assetCat in assetsTracker: + assetsTracker[assetCat]["currentSize"] += file_size + else: + eprint(f"Found file '{obj_file}' in unknown asset category '{assetCat}'") + eprint("I'll ignore this for now, but please fix it!") + + elif len(line_split) == 2 and line_split[0].startswith("0x00000000"): + varVramStr, varName = line_split + varVram = int(varVramStr, 16) + varName = varName.strip() + if varName == "0x0": + continue + if ASM_JMP_LABEL.search(varName) is not None: + # Filter out jump table's labels + continue + symbolData = {"name": varName, "vram": varVram, "size": 0} + mapFileList[-1]["symbols"].append(symbolData) + +mapFileList = CalculateMapSizes(mapFileList) +functionSizes = GetFunctionSizes(mapFileList) + +assetsTracker = CalculateNonNamedAssets(mapFileList, assetsTracker) - if (section == ".data"): - if (obj_file.startswith("build/assets/audio")): - audio += file_size - elif (obj_file.startswith("build/assets/misc")): - misc += file_size - elif (obj_file.startswith("build/assets/objects")): - object_ += file_size - elif (obj_file.startswith("build/assets/scenes")): - scene += file_size - elif (obj_file.startswith("build/assets/textures")): - texture += file_size # Add libultra to boot. -src_boot += src_libultra -asm_boot += asm_libultra +srcTracker["boot"]["totalSize"] += srcTracker["libultra"]["totalSize"] +asmTracker["boot"]["totalSize"] += asmTracker["libultra"]["totalSize"] +del srcTracker["libultra"] +del asmTracker["libultra"] # Calculate Non-Matching -non_matching_functions_ovl = list(filter(lambda x: "/overlays/" in x, non_matching_functions)) -non_matching_functions_code = list(filter(lambda x: "/code/" in x, non_matching_functions)) -non_matching_functions_boot = list(filter(lambda x: "/boot/" in x, non_matching_functions)) +non_matching_functions_ovl = list(map(lambda x: x.split("/")[-1].split(".")[0], filter(lambda x: "/overlays/" in x, non_matching_functions))) +non_matching_functions_code = list(map(lambda x: x.split("/")[-1].split(".")[0], filter(lambda x: "/code/" in x, non_matching_functions))) +non_matching_functions_boot = list(map(lambda x: x.split("/")[-1].split(".")[0], filter(lambda x: "/boot/" in x, non_matching_functions))) -non_matching_asm_ovl = GetRemovableSize(non_matching_functions_ovl) -non_matching_asm_code = GetRemovableSize(non_matching_functions_code) -non_matching_asm_boot = GetRemovableSize(non_matching_functions_boot) +non_matching_asm_ovl = GetRemovableSize(functionSizes, non_matching_functions_ovl) +non_matching_asm_code = GetRemovableSize(functionSizes, non_matching_functions_code) +non_matching_asm_boot = GetRemovableSize(functionSizes, non_matching_functions_boot) # Calculate Not Attempted -not_attempted_functions_ovl = list(filter(lambda x: "/overlays/" in x, not_attempted_functions)) -not_attempted_functions_code = list(filter(lambda x: "/code/" in x, not_attempted_functions)) -not_attempted_functions_boot = list(filter(lambda x: "/boot/" in x, not_attempted_functions)) +not_attempted_functions_ovl = list(map(lambda x: x.split("/")[-1].split(".")[0], filter(lambda x: "/overlays/" in x, not_attempted_functions))) +not_attempted_functions_code = list(map(lambda x: x.split("/")[-1].split(".")[0], filter(lambda x: "/code/" in x, not_attempted_functions))) +not_attempted_functions_boot = list(map(lambda x: x.split("/")[-1].split(".")[0], filter(lambda x: "/boot/" in x, not_attempted_functions))) -not_attempted_asm_ovl = GetRemovableSize(not_attempted_functions_ovl) -not_attempted_asm_code = GetRemovableSize(not_attempted_functions_code) -not_attempted_asm_boot = GetRemovableSize(not_attempted_functions_boot) +not_attempted_asm_ovl = GetRemovableSize(functionSizes, not_attempted_functions_ovl) +not_attempted_asm_code = GetRemovableSize(functionSizes, not_attempted_functions_code) +not_attempted_asm_boot = GetRemovableSize(functionSizes, not_attempted_functions_boot) # All the non matching asm is the sum of non-matching code non_matching_asm = non_matching_asm_ovl + non_matching_asm_code + non_matching_asm_boot @@ -179,60 +281,52 @@ non_matching_asm = non_matching_asm_ovl + non_matching_asm_code + non_matching_a not_attempted_asm = not_attempted_asm_ovl + not_attempted_asm_code + not_attempted_asm_boot # Calculate total decompiled for each bucket by taking out the non-matching and not attempted in ovl/code/boot buckets. -code = src_code - (non_matching_asm_code + not_attempted_asm_code) -boot = src_boot - (non_matching_asm_boot + not_attempted_asm_boot) -ovl = src_ovl - (non_matching_asm_ovl + not_attempted_asm_ovl) +srcTracker["code"]["currentSize"] = srcTracker["code"]["totalSize"] - (non_matching_asm_code + not_attempted_asm_code) +srcTracker["boot"]["currentSize"] = srcTracker["boot"]["totalSize"] - (non_matching_asm_boot + not_attempted_asm_boot) +srcTracker["overlays"]["currentSize"] = srcTracker["overlays"]["totalSize"] - (non_matching_asm_ovl + not_attempted_asm_ovl) # Total code bucket sizes -code_size = src_code + asm_code -boot_size = src_boot + asm_boot -ovl_size = src_ovl + asm_ovl -handwritten = 0 # Currently unsure of any handwritten asm in MM - -# Calculate size of all assets -audio_size = 0 -misc_size = 0 -object_size = 0 -scene_size = 0 -texture_size = 0 -for index, f in audio_files: - audio_size += os.stat(os.path.join("baserom", f)).st_size -for index, f in misc_files: - misc_size += os.stat(os.path.join("baserom", f)).st_size -for index, f in object_files: - object_size += os.stat(os.path.join("baserom", f)).st_size -for index, f in scene_files: - scene_size += os.stat(os.path.join("baserom", f)).st_size -for index, f in texture_files: - texture_size += os.stat(os.path.join("baserom", f)).st_size - -# Calculate asm and src totals -src = src_code + src_boot + src_ovl -asm = asm_code + asm_boot + asm_ovl - -# Take out the non-matchings and not attempted in grand totals -src -= non_matching_asm + not_attempted_asm -asm += non_matching_asm + not_attempted_asm +handwritten = 0 +for srcCat in asmTracker: + handwritten += asmTracker[srcCat]["totalSize"] # Calculate the total amount of decompilable code -total = src + asm +total = 0 +for srcCat in asmTracker: + total += srcTracker[srcCat]["totalSize"] + +# Calculate size of all assets +for assetCat in assetsTracker: + for index, f in assetsTracker[assetCat]["files"]: + assetsTracker[assetCat]["totalSize"] += os.stat(os.path.join("baserom", f)).st_size + +if args.matching: + for assetCat in assetsTracker: + assetsTracker[assetCat]["currentSize"] -= assetsTracker[assetCat]["removableSize"] + +# Calculate asm and src totals +src = 0 +for srcCat in srcTracker: + src += srcTracker[srcCat]["currentSize"] +asm = 0 +for srcCat in asmTracker: + asm += asmTracker[srcCat]["totalSize"] +asm += non_matching_asm + not_attempted_asm # Calculate assets totals -assets = audio + misc + object_ + scene + texture -assets_total = audio_size + misc_size + object_size + scene_size + texture_size +assets = sum(x["currentSize"] for x in assetsTracker.values()) +assets_total = sum(x["totalSize"] for x in assetsTracker.values()) # Convert vaules to percentages src_percent = 100 * src / total asm_percent = 100 * asm / total -code_percent = 100 * code / code_size -boot_percent = 100 * boot / boot_size -ovl_percent = 100 * ovl / ovl_size +for srcCat in ["boot", "code", "overlays"]: + srcTracker[srcCat]["percent"] = 100 * srcTracker[srcCat]["currentSize"] / srcTracker[srcCat]["totalSize"] + assets_percent = 100 * assets / assets_total -audio_percent = 100 * audio / audio_size -misc_percent = 100 * misc / misc_size -object_percent = 100 * object_ / object_size -scene_percent = 100 * scene / scene_size -texture_percent = 100 * texture / texture_size + +for assetCat in assetsTracker: + assetsTracker[assetCat]["percent"] = 100 * assetsTracker[assetCat]["currentSize"] / assetsTracker[assetCat]["totalSize"] # convert bytes to masks and rupees num_masks = 24 @@ -242,47 +336,27 @@ bytes_per_rupee = bytes_per_mask / max_rupees masks = int(src / bytes_per_mask) rupees = int((src % bytes_per_mask) / bytes_per_rupee) -# Debug print statements for the values -#print("Total: ", total) -#print("src: ", src) -#print("asm: ", asm) -#print("") -#print("src_code: ", src_code) -#print("src_boot: ", src_boot) -#print("src_ovl: ", src_ovl) -#print("") -#print("asm_code: ", asm_code) -#print("asm_boot: ", asm_boot) -#print("asm_ovl: ", asm_ovl) -#print("") -#print("Nonmatching code: ", non_matching_asm_code) -#print("Nonmatching boot: ", non_matching_asm_boot) -#print("Nonmatching ovl: ", non_matching_asm_ovl) -#print("") -#print("Not attempted code: ", not_attempted_asm_code) -#print("Not attempted boot: ", not_attempted_asm_boot) -#print("Not attempted ovl: ", not_attempted_asm_ovl) -#print("") -#print("code_size: ", code_size) -#print("boot_size: ", boot_size) -#print("ovl_size: ", ovl_size) -#print("") -#print("code: ", code) -#print("boot: ", boot) -#print("ovl: ", ovl) -#print("") - if args.format == 'csv': - version = 1 + version = 2 git_object = git.Repo().head.object timestamp = str(git_object.committed_date) git_hash = git_object.hexsha - csv_list = [str(version), timestamp, git_hash, str(code), str(code_size), str(boot), str(boot_size), - str(ovl), str(ovl_size), str(src), str(asm), str(len(non_matching_functions)), - str(audio), str(audio_size), str(misc), str(misc_size), str(object_), str(object_size), - str(scene), str(scene_size), str(texture), str(texture_size)] + csv_list = [ + version, timestamp, git_hash, src, total, + ] + for srcCat in ["boot", "code", "overlays"]: + csv_list += [srcTracker[srcCat]["currentSize"], srcTracker[srcCat]["totalSize"]] - print(",".join(csv_list)) + csv_list += [ + asm, len(non_matching_functions), + ] + csv_list += [ + assets, assets_total, + ] + for assetCat in assetsCategories: + csv_list += [assetsTracker[assetCat]["currentSize"], assetsTracker[assetCat]["totalSize"]] + + print(",".join(map(str, csv_list))) elif args.format == 'shield-json': # https://shields.io/endpoint print(json.dumps({ @@ -293,18 +367,20 @@ elif args.format == 'shield-json': })) elif args.format == 'text': adjective = "decompiled" if not args.matching else "matched" + assetsAdjective = "debinarized" if not args.matching else "identified" - print("src: {:>9} / {:>8} total bytes {:<13} {:>9.4f}%".format(src, total, adjective, round(src_percent, 4))) - print(" boot: {:>9} / {:>8} bytes {:<13} {:>9.4f}%".format(boot, boot_size, adjective, round(boot_percent, 4))) - print(" code: {:>9} / {:>8} bytes {:<13} {:>9.4f}%".format(code, code_size, adjective, round(code_percent, 4))) - print(" overlays: {:>9} / {:>8} bytes {:<13} {:>9.4f}%".format(ovl, ovl_size, adjective, round(ovl_percent, 4))) + print("src: {:>9} / {:>8} total bytes {:<13} {:>9.4f}%".format(src, total, adjective, round(src_percent, 4))) + + for srcCat in ["boot", "code", "overlays"]: + src = srcTracker[srcCat] + print(" {:<10} {:>9} / {:>8} bytes {:<13} {:>9.4f}%".format(f"{srcCat}:", src["currentSize"], src["totalSize"], adjective, round(src["percent"], 4))) print() - print("assets: {:>9} / {:>8} bytes reconstructed {:>9.4f}%".format(assets, assets_total, round(assets_percent, 4))) - print(" audio: {:>9} / {:>8} bytes reconstructed {:>9.4f}%".format(audio, audio_size, round(audio_percent, 4))) - print(" misc: {:>9} / {:>8} bytes reconstructed {:>9.4f}%".format(misc, misc_size, round(misc_percent, 4))) - print(" objects: {:>9} / {:>8} bytes reconstructed {:>9.4f}%".format(object_, object_size, round(object_percent, 4))) - print(" scenes: {:>9} / {:>8} bytes reconstructed {:>9.4f}%".format(scene, scene_size, round(scene_percent, 4))) - print(" textures: {:>9} / {:>8} bytes reconstructed {:>9.4f}%".format(texture, texture_size, round(texture_percent, 4))) + + print("assets: {:>9} / {:>8} total bytes {:<13} {:>9.4f}%".format(assets, assets_total, assetsAdjective, round(assets_percent, 4))) + for assetCat in assetsTracker: + data = assetsTracker[assetCat] + print(" {:<10} {:>9} / {:>8} bytes {:<13} {:>9.4f}%".format(f"{assetCat}:", data["currentSize"], data["totalSize"], assetsAdjective, round(data["percent"], 4))) + print() print("------------------------------------\n") diff --git a/tools/rename_sym.sh b/tools/rename_sym.sh index e68966ca7..227db4df7 100755 --- a/tools/rename_sym.sh +++ b/tools/rename_sym.sh @@ -10,4 +10,4 @@ fi #echo "Replace $1 with $2?" #read -grep -rl "$1" asm/**/*.s src/**/*.{c,h} include/**/*.h tools/disasm/functions.txt tools/disasm/variables.txt | xargs sed -i "s/\b$1\b/$2/g" \ No newline at end of file +grep -rl "$1" asm/**/*.s src/**/*.{c,h} include/**/*.h tools/disasm/functions.txt tools/disasm/variables.txt tools/sizes/*.csv | xargs sed -i "s/\b$1\b/$2/g" diff --git a/tools/sizes/code_functions.csv b/tools/sizes/code_functions.csv index 7425d5a1b..59f063e10 100644 --- a/tools/sizes/code_functions.csv +++ b/tools/sizes/code_functions.csv @@ -25,28 +25,28 @@ asm/non_matchings/code/z_en_item00/Item_DropCollectibleRandom.s,Item_DropCollect asm/non_matchings/code/z_en_item00/func_800A8150.s,func_800A8150,0x800A8150,0xB asm/non_matchings/code/z_en_item00/func_800A817C.s,func_800A817C,0x800A817C,0xA asm/non_matchings/code/z_en_item00/func_800A81A4.s,func_800A81A4,0x800A81A4,0x13 -asm/non_matchings/code/z_eff_blure/func_800A81F0.s,func_800A81F0,0x800A81F0,0xC9 -asm/non_matchings/code/z_eff_blure/func_800A8514.s,func_800A8514,0x800A8514,0x11 -asm/non_matchings/code/z_eff_blure/EffectBlure_Initcommon.s,EffectBlure_Initcommon,0x800A8558,0x2E +asm/non_matchings/code/z_eff_blure/EffectBlure_AddVertex.s,EffectBlure_AddVertex,0x800A81F0,0xC9 +asm/non_matchings/code/z_eff_blure/EffectBlure_AddSpace.s,EffectBlure_AddSpace,0x800A8514,0x11 +asm/non_matchings/code/z_eff_blure/EffectBlure_InitElements.s,EffectBlure_InitElements,0x800A8558,0x2E asm/non_matchings/code/z_eff_blure/EffectBlure_Init1.s,EffectBlure_Init1,0x800A8610,0x44 asm/non_matchings/code/z_eff_blure/EffectBlure_Init2.s,EffectBlure_Init2,0x800A8720,0x4D asm/non_matchings/code/z_eff_blure/EffectBlure_Destroy.s,EffectBlure_Destroy,0x800A8854,0x3 asm/non_matchings/code/z_eff_blure/EffectBlure_Update.s,EffectBlure_Update,0x800A8860,0x106 -asm/non_matchings/code/z_eff_blure/func_800A8C78.s,func_800A8C78,0x800A8C78,0x5C -asm/non_matchings/code/z_eff_blure/func_800A8DE8.s,func_800A8DE8,0x800A8DE8,0x145 -asm/non_matchings/code/z_eff_blure/func_800A92FC.s,func_800A92FC,0x800A92FC,0xD -asm/non_matchings/code/z_eff_blure/func_800A9330.s,func_800A9330,0x800A9330,0x135 -asm/non_matchings/code/z_eff_blure/func_800A9804.s,func_800A9804,0x800A9804,0x263 -asm/non_matchings/code/z_eff_blure/func_800AA190.s,func_800AA190,0x800AA190,0xB4 -asm/non_matchings/code/z_eff_blure/func_800AA460.s,func_800AA460,0x800AA460,0xE -asm/non_matchings/code/z_eff_blure/func_800AA498.s,func_800AA498,0x800AA498,0x9A -asm/non_matchings/code/z_eff_blure/func_800AA700.s,func_800AA700,0x800AA700,0x138 -asm/non_matchings/code/z_eff_blure/func_800AABE0.s,func_800AABE0,0x800AABE0,0x143 +asm/non_matchings/code/z_eff_blure/EffectBlure_UpdateFlags.s,EffectBlure_UpdateFlags,0x800A8C78,0x5C +asm/non_matchings/code/z_eff_blure/EffectBlure_GetComputedValues.s,EffectBlure_GetComputedValues,0x800A8DE8,0x145 +asm/non_matchings/code/z_eff_blure/EffectBlure_SetupSmooth.s,EffectBlure_SetupSmooth,0x800A92FC,0xD +asm/non_matchings/code/z_eff_blure/EffectBlure_DrawElemNoInterpolation.s,EffectBlure_DrawElemNoInterpolation,0x800A9330,0x135 +asm/non_matchings/code/z_eff_blure/EffectBlure_DrawElemHermiteInterpolation.s,EffectBlure_DrawElemHermiteInterpolation,0x800A9804,0x263 +asm/non_matchings/code/z_eff_blure/EffectBlure_DrawSmooth.s,EffectBlure_DrawSmooth,0x800AA190,0xB4 +asm/non_matchings/code/z_eff_blure/EffectBlure_SetupSimple.s,EffectBlure_SetupSimple,0x800AA460,0xE +asm/non_matchings/code/z_eff_blure/EffectBlure_SetupSimpleAlt.s,EffectBlure_SetupSimpleAlt,0x800AA498,0x9A +asm/non_matchings/code/z_eff_blure/EffectBlure_DrawSimpleVertices.s,EffectBlure_DrawSimpleVertices,0x800AA700,0x138 +asm/non_matchings/code/z_eff_blure/EffectBlure_DrawSimple.s,EffectBlure_DrawSimple,0x800AABE0,0x143 asm/non_matchings/code/z_eff_blure/EffectBlure_Draw.s,EffectBlure_Draw,0x800AB0EC,0x139 asm/non_matchings/code/z_eff_shield_particle/EffectShieldParticle_Init.s,EffectShieldParticle_Init,0x800AB5D0,0x8E asm/non_matchings/code/z_eff_shield_particle/EffectShieldParticle_Destroy.s,EffectShieldParticle_Destroy,0x800AB808,0x23 asm/non_matchings/code/z_eff_shield_particle/EffectShieldParticle_Update.s,EffectShieldParticle_Update,0x800AB894,0x59 -asm/non_matchings/code/z_eff_shield_particle/EffectShieldParticle_CalculateColors.s,EffectShieldParticle_CalculateColors,0x800AB9F8,0x348 +asm/non_matchings/code/z_eff_shield_particle/EffectShieldParticle_GetColors.s,EffectShieldParticle_GetColors,0x800AB9F8,0x348 asm/non_matchings/code/z_eff_shield_particle/EffectShieldParticle_Draw.s,EffectShieldParticle_Draw,0x800AC718,0x136 asm/non_matchings/code/z_eff_spark/EffectSpark_Init.s,EffectSpark_Init,0x800ACBF0,0xF7 asm/non_matchings/code/z_eff_spark/EffectSpark_Destroy.s,EffectSpark_Destroy,0x800ACFCC,0x3 @@ -60,15 +60,15 @@ asm/non_matchings/code/z_eff_ss_dead/func_800AE778.s,func_800AE778,0x800AE778,0x asm/non_matchings/code/z_eff_ss_dead/func_800AE8EC.s,func_800AE8EC,0x800AE8EC,0x11 asm/non_matchings/code/z_eff_tire_mark/func_800AE930.s,func_800AE930,0x800AE930,0x185 asm/non_matchings/code/z_eff_tire_mark/func_800AEF44.s,func_800AEF44,0x800AEF44,0xB -asm/non_matchings/code/z_eff_tire_mark/EffectTireMark_InitParticle.s,EffectTireMark_InitParticle,0x800AEF70,0xC +asm/non_matchings/code/z_eff_tire_mark/EffectTireMark_InitElement.s,EffectTireMark_InitElement,0x800AEF70,0xC asm/non_matchings/code/z_eff_tire_mark/EffectTireMark_Init.s,EffectTireMark_Init,0x800AEFA0,0x29 asm/non_matchings/code/z_eff_tire_mark/EffectTireMark_Destroy.s,EffectTireMark_Destroy,0x800AF044,0x3 asm/non_matchings/code/z_eff_tire_mark/EffectTireMark_Update.s,EffectTireMark_Update,0x800AF050,0x8D -asm/non_matchings/code/z_eff_tire_mark/EffectTireMark_InitVertices.s,EffectTireMark_InitVertices,0x800AF284,0x23 +asm/non_matchings/code/z_eff_tire_mark/EffectTireMark_SetVertices.s,EffectTireMark_SetVertices,0x800AF284,0x23 asm/non_matchings/code/z_eff_tire_mark/EffectTireMark_Draw.s,EffectTireMark_Draw,0x800AF310,0x100 -asm/non_matchings/code/z_effect/Effect_GetContext.s,Effect_GetContext,0x800AF710,0x4 -asm/non_matchings/code/z_effect/Effect_GetParams.s,Effect_GetParams,0x800AF720,0x57 -asm/non_matchings/code/z_effect/Effect_InitCommon.s,Effect_InitCommon,0x800AF87C,0x5 +asm/non_matchings/code/z_effect/Effect_GetGlobalCtx.s,Effect_GetGlobalCtx,0x800AF710,0x4 +asm/non_matchings/code/z_effect/Effect_GetByIndex.s,Effect_GetByIndex,0x800AF720,0x57 +asm/non_matchings/code/z_effect/Effect_InitStatus.s,Effect_InitStatus,0x800AF87C,0x5 asm/non_matchings/code/z_effect/Effect_Init.s,Effect_Init,0x800AF890,0x34 asm/non_matchings/code/z_effect/Effect_Add.s,Effect_Add,0x800AF960,0x71 asm/non_matchings/code/z_effect/Effect_DrawAll.s,Effect_DrawAll,0x800AFB24,0x4F @@ -413,33 +413,33 @@ asm/non_matchings/code/z_actor_dlftbls/ActorOverlayTable_FaultPrint.s,ActorOverl asm/non_matchings/code/z_actor_dlftbls/ActorOverlayTable_FaultAddrConv.s,ActorOverlayTable_FaultAddrConv,0x800BFA78,0x1C asm/non_matchings/code/z_actor_dlftbls/ActorOverlayTable_Init.s,ActorOverlayTable_Init,0x800BFAE8,0x16 asm/non_matchings/code/z_actor_dlftbls/ActorOverlayTable_Cleanup.s,ActorOverlayTable_Cleanup,0x800BFB40,0x10 -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonLinkedListNodeInit.s,BgCheck_PolygonLinkedListNodeInit,0x800BFB80,0x7 -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonLinkedListResetHead.s,BgCheck_PolygonLinkedListResetHead,0x800BFB9C,0x4 -asm/non_matchings/code/z_bgcheck/BgCheck_ScenePolygonListsNodeInsert.s,BgCheck_ScenePolygonListsNodeInsert,0x800BFBAC,0x16 -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonLinkedListNodeInsert.s,BgCheck_PolygonLinkedListNodeInsert,0x800BFC04,0x16 -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonLinkedListInit.s,BgCheck_PolygonLinkedListInit,0x800BFC5C,0x5 -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonLinkedListAlloc.s,BgCheck_PolygonLinkedListAlloc,0x800BFC70,0x14 -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonLinkedListReset.s,BgCheck_PolygonLinkedListReset,0x800BFCC0,0x3 -asm/non_matchings/code/z_bgcheck/BgCheck_AllocPolygonLinkedListNode.s,BgCheck_AllocPolygonLinkedListNode,0x800BFCCC,0xC -asm/non_matchings/code/z_bgcheck/BgCheck_CreateVec3fFromVertex.s,BgCheck_CreateVec3fFromVertex,0x800BFCFC,0x11 -asm/non_matchings/code/z_bgcheck/BgCheck_CreateVertexFromVec3f.s,BgCheck_CreateVertexFromVec3f,0x800BFD40,0x11 +asm/non_matchings/code/z_bgcheck/SSNode_SetValue.s,SSNode_SetValue,0x800BFB80,0x7 +asm/non_matchings/code/z_bgcheck/SSList_SetNull.s,SSList_SetNull,0x800BFB9C,0x4 +asm/non_matchings/code/z_bgcheck/SSNodeList_SetSSListHead.s,SSNodeList_SetSSListHead,0x800BFBAC,0x16 +asm/non_matchings/code/z_bgcheck/DynaSSNodeList_SetSSListHead.s,DynaSSNodeList_SetSSListHead,0x800BFC04,0x16 +asm/non_matchings/code/z_bgcheck/DynaSSNodeList_Init.s,DynaSSNodeList_Init,0x800BFC5C,0x5 +asm/non_matchings/code/z_bgcheck/DynaSSNodeList_Alloc.s,DynaSSNodeList_Alloc,0x800BFC70,0x14 +asm/non_matchings/code/z_bgcheck/DynaSSNodeList_ResetCount.s,DynaSSNodeList_ResetCount,0x800BFCC0,0x3 +asm/non_matchings/code/z_bgcheck/DynaSSNodeList_GetNextNodeIdx.s,DynaSSNodeList_GetNextNodeIdx,0x800BFCCC,0xC +asm/non_matchings/code/z_bgcheck/BgCheck_Vec3sToVec3f.s,BgCheck_Vec3sToVec3f,0x800BFCFC,0x11 +asm/non_matchings/code/z_bgcheck/BgCheck_Vec3fToVec3s.s,BgCheck_Vec3fToVec3s,0x800BFD40,0x11 asm/non_matchings/code/z_bgcheck/func_800BFD84.s,func_800BFD84,0x800BFD84,0x1A asm/non_matchings/code/z_bgcheck/func_800BFDEC.s,func_800BFDEC,0x800BFDEC,0x76 -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonGetMinY.s,BgCheck_PolygonGetMinY,0x800BFFC4,0x1E -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonGetNormal.s,BgCheck_PolygonGetNormal,0x800C003C,0x16 +asm/non_matchings/code/z_bgcheck/CollisionPoly_GetMinY.s,CollisionPoly_GetMinY,0x800BFFC4,0x1E +asm/non_matchings/code/z_bgcheck/CollisionPoly_GetNormalF.s,CollisionPoly_GetNormalF,0x800C003C,0x16 asm/non_matchings/code/z_bgcheck/func_800C0094.s,func_800C0094,0x800C0094,0x49 -asm/non_matchings/code/z_bgcheck/func_800C01B8.s,func_800C01B8,0x800C01B8,0x1A -asm/non_matchings/code/z_bgcheck/BgCheck_CreateTriNormFromPolygon.s,BgCheck_CreateTriNormFromPolygon,0x800C0220,0x28 -asm/non_matchings/code/z_bgcheck/func_800C02C0.s,func_800C02C0,0x800C02C0,0x20 +asm/non_matchings/code/z_bgcheck/CollisionPoly_GetPointDistanceFromPlane.s,CollisionPoly_GetPointDistanceFromPlane,0x800C01B8,0x1A +asm/non_matchings/code/z_bgcheck/CollisionPoly_GetVertices.s,CollisionPoly_GetVertices,0x800C0220,0x28 +asm/non_matchings/code/z_bgcheck/CollisionPoly_GetVerticesByBgId.s,CollisionPoly_GetVerticesByBgId,0x800C02C0,0x20 asm/non_matchings/code/z_bgcheck/func_800C0340.s,func_800C0340,0x800C0340,0x4D asm/non_matchings/code/z_bgcheck/func_800C0474.s,func_800C0474,0x800C0474,0x7D asm/non_matchings/code/z_bgcheck/func_800C0668.s,func_800C0668,0x800C0668,0x10 asm/non_matchings/code/z_bgcheck/func_800C06A8.s,func_800C06A8,0x800C06A8,0x29 asm/non_matchings/code/z_bgcheck/func_800C074C.s,func_800C074C,0x800C074C,0x29 asm/non_matchings/code/z_bgcheck/func_800C07F0.s,func_800C07F0,0x800C07F0,0xC0 -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonCollidesWithSphere.s,BgCheck_PolygonCollidesWithSphere,0x800C0AF0,0x34 -asm/non_matchings/code/z_bgcheck/BgCheck_ScenePolygonListsInsertSorted.s,BgCheck_ScenePolygonListsInsertSorted,0x800C0BC0,0x88 -asm/non_matchings/code/z_bgcheck/BgCheck_ScenePolygonListsInsert.s,BgCheck_ScenePolygonListsInsert,0x800C0DE0,0x25 +asm/non_matchings/code/z_bgcheck/CollisionPoly_SphVsPoly.s,CollisionPoly_SphVsPoly,0x800C0AF0,0x34 +asm/non_matchings/code/z_bgcheck/StaticLookup_AddPolyToSSList.s,StaticLookup_AddPolyToSSList,0x800C0BC0,0x88 +asm/non_matchings/code/z_bgcheck/StaticLookup_AddPoly.s,StaticLookup_AddPoly,0x800C0DE0,0x25 asm/non_matchings/code/z_bgcheck/func_800C0E74.s,func_800C0E74,0x800C0E74,0xA2 asm/non_matchings/code/z_bgcheck/func_800C10FC.s,func_800C10FC,0x800C10FC,0x4F asm/non_matchings/code/z_bgcheck/func_800C1238.s,func_800C1238,0x800C1238,0x1B @@ -452,98 +452,98 @@ asm/non_matchings/code/z_bgcheck/func_800C2310.s,func_800C2310,0x800C2310,0x54 asm/non_matchings/code/z_bgcheck/func_800C2460.s,func_800C2460,0x800C2460,0x2D asm/non_matchings/code/z_bgcheck/func_800C2514.s,func_800C2514,0x800C2514,0x33 asm/non_matchings/code/z_bgcheck/func_800C25E0.s,func_800C25E0,0x800C25E0,0x38 -asm/non_matchings/code/z_bgcheck/BgCheck_GetPolyMinSubdivisions.s,BgCheck_GetPolyMinSubdivisions,0x800C26C0,0x69 -asm/non_matchings/code/z_bgcheck/BgCheck_GetPolyMaxSubdivisions.s,BgCheck_GetPolyMaxSubdivisions,0x800C2864,0x73 -asm/non_matchings/code/z_bgcheck/BgCheck_GetPolyMinMaxSubdivisions.s,BgCheck_GetPolyMinMaxSubdivisions,0x800C2A30,0x6C -asm/non_matchings/code/z_bgcheck/func_800C2BE0.s,func_800C2BE0,0x800C2BE0,0x1D5 -asm/non_matchings/code/z_bgcheck/BgCheck_SplitScenePolygonsIntoSubdivisions.s,BgCheck_SplitScenePolygonsIntoSubdivisions,0x800C3334,0x100 -asm/non_matchings/code/z_bgcheck/BgCheck_GetIsDefaultSpecialScene.s,BgCheck_GetIsDefaultSpecialScene,0x800C3734,0x11 -asm/non_matchings/code/z_bgcheck/BgCheck_GetSpecialSceneMaxMemory.s,BgCheck_GetSpecialSceneMaxMemory,0x800C3778,0x11 -asm/non_matchings/code/z_bgcheck/BgCheck_CalcSubdivisionSize.s,BgCheck_CalcSubdivisionSize,0x800C37BC,0x22 +asm/non_matchings/code/z_bgcheck/BgCheck_GetSubdivisionMinBounds.s,BgCheck_GetSubdivisionMinBounds,0x800C26C0,0x69 +asm/non_matchings/code/z_bgcheck/BgCheck_GetSubdivisionMaxBounds.s,BgCheck_GetSubdivisionMaxBounds,0x800C2864,0x73 +asm/non_matchings/code/z_bgcheck/BgCheck_GetPolySubdivisionBounds.s,BgCheck_GetPolySubdivisionBounds,0x800C2A30,0x6C +asm/non_matchings/code/z_bgcheck/BgCheck_PolyIntersectsSubdivision.s,BgCheck_PolyIntersectsSubdivision,0x800C2BE0,0x1D5 +asm/non_matchings/code/z_bgcheck/BgCheck_InitStaticLookup.s,BgCheck_InitStaticLookup,0x800C3334,0x100 +asm/non_matchings/code/z_bgcheck/BgCheck_IsSmallMemScene.s,BgCheck_IsSmallMemScene,0x800C3734,0x11 +asm/non_matchings/code/z_bgcheck/BgCheck_TryGetCustomMemsize.s,BgCheck_TryGetCustomMemsize,0x800C3778,0x11 +asm/non_matchings/code/z_bgcheck/BgCheck_SetSubdivisionDimension.s,BgCheck_SetSubdivisionDimension,0x800C37BC,0x22 asm/non_matchings/code/z_bgcheck/BgCheck_GetSpecialSceneMaxObjects.s,BgCheck_GetSpecialSceneMaxObjects,0x800C3844,0x16 asm/non_matchings/code/z_bgcheck/BgCheck_Init.s,BgCheck_Init,0x800C389C,0xD9 -asm/non_matchings/code/z_bgcheck/func_800C3C00.s,func_800C3C00,0x800C3C00,0x5 -asm/non_matchings/code/z_bgcheck/func_800C3C14.s,func_800C3C14,0x800C3C14,0x6 -asm/non_matchings/code/z_bgcheck/BgCheck_GetActorMeshHeader.s,BgCheck_GetActorMeshHeader,0x800C3C2C,0x1A +asm/non_matchings/code/z_bgcheck/BgCheck_SetContextFlags.s,BgCheck_SetContextFlags,0x800C3C00,0x5 +asm/non_matchings/code/z_bgcheck/BgCheck_UnsetContextFlags.s,BgCheck_UnsetContextFlags,0x800C3C14,0x6 +asm/non_matchings/code/z_bgcheck/BgCheck_GetCollisionHeader.s,BgCheck_GetCollisionHeader,0x800C3C2C,0x1A asm/non_matchings/code/z_bgcheck/func_800C3C94.s,func_800C3C94,0x800C3C94,0x2F -asm/non_matchings/code/z_bgcheck/func_800C3D50.s,func_800C3D50,0x800C3D50,0x7C -asm/non_matchings/code/z_bgcheck/func_800C3F40.s,func_800C3F40,0x800C3F40,0x18 -asm/non_matchings/code/z_bgcheck/func_800C3FA0.s,func_800C3FA0,0x800C3FA0,0x18 -asm/non_matchings/code/z_bgcheck/func_800C4000.s,func_800C4000,0x800C4000,0x16 -asm/non_matchings/code/z_bgcheck/func_800C4058.s,func_800C4058,0x800C4058,0x17 -asm/non_matchings/code/z_bgcheck/func_800C40B4.s,func_800C40B4,0x800C40B4,0x1A -asm/non_matchings/code/z_bgcheck/func_800C411C.s,func_800C411C,0x800C411C,0x1B -asm/non_matchings/code/z_bgcheck/func_800C4188.s,func_800C4188,0x800C4188,0x17 -asm/non_matchings/code/z_bgcheck/func_800C41E4.s,func_800C41E4,0x800C41E4,0x17 -asm/non_matchings/code/z_bgcheck/func_800C4240.s,func_800C4240,0x800C4240,0x1A -asm/non_matchings/code/z_bgcheck/func_800C42A8.s,func_800C42A8,0x800C42A8,0x1B -asm/non_matchings/code/z_bgcheck/func_800C4314.s,func_800C4314,0x800C4314,0x2E -asm/non_matchings/code/z_bgcheck/func_800C43CC.s,func_800C43CC,0x800C43CC,0x2F -asm/non_matchings/code/z_bgcheck/func_800C4488.s,func_800C4488,0x800C4488,0x1A -asm/non_matchings/code/z_bgcheck/func_800C44F0.s,func_800C44F0,0x800C44F0,0x1B -asm/non_matchings/code/z_bgcheck/func_800C455C.s,func_800C455C,0x800C455C,0x1A -asm/non_matchings/code/z_bgcheck/func_800C45C4.s,func_800C45C4,0x800C45C4,0x1AC -asm/non_matchings/code/z_bgcheck/func_800C4C74.s,func_800C4C74,0x800C4C74,0x19 -asm/non_matchings/code/z_bgcheck/func_800C4CD8.s,func_800C4CD8,0x800C4CD8,0x19 -asm/non_matchings/code/z_bgcheck/func_800C4D3C.s,func_800C4D3C,0x800C4D3C,0x1A -asm/non_matchings/code/z_bgcheck/func_800C4DA4.s,func_800C4DA4,0x800C4DA4,0x1B -asm/non_matchings/code/z_bgcheck/func_800C4E10.s,func_800C4E10,0x800C4E10,0x4A -asm/non_matchings/code/z_bgcheck/func_800C4F38.s,func_800C4F38,0x800C4F38,0x13 -asm/non_matchings/code/z_bgcheck/func_800C4F84.s,func_800C4F84,0x800C4F84,0x14 +asm/non_matchings/code/z_bgcheck/BgCheck_RaycastFloorImpl.s,BgCheck_RaycastFloorImpl,0x800C3D50,0x7C +asm/non_matchings/code/z_bgcheck/BgCheck_CameraRaycastFloor1.s,BgCheck_CameraRaycastFloor1,0x800C3F40,0x18 +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor1.s,BgCheck_EntityRaycastFloor1,0x800C3FA0,0x18 +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor2.s,BgCheck_EntityRaycastFloor2,0x800C4000,0x16 +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor2_1.s,BgCheck_EntityRaycastFloor2_1,0x800C4058,0x17 +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor3.s,BgCheck_EntityRaycastFloor3,0x800C40B4,0x1A +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor5.s,BgCheck_EntityRaycastFloor5,0x800C411C,0x1B +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor5_2.s,BgCheck_EntityRaycastFloor5_2,0x800C4188,0x17 +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor5_3.s,BgCheck_EntityRaycastFloor5_3,0x800C41E4,0x17 +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor6.s,BgCheck_EntityRaycastFloor6,0x800C4240,0x1A +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor7.s,BgCheck_EntityRaycastFloor7,0x800C42A8,0x1B +asm/non_matchings/code/z_bgcheck/BgCheck_AnyRaycastFloor1.s,BgCheck_AnyRaycastFloor1,0x800C4314,0x2E +asm/non_matchings/code/z_bgcheck/BgCheck_AnyRaycastFloor2.s,BgCheck_AnyRaycastFloor2,0x800C43CC,0x2F +asm/non_matchings/code/z_bgcheck/BgCheck_CameraRaycastFloor2.s,BgCheck_CameraRaycastFloor2,0x800C4488,0x1A +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor8.s,BgCheck_EntityRaycastFloor8,0x800C44F0,0x1B +asm/non_matchings/code/z_bgcheck/BgCheck_EntityRaycastFloor9.s,BgCheck_EntityRaycastFloor9,0x800C455C,0x1A +asm/non_matchings/code/z_bgcheck/BgCheck_CheckWallImpl.s,BgCheck_CheckWallImpl,0x800C45C4,0x1AC +asm/non_matchings/code/z_bgcheck/BgCheck_EntitySphVsWall1.s,BgCheck_EntitySphVsWall1,0x800C4C74,0x19 +asm/non_matchings/code/z_bgcheck/BgCheck_EntitySphVsWall2.s,BgCheck_EntitySphVsWall2,0x800C4CD8,0x19 +asm/non_matchings/code/z_bgcheck/BgCheck_EntitySphVsWall3.s,BgCheck_EntitySphVsWall3,0x800C4D3C,0x1A +asm/non_matchings/code/z_bgcheck/BgCheck_EntitySphVsWall4.s,BgCheck_EntitySphVsWall4,0x800C4DA4,0x1B +asm/non_matchings/code/z_bgcheck/BgCheck_CheckCeilingImpl.s,BgCheck_CheckCeilingImpl,0x800C4E10,0x4A +asm/non_matchings/code/z_bgcheck/BgCheck_AnyCheckCeiling.s,BgCheck_AnyCheckCeiling,0x800C4F38,0x13 +asm/non_matchings/code/z_bgcheck/BgCheck_EntityCheckCeiling.s,BgCheck_EntityCheckCeiling,0x800C4F84,0x14 asm/non_matchings/code/z_bgcheck/func_800C4FD4.s,func_800C4FD4,0x800C4FD4,0x124 asm/non_matchings/code/z_bgcheck/func_800C5464.s,func_800C5464,0x800C5464,0x12 -asm/non_matchings/code/z_bgcheck/func_800C54AC.s,func_800C54AC,0x800C54AC,0x23 -asm/non_matchings/code/z_bgcheck/func_800C5538.s,func_800C5538,0x800C5538,0x23 -asm/non_matchings/code/z_bgcheck/func_800C55C4.s,func_800C55C4,0x800C55C4,0x23 -asm/non_matchings/code/z_bgcheck/func_800C5650.s,func_800C5650,0x800C5650,0x24 -asm/non_matchings/code/z_bgcheck/func_800C56E0.s,func_800C56E0,0x800C56E0,0x23 -asm/non_matchings/code/z_bgcheck/func_800C576C.s,func_800C576C,0x800C576C,0x23 -asm/non_matchings/code/z_bgcheck/func_800C57F8.s,func_800C57F8,0x800C57F8,0x11 -asm/non_matchings/code/z_bgcheck/func_800C583C.s,func_800C583C,0x800C583C,0x23 -asm/non_matchings/code/z_bgcheck/func_800C58C8.s,func_800C58C8,0x800C58C8,0x23 -asm/non_matchings/code/z_bgcheck/func_800C5954.s,func_800C5954,0x800C5954,0x33 -asm/non_matchings/code/z_bgcheck/func_800C5A20.s,func_800C5A20,0x800C5A20,0x11 -asm/non_matchings/code/z_bgcheck/func_800C5A64.s,func_800C5A64,0x800C5A64,0x12 -asm/non_matchings/code/z_bgcheck/BgCheck_ScenePolygonListsInit.s,BgCheck_ScenePolygonListsInit,0x800C5AAC,0x6 -asm/non_matchings/code/z_bgcheck/BgCheck_ScenePolygonListsAlloc.s,BgCheck_ScenePolygonListsAlloc,0x800C5AC4,0x2F -asm/non_matchings/code/z_bgcheck/func_800C5B80.s,func_800C5B80,0x800C5B80,0xF -asm/non_matchings/code/z_bgcheck/BgCheck_ScenePolygonListsReserveNode.s,BgCheck_ScenePolygonListsReserveNode,0x800C5BBC,0x5 -asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshParamsInit.s,BgCheck_ActorMeshParamsInit,0x800C5BD0,0xF -asm/non_matchings/code/z_bgcheck/BgCheck_SetActorMeshParams.s,BgCheck_SetActorMeshParams,0x800C5C0C,0x14 +asm/non_matchings/code/z_bgcheck/BgCheck_CameraLineTest1.s,BgCheck_CameraLineTest1,0x800C54AC,0x23 +asm/non_matchings/code/z_bgcheck/BgCheck_CameraLineTest2.s,BgCheck_CameraLineTest2,0x800C5538,0x23 +asm/non_matchings/code/z_bgcheck/BgCheck_EntityLineTest1.s,BgCheck_EntityLineTest1,0x800C55C4,0x23 +asm/non_matchings/code/z_bgcheck/BgCheck_EntityLineTest2.s,BgCheck_EntityLineTest2,0x800C5650,0x24 +asm/non_matchings/code/z_bgcheck/BgCheck_EntityLineTest3.s,BgCheck_EntityLineTest3,0x800C56E0,0x23 +asm/non_matchings/code/z_bgcheck/BgCheck_ProjectileLineTest.s,BgCheck_ProjectileLineTest,0x800C576C,0x23 +asm/non_matchings/code/z_bgcheck/BgCheck_AnyLineTest1.s,BgCheck_AnyLineTest1,0x800C57F8,0x11 +asm/non_matchings/code/z_bgcheck/BgCheck_AnyLineTest2.s,BgCheck_AnyLineTest2,0x800C583C,0x23 +asm/non_matchings/code/z_bgcheck/BgCheck_AnyLineTest3.s,BgCheck_AnyLineTest3,0x800C58C8,0x23 +asm/non_matchings/code/z_bgcheck/BgCheck_SphVsFirstPolyImpl.s,BgCheck_SphVsFirstPolyImpl,0x800C5954,0x33 +asm/non_matchings/code/z_bgcheck/BgCheck_SphVsFirstPoly.s,BgCheck_SphVsFirstPoly,0x800C5A20,0x11 +asm/non_matchings/code/z_bgcheck/BgCheck_SphVsFirstWall.s,BgCheck_SphVsFirstWall,0x800C5A64,0x12 +asm/non_matchings/code/z_bgcheck/SSNodeList_Init.s,SSNodeList_Init,0x800C5AAC,0x6 +asm/non_matchings/code/z_bgcheck/SSNodeList_Alloc.s,SSNodeList_Alloc,0x800C5AC4,0x2F +asm/non_matchings/code/z_bgcheck/SSNodeList_GetNextNode.s,SSNodeList_GetNextNode,0x800C5B80,0xF +asm/non_matchings/code/z_bgcheck/SSNodeList_GetNextNodeIdx.s,SSNodeList_GetNextNodeIdx,0x800C5BBC,0x5 +asm/non_matchings/code/z_bgcheck/ScaleRotPos_Init.s,ScaleRotPos_Init,0x800C5BD0,0xF +asm/non_matchings/code/z_bgcheck/ScaleRotPos_SetValue.s,ScaleRotPos_SetValue,0x800C5C0C,0x14 asm/non_matchings/code/z_bgcheck/BgCheck_AreActorMeshParamsEqual.s,BgCheck_AreActorMeshParamsEqual,0x800C5C5C,0x35 -asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshPolyListsHeadsInit.s,BgCheck_ActorMeshPolyListsHeadsInit,0x800C5D30,0x10 -asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshPolyListsInit.s,BgCheck_ActorMeshPolyListsInit,0x800C5D70,0x8 -asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshVerticesIndexInit.s,BgCheck_ActorMeshVerticesIndexInit,0x800C5D90,0x3 -asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshWaterboxesIndexInit.s,BgCheck_ActorMeshWaterboxesIndexInit,0x800C5D9C,0x3 -asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshInit.s,BgCheck_ActorMeshInit,0x800C5DA8,0x1A -asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshInitFromActor.s,BgCheck_ActorMeshInitFromActor,0x800C5E10,0x2E -asm/non_matchings/code/z_bgcheck/BgCheck_HasActorMeshChanged.s,BgCheck_HasActorMeshChanged,0x800C5EC8,0xA -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonsInit.s,BgCheck_PolygonsInit,0x800C5EF0,0x3 -asm/non_matchings/code/z_bgcheck/BgCheck_PolygonsAlloc.s,BgCheck_PolygonsAlloc,0x800C5EFC,0xF -asm/non_matchings/code/z_bgcheck/BgCheck_VerticesInit.s,BgCheck_VerticesInit,0x800C5F38,0x3 -asm/non_matchings/code/z_bgcheck/BgCheck_VerticesListAlloc.s,BgCheck_VerticesListAlloc,0x800C5F44,0x12 -asm/non_matchings/code/z_bgcheck/BgCheck_WaterboxListInit.s,BgCheck_WaterboxListInit,0x800C5F8C,0x4 -asm/non_matchings/code/z_bgcheck/BgCheck_WaterboxListAlloc.s,BgCheck_WaterboxListAlloc,0x800C5F9C,0xF -asm/non_matchings/code/z_bgcheck/BgCheck_ActorMeshUpdateParams.s,BgCheck_ActorMeshUpdateParams,0x800C5FD8,0x13 -asm/non_matchings/code/z_bgcheck/BgCheck_IsActorMeshIndexValid.s,BgCheck_IsActorMeshIndexValid,0x800C6024,0x8 -asm/non_matchings/code/z_bgcheck/BgCheck_DynaInit.s,BgCheck_DynaInit,0x800C6044,0x15 -asm/non_matchings/code/z_bgcheck/BgCheck_DynaAlloc.s,BgCheck_DynaAlloc,0x800C6098,0x3C -asm/non_matchings/code/z_bgcheck/BgCheck_AddActorMesh.s,BgCheck_AddActorMesh,0x800C6188,0x30 -asm/non_matchings/code/z_bgcheck/BgCheck_GetActorOfMesh.s,BgCheck_GetActorOfMesh,0x800C6248,0x1D +asm/non_matchings/code/z_bgcheck/DynaLookup_ResetLists.s,DynaLookup_ResetLists,0x800C5D30,0x10 +asm/non_matchings/code/z_bgcheck/DynaLookup_Reset.s,DynaLookup_Reset,0x800C5D70,0x8 +asm/non_matchings/code/z_bgcheck/DynaLookup_ResetVtxStartIndex.s,DynaLookup_ResetVtxStartIndex,0x800C5D90,0x3 +asm/non_matchings/code/z_bgcheck/DynaLookup_ResetWaterBoxStartIndex.s,DynaLookup_ResetWaterBoxStartIndex,0x800C5D9C,0x3 +asm/non_matchings/code/z_bgcheck/BgActor_Init.s,BgActor_Init,0x800C5DA8,0x1A +asm/non_matchings/code/z_bgcheck/BgActor_InitFromActor.s,BgActor_InitFromActor,0x800C5E10,0x2E +asm/non_matchings/code/z_bgcheck/BgActor_IsTransformUnchanged.s,BgActor_IsTransformUnchanged,0x800C5EC8,0xA +asm/non_matchings/code/z_bgcheck/DynaPoly_NullPolyList.s,DynaPoly_NullPolyList,0x800C5EF0,0x3 +asm/non_matchings/code/z_bgcheck/DynaPoly_AllocPolyList.s,DynaPoly_AllocPolyList,0x800C5EFC,0xF +asm/non_matchings/code/z_bgcheck/DynaPoly_NullVtxList.s,DynaPoly_NullVtxList,0x800C5F38,0x3 +asm/non_matchings/code/z_bgcheck/DynaPoly_AllocVtxList.s,DynaPoly_AllocVtxList,0x800C5F44,0x12 +asm/non_matchings/code/z_bgcheck/DynaPoly_InitWaterBoxList.s,DynaPoly_InitWaterBoxList,0x800C5F8C,0x4 +asm/non_matchings/code/z_bgcheck/DynaPoly_AllocWaterBoxList.s,DynaPoly_AllocWaterBoxList,0x800C5F9C,0xF +asm/non_matchings/code/z_bgcheck/DynaPoly_SetBgActorPrevTransform.s,DynaPoly_SetBgActorPrevTransform,0x800C5FD8,0x13 +asm/non_matchings/code/z_bgcheck/DynaPoly_IsBgIdBgActor.s,DynaPoly_IsBgIdBgActor,0x800C6024,0x8 +asm/non_matchings/code/z_bgcheck/DynaPoly_Init.s,DynaPoly_Init,0x800C6044,0x15 +asm/non_matchings/code/z_bgcheck/DynaPoly_Alloc.s,DynaPoly_Alloc,0x800C6098,0x3C +asm/non_matchings/code/z_bgcheck/DynaPoly_SetBgActor.s,DynaPoly_SetBgActor,0x800C6188,0x30 +asm/non_matchings/code/z_bgcheck/DynaPoly_GetActor.s,DynaPoly_GetActor,0x800C6248,0x1D asm/non_matchings/code/z_bgcheck/func_800C62BC.s,func_800C62BC,0x800C62BC,0x16 asm/non_matchings/code/z_bgcheck/func_800C6314.s,func_800C6314,0x800C6314,0x16 asm/non_matchings/code/z_bgcheck/func_800C636C.s,func_800C636C,0x800C636C,0x16 asm/non_matchings/code/z_bgcheck/func_800C63C4.s,func_800C63C4,0x800C63C4,0x16 asm/non_matchings/code/z_bgcheck/func_800C641C.s,func_800C641C,0x800C641C,0x16 asm/non_matchings/code/z_bgcheck/func_800C6474.s,func_800C6474,0x800C6474,0x16 -asm/non_matchings/code/z_bgcheck/BgCheck_RemoveActorMesh.s,BgCheck_RemoveActorMesh,0x800C64CC,0x22 +asm/non_matchings/code/z_bgcheck/DynaPoly_DeleteBgActor.s,DynaPoly_DeleteBgActor,0x800C64CC,0x22 asm/non_matchings/code/z_bgcheck/func_800C6554.s,func_800C6554,0x800C6554,0x6 asm/non_matchings/code/z_bgcheck/BgCheck_CalcWaterboxDimensions.s,BgCheck_CalcWaterboxDimensions,0x800C656C,0xB3 -asm/non_matchings/code/z_bgcheck/BgCheck_AddActorMeshToLists.s,BgCheck_AddActorMeshToLists,0x800C6838,0x2C5 +asm/non_matchings/code/z_bgcheck/DynaPoly_SetBgActorToLists.s,DynaPoly_SetBgActorToLists,0x800C6838,0x2C5 asm/non_matchings/code/z_bgcheck/BgCheck_ResetFlagsIfLoadedActor.s,BgCheck_ResetFlagsIfLoadedActor,0x800C734C,0x26 -asm/non_matchings/code/z_bgcheck/BgCheck_Update.s,BgCheck_Update,0x800C73E4,0x62 +asm/non_matchings/code/z_bgcheck/DynaPoly_Setup.s,DynaPoly_Setup,0x800C73E4,0x62 asm/non_matchings/code/z_bgcheck/func_800C756C.s,func_800C756C,0x800C756C,0x3C -asm/non_matchings/code/z_bgcheck/BgCheck_UpdateAllActorMeshes.s,BgCheck_UpdateAllActorMeshes,0x800C765C,0x24 +asm/non_matchings/code/z_bgcheck/DynaPoly_SetupAllActorMeshes.s,DynaPoly_SetupAllActorMeshes,0x800C765C,0x24 asm/non_matchings/code/z_bgcheck/func_800C76EC.s,func_800C76EC,0x800C76EC,0xA2 asm/non_matchings/code/z_bgcheck/func_800C7974.s,func_800C7974,0x800C7974,0x133 asm/non_matchings/code/z_bgcheck/func_800C7E40.s,func_800C7E40,0x800C7E40,0x1D0 @@ -556,19 +556,19 @@ asm/non_matchings/code/z_bgcheck/func_800C8EEC.s,func_800C8EEC,0x800C8EEC,0x70 asm/non_matchings/code/z_bgcheck/func_800C90AC.s,func_800C90AC,0x800C90AC,0x5C asm/non_matchings/code/z_bgcheck/func_800C921C.s,func_800C921C,0x800C921C,0x59 asm/non_matchings/code/z_bgcheck/func_800C9380.s,func_800C9380,0x800C9380,0x58 -asm/non_matchings/code/z_bgcheck/BgCheck_RelocateMeshHeaderPointers.s,BgCheck_RelocateMeshHeaderPointers,0x800C94E0,0x21 -asm/non_matchings/code/z_bgcheck/BgCheck_RelocateMeshHeader.s,BgCheck_RelocateMeshHeader,0x800C9564,0xD -asm/non_matchings/code/z_bgcheck/BgCheck_RelocateAllMeshHeaders.s,BgCheck_RelocateAllMeshHeaders,0x800C9598,0x2A +asm/non_matchings/code/z_bgcheck/CollisionHeader_GetVirtualPointers.s,CollisionHeader_GetVirtualPointers,0x800C94E0,0x21 +asm/non_matchings/code/z_bgcheck/CollisionHeader_GetVirtual.s,CollisionHeader_GetVirtual,0x800C9564,0xD +asm/non_matchings/code/z_bgcheck/BgCheck_InitCollisionHeaders.s,BgCheck_InitCollisionHeaders,0x800C9598,0x2A asm/non_matchings/code/z_bgcheck/func_800C9640.s,func_800C9640,0x800C9640,0x15 -asm/non_matchings/code/z_bgcheck/BgCheck_GetPolygonAttributes.s,BgCheck_GetPolygonAttributes,0x800C9694,0x1C -asm/non_matchings/code/z_bgcheck/func_800C9704.s,func_800C9704,0x800C9704,0x9 +asm/non_matchings/code/z_bgcheck/SurfaceType_GetData.s,SurfaceType_GetData,0x800C9694,0x1C +asm/non_matchings/code/z_bgcheck/SurfaceType_GetCamDataIndex.s,SurfaceType_GetCamDataIndex,0x800C9704,0x9 asm/non_matchings/code/z_bgcheck/func_800C9728.s,func_800C9728,0x800C9728,0x12 asm/non_matchings/code/z_bgcheck/func_800C9770.s,func_800C9770,0x800C9770,0x22 asm/non_matchings/code/z_bgcheck/func_800C97F8.s,func_800C97F8,0x800C97F8,0x13 asm/non_matchings/code/z_bgcheck/func_800C9844.s,func_800C9844,0x800C9844,0x22 asm/non_matchings/code/z_bgcheck/func_800C98CC.s,func_800C98CC,0x800C98CC,0x16 -asm/non_matchings/code/z_bgcheck/func_800C9924.s,func_800C9924,0x800C9924,0x22 -asm/non_matchings/code/z_bgcheck/func_800C99AC.s,func_800C99AC,0x800C99AC,0xA +asm/non_matchings/code/z_bgcheck/SurfaceType_GetCamPosData.s,SurfaceType_GetCamPosData,0x800C9924,0x22 +asm/non_matchings/code/z_bgcheck/SurfaceType_GetSceneExitIndex.s,SurfaceType_GetSceneExitIndex,0x800C99AC,0xA asm/non_matchings/code/z_bgcheck/func_800C99D4.s,func_800C99D4,0x800C99D4,0xA asm/non_matchings/code/z_bgcheck/func_800C99FC.s,func_800C99FC,0x800C99FC,0xA asm/non_matchings/code/z_bgcheck/func_800C9A24.s,func_800C9A24,0x800C9A24,0xA @@ -579,30 +579,30 @@ asm/non_matchings/code/z_bgcheck/func_800C9AE4.s,func_800C9AE4,0x800C9AE4,0xD asm/non_matchings/code/z_bgcheck/func_800C9B18.s,func_800C9B18,0x800C9B18,0xA asm/non_matchings/code/z_bgcheck/func_800C9B40.s,func_800C9B40,0x800C9B40,0xA asm/non_matchings/code/z_bgcheck/func_800C9B68.s,func_800C9B68,0x800C9B68,0xA -asm/non_matchings/code/z_bgcheck/func_800C9B90.s,func_800C9B90,0x800C9B90,0xA +asm/non_matchings/code/z_bgcheck/SurfaceType_IsHorseBlocked.s,SurfaceType_IsHorseBlocked,0x800C9B90,0xA asm/non_matchings/code/z_bgcheck/func_800C9BB8.s,func_800C9BB8,0x800C9BB8,0x9 -asm/non_matchings/code/z_bgcheck/func_800C9BDC.s,func_800C9BDC,0x800C9BDC,0x12 +asm/non_matchings/code/z_bgcheck/SurfaceType_GetSfx.s,SurfaceType_GetSfx,0x800C9BDC,0x12 asm/non_matchings/code/z_bgcheck/func_800C9C24.s,func_800C9C24,0x800C9C24,0x14 -asm/non_matchings/code/z_bgcheck/func_800C9C74.s,func_800C9C74,0x800C9C74,0xA -asm/non_matchings/code/z_bgcheck/func_800C9C9C.s,func_800C9C9C,0x800C9C9C,0xA -asm/non_matchings/code/z_bgcheck/func_800C9CC4.s,func_800C9CC4,0x800C9CC4,0xA -asm/non_matchings/code/z_bgcheck/func_800C9CEC.s,func_800C9CEC,0x800C9CEC,0xA -asm/non_matchings/code/z_bgcheck/func_800C9D14.s,func_800C9D14,0x800C9D14,0xF -asm/non_matchings/code/z_bgcheck/func_800C9D50.s,func_800C9D50,0x800C9D50,0xF -asm/non_matchings/code/z_bgcheck/func_800C9D8C.s,func_800C9D8C,0x800C9D8C,0x14 +asm/non_matchings/code/z_bgcheck/SurfaceType_GetSlope.s,SurfaceType_GetSlope,0x800C9C74,0xA +asm/non_matchings/code/z_bgcheck/SurfaceType_GetLightSettingIndex.s,SurfaceType_GetLightSettingIndex,0x800C9C9C,0xA +asm/non_matchings/code/z_bgcheck/SurfaceType_GetEcho.s,SurfaceType_GetEcho,0x800C9CC4,0xA +asm/non_matchings/code/z_bgcheck/SurfaceType_IsHookshotSurface.s,SurfaceType_IsHookshotSurface,0x800C9CEC,0xA +asm/non_matchings/code/z_bgcheck/SurfaceType_IsIgnoredByEntities.s,SurfaceType_IsIgnoredByEntities,0x800C9D14,0xF +asm/non_matchings/code/z_bgcheck/SurfaceType_IsIgnoredByProjectiles.s,SurfaceType_IsIgnoredByProjectiles,0x800C9D50,0xF +asm/non_matchings/code/z_bgcheck/SurfaceType_IsConveyor.s,SurfaceType_IsConveyor,0x800C9D8C,0x14 asm/non_matchings/code/z_bgcheck/func_800C9DDC.s,func_800C9DDC,0x800C9DDC,0xF -asm/non_matchings/code/z_bgcheck/func_800C9E18.s,func_800C9E18,0x800C9E18,0xA -asm/non_matchings/code/z_bgcheck/func_800C9E40.s,func_800C9E40,0x800C9E40,0x12 -asm/non_matchings/code/z_bgcheck/func_800C9E88.s,func_800C9E88,0x800C9E88,0xD -asm/non_matchings/code/z_bgcheck/func_800C9EBC.s,func_800C9EBC,0x800C9EBC,0xBC -asm/non_matchings/code/z_bgcheck/func_800CA1AC.s,func_800CA1AC,0x800CA1AC,0xF -asm/non_matchings/code/z_bgcheck/func_800CA1E8.s,func_800CA1E8,0x800CA1E8,0x11 -asm/non_matchings/code/z_bgcheck/func_800CA22C.s,func_800CA22C,0x800CA22C,0xCF +asm/non_matchings/code/z_bgcheck/SurfaceType_GetConveyorSpeed.s,SurfaceType_GetConveyorSpeed,0x800C9E18,0xA +asm/non_matchings/code/z_bgcheck/SurfaceType_GetConveyorDirection.s,SurfaceType_GetConveyorDirection,0x800C9E40,0x12 +asm/non_matchings/code/z_bgcheck/SurfaceType_IsWallDamage.s,SurfaceType_IsWallDamage,0x800C9E88,0xD +asm/non_matchings/code/z_bgcheck/WaterBox_GetSurfaceImpl.s,WaterBox_GetSurfaceImpl,0x800C9EBC,0xBC +asm/non_matchings/code/z_bgcheck/WaterBox_GetSurface1.s,WaterBox_GetSurface1,0x800CA1AC,0xF +asm/non_matchings/code/z_bgcheck/WaterBox_GetSurface1_2.s,WaterBox_GetSurface1_2,0x800CA1E8,0x11 +asm/non_matchings/code/z_bgcheck/WaterBox_GetSurface2.s,WaterBox_GetSurface2,0x800CA22C,0xCF asm/non_matchings/code/z_bgcheck/func_800CA568.s,func_800CA568,0x800CA568,0x33 asm/non_matchings/code/z_bgcheck/func_800CA634.s,func_800CA634,0x800CA634,0x5 asm/non_matchings/code/z_bgcheck/func_800CA648.s,func_800CA648,0x800CA648,0x1C asm/non_matchings/code/z_bgcheck/func_800CA6B8.s,func_800CA6B8,0x800CA6B8,0x8 -asm/non_matchings/code/z_bgcheck/func_800CA6D8.s,func_800CA6D8,0x800CA6D8,0x6 +asm/non_matchings/code/z_bgcheck/WaterBox_GetLightSettingIndex.s,WaterBox_GetLightSettingIndex,0x800CA6D8,0x6 asm/non_matchings/code/z_bgcheck/func_800CA6F0.s,func_800CA6F0,0x800CA6F0,0xB8 asm/non_matchings/code/z_bgcheck/func_800CA9D0.s,func_800CA9D0,0x800CA9D0,0x11 asm/non_matchings/code/z_bgcheck/func_800CAA14.s,func_800CAA14,0x800CAA14,0x2F @@ -2169,7 +2169,7 @@ asm/non_matchings/code/z_snap/func_8013A46C.s,func_8013A46C,0x8013A46C,0x16 asm/non_matchings/code/z_snap/func_8013A4C4.s,func_8013A4C4,0x8013A4C4,0x10 asm/non_matchings/code/z_snap/func_8013A504.s,func_8013A504,0x8013A504,0xB asm/non_matchings/code/z_snap/func_8013A530.s,func_8013A530,0x8013A530,0xA4 -asm/non_matchings/code/z_sub_s/func_8013A7C0.s,func_8013A7C0,0x8013A7C0,0x28 +asm/non_matchings/code/z_sub_s/SubS_FindDoor.s,SubS_FindDoor,0x8013A7C0,0x28 asm/non_matchings/code/z_sub_s/func_8013A860.s,func_8013A860,0x8013A860,0xA8 asm/non_matchings/code/z_sub_s/func_8013AB00.s,func_8013AB00,0x8013AB00,0x9B asm/non_matchings/code/z_sub_s/func_8013AD6C.s,func_8013AD6C,0x8013AD6C,0xC @@ -2182,7 +2182,7 @@ asm/non_matchings/code/z_sub_s/func_8013B350.s,func_8013B350,0x8013B350,0xD8 asm/non_matchings/code/z_sub_s/func_8013B6B0.s,func_8013B6B0,0x8013B6B0,0x72 asm/non_matchings/code/z_sub_s/func_8013B878.s,func_8013B878,0x8013B878,0xAF asm/non_matchings/code/z_sub_s/func_8013BB34.s,func_8013BB34,0x8013BB34,0x12 -asm/non_matchings/code/z_sub_s/func_8013BB7C.s,func_8013BB7C,0x8013BB7C,0x3C +asm/non_matchings/code/z_sub_s/SubS_FindNearestActor.s,SubS_FindNearestActor,0x8013BB7C,0x3C asm/non_matchings/code/z_sub_s/func_8013BC6C.s,func_8013BC6C,0x8013BC6C,0x35 asm/non_matchings/code/z_sub_s/func_8013BD40.s,func_8013BD40,0x8013BD40,0x67 asm/non_matchings/code/z_sub_s/func_8013BEDC.s,func_8013BEDC,0x8013BEDC,0x63 @@ -2203,7 +2203,7 @@ asm/non_matchings/code/z_sub_s/func_8013D768.s,func_8013D768,0x8013D768,0x35 asm/non_matchings/code/z_sub_s/func_8013D83C.s,func_8013D83C,0x8013D83C,0x28 asm/non_matchings/code/z_sub_s/func_8013D8DC.s,func_8013D8DC,0x8013D8DC,0x12 asm/non_matchings/code/z_sub_s/func_8013D924.s,func_8013D924,0x8013D924,0xF -asm/non_matchings/code/z_sub_s/func_ActorCategoryIterateById.s,func_ActorCategoryIterateById,0x8013D960,0x1A +asm/non_matchings/code/z_sub_s/SubS_FindActor.s,SubS_FindActor,0x8013D960,0x1A asm/non_matchings/code/z_sub_s/func_8013D9C8.s,func_8013D9C8,0x8013D9C8,0x72 asm/non_matchings/code/z_sub_s/func_8013DB90.s,func_8013DB90,0x8013DB90,0x2C asm/non_matchings/code/z_sub_s/func_8013DC40.s,func_8013DC40,0x8013DC40,0x23 @@ -2219,7 +2219,7 @@ asm/non_matchings/code/z_sub_s/func_8013E2D4.s,func_8013E2D4,0x8013E2D4,0x39 asm/non_matchings/code/z_sub_s/func_8013E3B8.s,func_8013E3B8,0x8013E3B8,0x3E asm/non_matchings/code/z_sub_s/func_8013E4B0.s,func_8013E4B0,0x8013E4B0,0x47 asm/non_matchings/code/z_sub_s/func_8013E5CC.s,func_8013E5CC,0x8013E5CC,0x1D -asm/non_matchings/code/z_sub_s/func_8013E640.s,func_8013E640,0x8013E640,0x42 +asm/non_matchings/code/z_sub_s/SubS_FindActorCustom.s,SubS_FindActorCustom,0x8013E640,0x42 asm/non_matchings/code/z_sub_s/func_8013E748.s,func_8013E748,0x8013E748,0x1E asm/non_matchings/code/z_sub_s/func_8013E7C0.s,func_8013E7C0,0x8013E7C0,0x4E asm/non_matchings/code/z_sub_s/func_8013E8F8.s,func_8013E8F8,0x8013E8F8,0x16 @@ -2509,7 +2509,7 @@ asm/non_matchings/code/z_play/func_80166B30.s,func_80166B30,0x80166B30,0x339 asm/non_matchings/code/z_play/func_80167814.s,func_80167814,0x80167814,0x174 asm/non_matchings/code/z_play/func_80167DE4.s,func_80167DE4,0x80167DE4,0x4A asm/non_matchings/code/z_play/func_80167F0C.s,func_80167F0C,0x80167F0C,0x61 -asm/non_matchings/code/z_play/func_80168090.s,func_80168090,0x80168090,0x347 +asm/non_matchings/code/z_play/Play_Draw.s,Play_Draw,0x80168090,0x347 asm/non_matchings/code/z_play/func_80168DAC.s,func_80168DAC,0x80168DAC,0x6E asm/non_matchings/code/z_play/Play_Update.s,Play_Update,0x80168F64,0x5A asm/non_matchings/code/z_play/func_801690CC.s,func_801690CC,0x801690CC,0xD @@ -2770,7 +2770,7 @@ asm/non_matchings/code/sys_math/cos_rad.s,cos_rad,0x80179540,0x15 asm/non_matchings/code/sys_math/Rand_ZeroFloat.s,Rand_ZeroFloat,0x80179594,0xB asm/non_matchings/code/sys_math/randPlusMinusPoint5Scaled.s,randPlusMinusPoint5Scaled,0x801795C0,0xC asm/non_matchings/code/sys_math3d/Math3D_Normalize.s,Math3D_Normalize,0x801795F0,0x22 -asm/non_matchings/code/sys_math3d/func_80179678.s,func_80179678,0x80179678,0x48 +asm/non_matchings/code/sys_math3d/Math3D_PlaneVsLineSegClosestPoint.s,Math3D_PlaneVsLineSegClosestPoint,0x80179678,0x48 asm/non_matchings/code/sys_math3d/func_80179798.s,func_80179798,0x80179798,0xAB asm/non_matchings/code/sys_math3d/func_80179A44.s,func_80179A44,0x80179A44,0x3C asm/non_matchings/code/sys_math3d/func_80179B34.s,func_80179B34,0x80179B34,0x18 @@ -2792,46 +2792,46 @@ asm/non_matchings/code/sys_math3d/Math3D_XZDistanceSquared.s,Math3D_XZDistanceSq asm/non_matchings/code/sys_math3d/Math3D_XZDistance.s,Math3D_XZDistance,0x8017A678,0xC asm/non_matchings/code/sys_math3d/Math3D_LengthSquared.s,Math3D_LengthSquared,0x8017A6A8,0xB asm/non_matchings/code/sys_math3d/Math3D_Vec3fMagnitude.s,Math3D_Vec3fMagnitude,0x8017A6D4,0x9 -asm/non_matchings/code/sys_math3d/Math3D_DistanceSquared.s,Math3D_DistanceSquared,0x8017A6F8,0xA +asm/non_matchings/code/sys_math3d/Math3D_Vec3fDistSq.s,Math3D_Vec3fDistSq,0x8017A6F8,0xA asm/non_matchings/code/sys_math3d/Math3D_Distance.s,Math3D_Distance,0x8017A720,0x8 asm/non_matchings/code/sys_math3d/Math3D_DistanceS.s,Math3D_DistanceS,0x8017A740,0x1E asm/non_matchings/code/sys_math3d/func_8017A7B8.s,func_8017A7B8,0x8017A7B8,0x10 asm/non_matchings/code/sys_math3d/func_8017A7F8.s,func_8017A7F8,0x8017A7F8,0x10 asm/non_matchings/code/sys_math3d/func_8017A838.s,func_8017A838,0x8017A838,0x10 asm/non_matchings/code/sys_math3d/Math3D_CrossProduct.s,Math3D_CrossProduct,0x8017A878,0x1D -asm/non_matchings/code/sys_math3d/Math3D_NormalVector.s,Math3D_NormalVector,0x8017A8EC,0x1A -asm/non_matchings/code/sys_math3d/func_8017A954.s,func_8017A954,0x8017A954,0x2E -asm/non_matchings/code/sys_math3d/func_8017AA0C.s,func_8017AA0C,0x8017AA0C,0x6C -asm/non_matchings/code/sys_math3d/func_8017ABBC.s,func_8017ABBC,0x8017ABBC,0x5F -asm/non_matchings/code/sys_math3d/func_8017AD38.s,func_8017AD38,0x8017AD38,0x255 +asm/non_matchings/code/sys_math3d/Math3D_SurfaceNorm.s,Math3D_SurfaceNorm,0x8017A8EC,0x1A +asm/non_matchings/code/sys_math3d/Math3D_PointRelativeToCubeFaces.s,Math3D_PointRelativeToCubeFaces,0x8017A954,0x2E +asm/non_matchings/code/sys_math3d/Math3D_PointRelativeToCubeEdges.s,Math3D_PointRelativeToCubeEdges,0x8017AA0C,0x6C +asm/non_matchings/code/sys_math3d/Math3D_PointRelativeToCubeVertices.s,Math3D_PointRelativeToCubeVertices,0x8017ABBC,0x5F +asm/non_matchings/code/sys_math3d/Math3D_LineVsCube.s,Math3D_LineVsCube,0x8017AD38,0x255 asm/non_matchings/code/sys_math3d/func_8017B68C.s,func_8017B68C,0x8017B68C,0x5B asm/non_matchings/code/sys_math3d/func_8017B7F8.s,func_8017B7F8,0x8017B7F8,0x23 asm/non_matchings/code/sys_math3d/Math3D_UnitNormalVector.s,Math3D_UnitNormalVector,0x8017B884,0x45 asm/non_matchings/code/sys_math3d/Math3D_SignedDistanceFromPlane.s,Math3D_SignedDistanceFromPlane,0x8017B998,0x10 asm/non_matchings/code/sys_math3d/func_8017B9D8.s,func_8017B9D8,0x8017B9D8,0xF -asm/non_matchings/code/sys_math3d/Math3D_NormalizedDistanceFromPlane.s,Math3D_NormalizedDistanceFromPlane,0x8017BA14,0xE -asm/non_matchings/code/sys_math3d/Math3D_NormalizedSignedDistanceFromPlane.s,Math3D_NormalizedSignedDistanceFromPlane,0x8017BA4C,0x21 -asm/non_matchings/code/sys_math3d/func_8017BAD0.s,func_8017BAD0,0x8017BAD0,0xB2 +asm/non_matchings/code/sys_math3d/Math3D_UDistPlaneToPos.s,Math3D_UDistPlaneToPos,0x8017BA14,0xE +asm/non_matchings/code/sys_math3d/Math3D_DistPlaneToPos.s,Math3D_DistPlaneToPos,0x8017BA4C,0x21 +asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaYDist.s,Math3D_TriChkPointParaYDist,0x8017BAD0,0xB2 asm/non_matchings/code/sys_math3d/func_8017BD98.s,func_8017BD98,0x8017BD98,0x12 asm/non_matchings/code/sys_math3d/func_8017BDE0.s,func_8017BDE0,0x8017BDE0,0x14 -asm/non_matchings/code/sys_math3d/func_8017BE30.s,func_8017BE30,0x8017BE30,0x2C -asm/non_matchings/code/sys_math3d/func_8017BEE0.s,func_8017BEE0,0x8017BEE0,0x2B +asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaYIntersectDist.s,Math3D_TriChkPointParaYIntersectDist,0x8017BE30,0x2C +asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaYIntersectInsideTri.s,Math3D_TriChkPointParaYIntersectInsideTri,0x8017BEE0,0x2B asm/non_matchings/code/sys_math3d/func_8017BF8C.s,func_8017BF8C,0x8017BF8C,0x1F -asm/non_matchings/code/sys_math3d/func_8017C008.s,func_8017C008,0x8017C008,0x5D +asm/non_matchings/code/sys_math3d/Math3D_TriChkLineSegParaYIntersect.s,Math3D_TriChkLineSegParaYIntersect,0x8017C008,0x5D asm/non_matchings/code/sys_math3d/func_8017C17C.s,func_8017C17C,0x8017C17C,0x1D asm/non_matchings/code/sys_math3d/func_8017C1F0.s,func_8017C1F0,0x8017C1F0,0xA9 -asm/non_matchings/code/sys_math3d/func_8017C494.s,func_8017C494,0x8017C494,0x2B -asm/non_matchings/code/sys_math3d/func_8017C540.s,func_8017C540,0x8017C540,0xB2 +asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaYIntersectInsideTri2.s,Math3D_TriChkPointParaYIntersectInsideTri2,0x8017C494,0x2B +asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaXDist.s,Math3D_TriChkPointParaXDist,0x8017C540,0xB2 asm/non_matchings/code/sys_math3d/func_8017C808.s,func_8017C808,0x8017C808,0x12 -asm/non_matchings/code/sys_math3d/func_8017C850.s,func_8017C850,0x8017C850,0x2D +asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaXIntersect.s,Math3D_TriChkPointParaXIntersect,0x8017C850,0x2D asm/non_matchings/code/sys_math3d/func_8017C904.s,func_8017C904,0x8017C904,0x1F -asm/non_matchings/code/sys_math3d/func_8017C980.s,func_8017C980,0x8017C980,0x62 +asm/non_matchings/code/sys_math3d/Math3D_TriChkLineSegParaXIntersect.s,Math3D_TriChkLineSegParaXIntersect,0x8017C980,0x62 asm/non_matchings/code/sys_math3d/func_8017CB08.s,func_8017CB08,0x8017CB08,0x1D -asm/non_matchings/code/sys_math3d/func_8017CB7C.s,func_8017CB7C,0x8017CB7C,0xCB +asm/non_matchings/code/sys_math3d/Math3D_TriChkLineSegParaZDist.s,Math3D_TriChkLineSegParaZDist,0x8017CB7C,0xCB asm/non_matchings/code/sys_math3d/func_8017CEA8.s,func_8017CEA8,0x8017CEA8,0x12 -asm/non_matchings/code/sys_math3d/func_8017CEF0.s,func_8017CEF0,0x8017CEF0,0x2D +asm/non_matchings/code/sys_math3d/Math3D_TriChkPointParaZIntersect.s,Math3D_TriChkPointParaZIntersect,0x8017CEF0,0x2D asm/non_matchings/code/sys_math3d/func_8017CFA4.s,func_8017CFA4,0x8017CFA4,0x1F -asm/non_matchings/code/sys_math3d/func_8017D020.s,func_8017D020,0x8017D020,0x63 +asm/non_matchings/code/sys_math3d/Math3D_TriChkLineSegParaZIntersect.s,Math3D_TriChkLineSegParaZIntersect,0x8017D020,0x63 asm/non_matchings/code/sys_math3d/func_8017D1AC.s,func_8017D1AC,0x8017D1AC,0x1D asm/non_matchings/code/sys_math3d/func_8017D220.s,func_8017D220,0x8017D220,0x37 asm/non_matchings/code/sys_math3d/func_8017D2FC.s,func_8017D2FC,0x8017D2FC,0x42 @@ -2843,7 +2843,7 @@ asm/non_matchings/code/sys_math3d/func_8017D7C0.s,func_8017D7C0,0x8017D7C0,0x15 asm/non_matchings/code/sys_math3d/func_8017D814.s,func_8017D814,0x8017D814,0x42 asm/non_matchings/code/sys_math3d/func_8017D91C.s,func_8017D91C,0x8017D91C,0x42 asm/non_matchings/code/sys_math3d/func_8017DA24.s,func_8017DA24,0x8017DA24,0x42 -asm/non_matchings/code/sys_math3d/Math3D_ColSphereLineSeg.s,Math3D_ColSphereLineSeg,0x8017DB2C,0x82 +asm/non_matchings/code/sys_math3d/Math3D_LineVsSph.s,Math3D_LineVsSph,0x8017DB2C,0x82 asm/non_matchings/code/sys_math3d/func_8017DD34.s,func_8017DD34,0x8017DD34,0x50 asm/non_matchings/code/sys_math3d/Math3D_ColSphereTri.s,Math3D_ColSphereTri,0x8017DE74,0x108 asm/non_matchings/code/sys_math3d/func_8017E294.s,func_8017E294,0x8017E294,0x2F @@ -2858,9 +2858,9 @@ asm/non_matchings/code/sys_math3d/Math3D_ColSphereCylinderDistanceAndAmount.s,Ma asm/non_matchings/code/sys_math3d/Math3D_ColCylinderCylinderAmount.s,Math3D_ColCylinderCylinderAmount,0x8017F45C,0x8 asm/non_matchings/code/sys_math3d/Math3D_ColCylinderCylinderAmountAndDistance.s,Math3D_ColCylinderCylinderAmountAndDistance,0x8017F47C,0x74 asm/non_matchings/code/sys_math3d/Math3d_ColTriTri.s,Math3d_ColTriTri,0x8017F64C,0xDD -asm/non_matchings/code/sys_math3d/func_8017F9C0.s,func_8017F9C0,0x8017F9C0,0x1D -asm/non_matchings/code/sys_math3d/func_8017FA34.s,func_8017FA34,0x8017FA34,0x1D -asm/non_matchings/code/sys_math3d/func_8017FAA8.s,func_8017FAA8,0x8017FAA8,0x1D +asm/non_matchings/code/sys_math3d/Math3D_XZInSphere.s,Math3D_XZInSphere,0x8017F9C0,0x1D +asm/non_matchings/code/sys_math3d/Math3D_XYInSphere.s,Math3D_XYInSphere,0x8017FA34,0x1D +asm/non_matchings/code/sys_math3d/Math3D_YZInSphere.s,Math3D_YZInSphere,0x8017FAA8,0x1D asm/non_matchings/code/sys_math3d/func_8017FB1C.s,func_8017FB1C,0x8017FB1C,0x8A asm/non_matchings/code/sys_math3d/func_8017FD44.s,func_8017FD44,0x8017FD44,0x5B asm/non_matchings/code/sys_math_atan/Math_GetAtan2Tbl.s,Math_GetAtan2Tbl,0x8017FEB0,0xD @@ -3238,8 +3238,8 @@ asm/non_matchings/code/code_80192BE0/func_80194548.s,func_80194548,0x80194548,0x asm/non_matchings/code/code_80192BE0/func_80194568.s,func_80194568,0x80194568,0x40 asm/non_matchings/code/code_80192BE0/func_80194668.s,func_80194668,0x80194668,0x1F asm/non_matchings/code/code_80192BE0/func_801946E4.s,func_801946E4,0x801946E4,0xB -asm/non_matchings/code/code_80194710/func_80194710.s,func_80194710,0x80194710,0x10 -asm/non_matchings/code/code_80194710/func_80194750.s,func_80194750,0x80194750,0x10 +asm/non_matchings/code/code_80194710/Audio_InvalDCache.s,Audio_InvalDCache,0x80194710,0x10 +asm/non_matchings/code/code_80194710/Audio_WritebackDCache.s,Audio_WritebackDCache,0x80194750,0x10 asm/non_matchings/code/code_80194710/func_80194790.s,func_80194790,0x80194790,0x1D asm/non_matchings/code/code_80194710/func_80194804.s,func_80194804,0x80194804,0xF asm/non_matchings/code/code_80194710/func_80194840.s,func_80194840,0x80194840,0x1C diff --git a/tools/vtxdis.c b/tools/vtxdis.c index 1ba696963..8debd89e0 100644 --- a/tools/vtxdis.c +++ b/tools/vtxdis.c @@ -254,4 +254,4 @@ int main(int argc, char **argv) } return 0; -} \ No newline at end of file +} diff --git a/tools/z64compress/.gitrepo b/tools/z64compress/.gitrepo index 9507f81ce..183bfc326 100644 --- a/tools/z64compress/.gitrepo +++ b/tools/z64compress/.gitrepo @@ -6,7 +6,7 @@ [subrepo] remote = https://github.com/z64me/z64compress.git branch = main - commit = 98ef0ac25f7adb47235c839838e29496d3546917 - parent = 69cc19eea8c30e50e280f400e8cf06fe66efca60 + commit = 5da3132606e4fd427a8d72b8428e4f921cd6e56f + parent = 837eb1c80687fe9b57a3c7b841547c33feeed6c7 method = merge cmdver = 0.4.3 diff --git a/tools/z64compress/Makefile b/tools/z64compress/Makefile index bb80891b1..f16167ccd 100644 --- a/tools/z64compress/Makefile +++ b/tools/z64compress/Makefile @@ -1,23 +1,28 @@ CC := gcc -CFLAGS := -DNDEBUG -s -Os -flto -Wall -Wextra -march=native -mtune=native +CFLAGS := -DNDEBUG -s -Os -flto -Wall -Wextra -OBJ_DIR := o - -# Target platform, specify with TARGET= on the command line, linux64 is default +# Target platform, specify with TARGET= on the command line, linux64 is default. # Currently supported: linux64, linux32, win32 TARGET ?= linux64 ifeq ($(TARGET),linux32) TARGET_CFLAGS := -m32 else ifeq ($(TARGET),win32) -# If using a cross compiler, specify the compiler executable on the command line +# If using a cross compiler, specify the compiler executable on the command line. # make TARGET=win32 CC=~/c/mxe/usr/bin/i686-w64-mingw32.static-gcc TARGET_LIBS := -mconsole -municode else ifneq ($(TARGET),linux64) $(error Supported targets: linux64, linux32, win32) endif -OBJ_DIR := $(OBJ_DIR)/$(TARGET) +# Whether to use native optimizations, specify with NATIVE_OPT=0/1 on the command line, default is 0. +# This is not supported by all compilers which is particularly an issue on Mac, and may inhibit tests. +NATIVE_OPT ?= 0 +ifeq ($(NATIVE_OPT),1) + TARGET_CFLAGS += -march=native -mtune=native +endif + +OBJ_DIR := o/$(TARGET) $(OBJ_DIR)/src/enc/%.o: CFLAGS := -DNDEBUG -s -Ofast -flto -Wall diff --git a/tools/z64compress/src/main.c b/tools/z64compress/src/main.c index 71d1d2040..bd044059d 100644 --- a/tools/z64compress/src/main.c +++ b/tools/z64compress/src/main.c @@ -221,7 +221,7 @@ wow_main } } - fprintf(printer, "welcome to z64compress 1.0.1 \n"); + fprintf(printer, "welcome to z64compress 1.0.2 \n"); if (argc <= 1) { @@ -356,7 +356,6 @@ wow_main ARG_ZERO_TEST(Ain , "--in" ); ARG_ZERO_TEST(Aout , "--out" ); - ARG_ZERO_TEST(Amb , "--mb" ); ARG_ZERO_TEST(Acodec, "--codec"); #undef ARG_ZERO_TEST diff --git a/tools/z64compress/src/rom.c b/tools/z64compress/src/rom.c index decf8ca1d..008597b52 100644 --- a/tools/z64compress/src/rom.c +++ b/tools/z64compress/src/rom.c @@ -68,7 +68,9 @@ for (dma = rom->dma; (unsigned)(dma - rom->dma) < rom->dma_num; ++dma) #define PROGRESS_A_B (int)(dma - rom->dma), rom->dma_num -#define ALIGN16(x) (((x) + 0xF) & ~0xF) +#define ALIGN(x, n) (((x) + ((n)-1)) & ~((n)-1)) +#define ALIGN16(x) ALIGN(x, 16) +#define ALIGN8MB(x) ALIGN(x, 8 * 0x100000) /* * @@ -936,7 +938,7 @@ void rom_compress(struct rom *rom, int mb, int numThreads, bool matching) cache = rom->cache; - if (compsz > rom->data_sz || mb <= 0) + if (compsz > rom->data_sz || mb < 0) die("invalid mb argument %d", mb); /* get encoding functions */ @@ -1057,31 +1059,13 @@ void rom_compress(struct rom *rom, int mb, int numThreads, bool matching) /* sort by original start, ascending */ DMASORT(rom, sortfunc_dma_start_ascend); - if (matching) - { - /* fill the entire (compressed) rom space with 00010203...FF... - in order to match retail rom padding */ - unsigned char n = 0; // will intentionally overflow - for (unsigned int j = 0; j < compsz; j++, n++) - { - rom->data[j] = n; - } - } - else - { - /* zero the entire (compressed) rom space */ - memset(rom->data, 0, compsz); - } - - /* go through dma table, injecting compressed files */ + /* determine physical addresses for each segment */ comp_total = 0; DMA_FOR_EACH { - unsigned char *dst; char *fn = dma->compname; unsigned int sz; unsigned int sz16; - fprintf(printer, "\r""injecting file %d/%d: ", PROGRESS_A_B); if (dma->deleted) continue; @@ -1114,9 +1098,6 @@ void rom_compress(struct rom *rom, int mb, int numThreads, bool matching) if (sz16 & 15) sz16 += 16 - (sz16 & 15); - /* put the files in */ - dst = rom->data + comp_total; - dma->Pstart = comp_total; if (dma->compress) { @@ -1130,26 +1111,66 @@ void rom_compress(struct rom *rom, int mb, int numThreads, bool matching) dma->Pend = 0; comp_total += sz16; - if (dma->Pend > compsz) + if (mb != 0 && dma->Pend > compsz) die("ran out of compressed rom space"); + } + + /* adaptive final size */ + if (mb == 0) + compsz = ALIGN8MB(comp_total); + + if (matching) + { + /* fill the entire (compressed) rom space with 00010203...FF... + in order to match retail rom padding */ + unsigned char n = 0; /* will intentionally overflow */ + for (unsigned int j = 0; j < compsz; j++, n++) + { + rom->data[j] = n; + } + } + else + { + /* zero the entire (compressed) rom space */ + memset(rom->data, 0, compsz); + } + + /* inject compressed files */ + comp_total = 0; + DMA_FOR_EACH + { + unsigned char *dst; + char *fn = dma->compname; + unsigned int sz; + fprintf(printer, "\r""injecting file %d/%d: ", PROGRESS_A_B); + + if (dma->deleted) + continue; + + dst = rom->data + dma->Pstart; /* external cached file logic */ if (cache) { + /* skip entries that don't reference compressed files */ + if (!fn) + continue; + /* load file into rom at offset */ dst = file_load_into(cache_codec, fn, &sz, dst); } - /* otherwise, a simple memcpy */ else { memcpy(dst, dma->compbuf, dma->compSz); - if (matching) - { - // since matching rom padding is not zero but file padding is zero, - // fill file padding space with zeros - memset(dst + dma->compSz, 0, ALIGN16(dma->compSz) - dma->compSz); - } + sz = dma->compSz; + } + + if (matching) + { + /* since matching rom padding is not zero but file padding is zero, + fill file padding space with zeros */ + memset(dst + sz, 0, ALIGN16(sz) - sz); } } fprintf(printer, "\r""injecting file %d/%d: ", dma_num, dma_num); diff --git a/tools/z64compress_wrapper.py b/tools/z64compress_wrapper.py index d70db8426..ff2bf1bb6 100644 --- a/tools/z64compress_wrapper.py +++ b/tools/z64compress_wrapper.py @@ -1,15 +1,19 @@ #!/usr/bin/env python3 # # z64compress wrapper for decomp projects -# Arguments: [cache directory] [num threads] +# https://github.com/z64me/z64compress +# Arguments: [--cache [cache directory]] [--threads [num threads]] [--mb [target rom size]] [--matching] +# Example Makefile usage: +# python3 tools/z64compress_wrapper.py --matching --threads $(shell nproc) $< $@ $(ELF) build/$(SPEC) # import argparse, itertools, subprocess, sys + from elftools.elf.elffile import ELFFile from elftools.elf.sections import SymbolTableSection # Args from command line -parser = argparse.ArgumentParser(description="Compress rom produced by the OoT Decomp project") +parser = argparse.ArgumentParser(description="Compress rom produced by the OoT and MM Decomp projects") parser.add_argument("in_rom", help="uncompressed input rom filename") parser.add_argument("out_rom", help="compressed output rom filename") @@ -17,7 +21,7 @@ parser.add_argument("elf", help="path to the uncompressed rom elf file") parser.add_argument("spec", help="path to processed spec file") parser.add_argument("--cache", help="cache directory") parser.add_argument("--threads", help="number of threads to run compression on, 0 disables multithreading") -parser.add_argument("--mb", help="compressed rom size in MB, default 32") +parser.add_argument("--mb", help="compressed rom size in MB, default is the smallest multiple of 8mb fitting the whole rom") parser.add_argument("--matching", help="matching compression, forfeits some useful optimizations", action="store_true") parser.add_argument("--stderr", help="z64compress will write its output messages to stderr instead of stdout", action="store_true") @@ -26,14 +30,13 @@ args = parser.parse_args() IN_ROM = args.in_rom OUT_ROM = args.out_rom -STDOUT = not args.stderr - elf_path = args.elf CACHE_DIR = args.cache N_THREADS = int(args.threads or 0) -MB = int(args.mb or 32) -matching = args.matching +MB = args.mb +MATCHING = args.matching +STDOUT = not args.stderr # Get segments to compress @@ -83,8 +86,8 @@ def get_dmadata_start_len(): if dmadata_start != -1 and dmadata_end != -1: break - assert dmadata_start != -1 - assert dmadata_end != -1 + assert dmadata_start != -1, "_dmadataSegmentRomStart symbol not found in supplied ELF" + assert dmadata_end != -1, "_dmadataSegmentRomEnd symbol not found in supplied ELF" return dmadata_start, (dmadata_end - dmadata_start)//0x10 @@ -92,13 +95,21 @@ DMADATA_ADDR, DMADATA_COUNT = get_dmadata_start_len() # Run -cmd = f"./tools/z64compress/z64compress --in {IN_ROM} --out {OUT_ROM}{' --matching' if matching else ''} \ ---mb {MB} --codec yaz{f' --cache {CACHE_DIR}' if CACHE_DIR is not None else ''} --dma 0x{DMADATA_ADDR:X},{DMADATA_COUNT} \ ---compress {COMPRESS_INDICES}{f' --threads {N_THREADS}' if N_THREADS > 0 else ''}{f' --only-stdout' if STDOUT else ''}" +cmd = f"./tools/z64compress/z64compress \ +--in {IN_ROM} \ +--out {OUT_ROM}\ +{' --matching' if MATCHING else ''}\ +{f' --mb {MB}' if MB is not None else ''} \ +--codec yaz\ +{f' --cache {CACHE_DIR}' if CACHE_DIR is not None else ''} \ +--dma 0x{DMADATA_ADDR:X},{DMADATA_COUNT} \ +--compress {COMPRESS_INDICES}\ +{f' --threads {N_THREADS}' if N_THREADS > 0 else ''}\ +{f' --only-stdout' if STDOUT else ''}" print(cmd) - try: subprocess.check_call(cmd, shell=True) except subprocess.CalledProcessError as e: + # Return the same error code for the wrapper if z64compress fails sys.exit(e.returncode) diff --git a/undefined_syms.txt b/undefined_syms.txt index d54482337..5fe1bfcac 100644 --- a/undefined_syms.txt +++ b/undefined_syms.txt @@ -4,8 +4,8 @@ D_80000000 = 0x80000000; // __osExceptionPreamble D_80000004 = 0x80000004; // __osExceptionPreamble D_80000008 = 0x80000008; // __osExceptionPreamble D_8000000C = 0x8000000C; // __osExceptionPreamble -D_80000010 = 0x80000010; // -D_80000020 = 0x80000020; // +D_80000010 = 0x80000010; // +D_80000020 = 0x80000020; // osTvType = 0x80000300; osRomType = 0x80000304; @@ -127,6 +127,11 @@ D_A4800018 = 0xA4800018; // SI_STATUS_REG gFramebuffer1 = 0x80000500; D_80025D00 = 0x80025D00; +// Ucode symbols + +rspbootTextSize = 0x160; +rspbootTextEnd = rspbootTextStart + rspbootTextSize; + // Segmented Addresses // segment 0x01 @@ -603,6 +608,24 @@ D_06011AB8 = 0x06011AB8; D_06012A80 = 0x06012A80; D_06013138 = 0x06013138; +// z_en_hy.c +D_0600007C = 0x0600007C; +D_0600066C = 0x0600066C; +D_0600071C = 0x0600071C; +D_060008C0 = 0x060008C0; +D_06000AB0 = 0x06000AB0; +D_06000FDC = 0x06000FDC; +D_06001494 = 0x06001494; +D_06001908 = 0x06001908; +D_06001EE0 = 0x06001EE0; +D_06005DC4 = 0x06005DC4; +D_06005D9C = 0x06005D9C; +D_0600DED8 = 0x0600DED8; +D_0600F920 = 0x0600F920; +D_0600FC1C = 0x0600FC1C; +D_0600FEE4 = 0x0600FEE4; +D_06010330 = 0x06010330; + // ovl_Arms_Hook D_0601D960 = 0x0601D960; @@ -858,6 +881,15 @@ D_06013058 = 0x06013058; D_060006B0 = 0x060006B0; D_060016DC = 0x060016DC; +// ovl_Bg_Inibs_Movebg + +D_06001C10 = 0x06001C10; +D_06001DC0 = 0x06001DC0; +D_06002598 = 0x06002598; +D_06006140 = 0x06006140; +D_060062D8 = 0x060062D8; +D_06006858 = 0x06006858; + // ovl_Bg_Keikoku_Saku D_06001640 = 0x06001640; @@ -1055,13 +1087,6 @@ D_06009C14 = 0x06009C14; D_06009CF8 = 0x06009CF8; D_0600A6C8 = 0x0600A6C8; -// ovl_Boss_04 - -D_0600004C = 0x0600004C; -D_06004510 = 0x06004510; -D_06004550 = 0x06004550; -D_060045E8 = 0x060045E8; - // ovl_Boss_05 D_060006A4 = 0x060006A4; @@ -1339,10 +1364,26 @@ D_06001788 = 0x06001788; // ovl_Dm_Stk +D_0600055C = 0x0600055C; +D_06001030 = 0x06001030; +D_0600130C = 0x0600130C; +D_06001374 = 0x06001374; +D_06001EDC = 0x06001EDC; +D_06002774 = 0x06002774; +D_06002CD8 = 0x06002CD8; +D_06003068 = 0x06003068; +D_060035C8 = 0x060035C8; +D_060039F0 = 0x060039F0; +D_06004554 = 0x06004554; +D_06004580 = 0x06004580; D_060046B0 = 0x060046B0; +D_060049C8 = 0x060049C8; +D_060051C0 = 0x060051C0; D_060053C0 = 0x060053C0; D_06005870 = 0x06005870; +D_06005F44 = 0x06005F44; D_06006BB0 = 0x06006BB0; +D_060070DC = 0x060070DC; D_06007840 = 0x06007840; D_060079F0 = 0x060079F0; D_060084C0 = 0x060084C0; @@ -1357,9 +1398,61 @@ D_0600A530 = 0x0600A530; D_0600A5C0 = 0x0600A5C0; D_0600AE30 = 0x0600AE30; D_0600AEC0 = 0x0600AEC0; +D_0600BB2C = 0x0600BB2C; +D_0600C270 = 0x0600C270; +D_0600C964 = 0x0600C964; D_0600CAD0 = 0x0600CAD0; +D_0600CBB8 = 0x0600CBB8; +D_0600D830 = 0x0600D830; +D_0600E6EC = 0x0600E6EC; +D_0600EEC0 = 0x0600EEC0; +D_060101A4 = 0x060101A4; +D_06010B60 = 0x06010B60; +D_060110B4 = 0x060110B4; +D_06011FB0 = 0x06011FB0; +D_06012A58 = 0x06012A58; D_06013328 = 0x06013328; +D_060141E4 = 0x060141E4; +D_06014920 = 0x06014920; +D_06015028 = 0x06015028; +D_06015C14 = 0x06015C14; +D_06016508 = 0x06016508; D_06016620 = 0x06016620; +D_06016910 = 0x06016910; +D_06018ED0 = 0x06018ED0; +D_0601AA80 = 0x0601AA80; +D_0601C114 = 0x0601C114; +D_0601C21C = 0x0601C21C; +D_0601D008 = 0x0601D008; +D_0601D07C = 0x0601D07C; +D_0601D3D0 = 0x0601D3D0; +D_0601DDE0 = 0x0601DDE0; +D_0601EF50 = 0x0601EF50; +D_0601F9E4 = 0x0601F9E4; +D_06020CAC = 0x06020CAC; +D_0602200C = 0x0602200C; +D_0602336C = 0x0602336C; +D_060259F4 = 0x060259F4; +D_060266C8 = 0x060266C8; +D_06026CF4 = 0x06026CF4; +D_06027CF4 = 0x06027CF4; +D_06028F28 = 0x06028F28; +D_06029A04 = 0x06029A04; +D_0602A2D8 = 0x0602A2D8; +D_0602AD54 = 0x0602AD54; +D_0602DC64 = 0x0602DC64; +D_0602E9A0 = 0x0602E9A0; +D_0602FA70 = 0x0602FA70; +D_0603021C = 0x0603021C; +D_06031210 = 0x06031210; +D_060322FC = 0x060322FC; +D_06032AE0 = 0x06032AE0; +D_0603323C = 0x0603323C; +D_06034FD8 = 0x06034FD8; +D_06036964 = 0x06036964; +D_06037B94 = 0x06037B94; +D_0603967C = 0x0603967C; +D_0603A8F8 = 0x0603A8F8; // ovl_Dm_Tsg @@ -1388,17 +1481,12 @@ D_06013EA8 = 0x06013EA8; // ovl_Door_Warp1 -D_060001A0 = 0x060001A0; -D_06001374 = 0x06001374; -D_06002CA8 = 0x06002CA8; D_06003230 = 0x06003230; D_060044D8 = 0x060044D8; D_06004690 = 0x06004690; D_060057D8 = 0x060057D8; D_060058C8 = 0x060058C8; D_06007238 = 0x06007238; -D_060076C0 = 0x060076C0; -D_06008BD4 = 0x06008BD4; // ovl_Effect_En_Ice_Block @@ -1446,13 +1534,6 @@ D_06000F38 = 0x06000F38; D_06009E70 = 0x06009E70; -// ovl_En_Akindonuts - -D_06001350 = 0x06001350; -D_06005488 = 0x06005488; -D_06008290 = 0x06008290; -D_0600AC70 = 0x0600AC70; - // ovl_En_Al D_0600A0D8 = 0x0600A0D8; @@ -1488,11 +1569,6 @@ D_060028A0 = 0x060028A0; D_06009220 = 0x06009220; D_06009D34 = 0x06009D34; -// ovl_En_Aob_01 - -D_06000180 = 0x06000180; -D_06003D18 = 0x06003D18; - // ovl_En_Attack_Niw D_060000E8 = 0x060000E8; @@ -1512,13 +1588,6 @@ D_06005EF0 = 0x06005EF0; D_06006B10 = 0x06006B10; D_060092A0 = 0x060092A0; -// ovl_En_Baguo - -D_060014C8 = 0x060014C8; -D_060018C8 = 0x060018C8; -D_06001CC8 = 0x06001CC8; -D_060020E8 = 0x060020E8; - // ovl_En_Baisen D_060008B4 = 0x060008B4; @@ -1585,49 +1654,6 @@ D_06004210 = 0x06004210; D_06007C70 = 0x06007C70; D_0600823C = 0x0600823C; -// ovl_En_Bigpo - -D_06000454 = 0x06000454; -D_06000924 = 0x06000924; -D_06001360 = 0x06001360; -D_06001BB0 = 0x06001BB0; -D_060041A0 = 0x060041A0; -D_060042C8 = 0x060042C8; -D_060043F8 = 0x060043F8; -D_060058B8 = 0x060058B8; -D_06005C18 = 0x06005C18; - -// ovl_En_Bigslime - -D_060010F4 = 0x060010F4; -D_06001B08 = 0x06001B08; -D_0600276C = 0x0600276C; -D_06002E0C = 0x06002E0C; -D_0600347C = 0x0600347C; -D_060039C4 = 0x060039C4; -D_06003F28 = 0x06003F28; -D_060066B4 = 0x060066B4; -D_060069FC = 0x060069FC; -D_060070C4 = 0x060070C4; -D_06007790 = 0x06007790; -D_0600DF98 = 0x0600DF98; -D_0600F048 = 0x0600F048; -D_0600F3F0 = 0x0600F3F0; -D_0600F990 = 0x0600F990; -D_0600F9D0 = 0x0600F9D0; -D_0600FB40 = 0x0600FB40; -D_06010530 = 0x06010530; -D_060105E8 = 0x060105E8; -D_06010B80 = 0x06010B80; -D_06010C48 = 0x06010C48; -D_06010DB0 = 0x06010DB0; -D_06010EC8 = 0x06010EC8; -D_06010F20 = 0x06010F20; -D_06010FE0 = 0x06010FE0; -D_06011008 = 0x06011008; -D_06011050 = 0x06011050; -D_060113B0 = 0x060113B0; - // ovl_En_Bji_01 D_0600066C = 0x0600066C; @@ -1664,11 +1690,6 @@ D_06000340 = 0x06000340; D_06000408 = 0x06000408; D_06000530 = 0x06000530; -// ovl_En_Bomjima - -D_060064B8 = 0x060064B8; -D_0600F82C = 0x0600F82C; - // ovl_En_Bomjimb D_060064B8 = 0x060064B8; @@ -2144,21 +2165,6 @@ D_0600A490 = 0x0600A490; D_06010240 = 0x06010240; -// ovl_En_Fall - -D_06000198 = 0x06000198; -D_06000400 = 0x06000400; -D_060004C0 = 0x060004C0; -D_060004C8 = 0x060004C8; -D_060010E0 = 0x060010E0; -D_06001158 = 0x06001158; -D_060011D0 = 0x060011D0; -D_06001220 = 0x06001220; -D_06002970 = 0x06002970; -D_06003C30 = 0x06003C30; -D_06004E38 = 0x06004E38; -D_060077F0 = 0x060077F0; - // ovl_En_Fall2 D_06005EF4 = 0x06005EF4; @@ -2199,48 +2205,8 @@ D_06006190 = 0x06006190; // ovl_En_Fishing -D_0600007C = 0x0600007C; -D_060029C0 = 0x060029C0; -D_06003230 = 0x06003230; -D_06003460 = 0x06003460; -D_060034C0 = 0x060034C0; -D_06003610 = 0x06003610; -D_06003680 = 0x06003680; -D_06003710 = 0x06003710; -D_06003760 = 0x06003760; -D_060039A8 = 0x060039A8; -D_06003A18 = 0x06003A18; -D_0600453C = 0x0600453C; -D_06007350 = 0x06007350; -D_060074C8 = 0x060074C8; -D_060085F8 = 0x060085F8; -D_06008610 = 0x06008610; -D_06008678 = 0x06008678; -D_060088C0 = 0x060088C0; -D_06008970 = 0x06008970; -D_0600B950 = 0x0600B950; -D_0600B9C0 = 0x0600B9C0; -D_0600C220 = 0x0600C220; -D_0600C298 = 0x0600C298; D_0600CFE0 = 0x0600CFE0; D_06011058 = 0x06011058; -D_06011070 = 0x06011070; -D_06011170 = 0x06011170; -D_06011270 = 0x06011270; -D_060113D0 = 0x060113D0; -D_06011410 = 0x06011410; -D_06012160 = 0x06012160; -D_060121F0 = 0x060121F0; -D_06013330 = 0x06013330; -D_060133B0 = 0x060133B0; -D_06013590 = 0x06013590; -D_06013610 = 0x06013610; -D_06013F50 = 0x06013F50; -D_06013FD0 = 0x06013FD0; -D_06014030 = 0x06014030; -D_060140B0 = 0x060140B0; -D_060153D0 = 0x060153D0; -D_06015470 = 0x06015470; // ovl_En_Floormas @@ -2305,11 +2271,6 @@ D_060015C0 = 0x060015C0; D_060023D4 = 0x060023D4; D_06002720 = 0x06002720; -// ovl_En_Gb2 - -D_0600049C = 0x0600049C; -D_06007230 = 0x06007230; - // ovl_En_Ge1 D_06002B98 = 0x06002B98; @@ -2330,13 +2291,6 @@ D_0600A344 = 0x0600A344; D_06001EFC = 0x06001EFC; D_0600A808 = 0x0600A808; -// ovl_En_Geg - -D_06004DB0 = 0x06004DB0; -D_060091A8 = 0x060091A8; -D_06011AC8 = 0x06011AC8; -D_06012DE0 = 0x06012DE0; - // ovl_En_Gg D_0600F578 = 0x0600F578; @@ -2347,30 +2301,6 @@ D_0600F6C0 = 0x0600F6C0; D_0600F578 = 0x0600F578; D_0600F6C0 = 0x0600F6C0; -// ovl_En_Giant - -D_06002168 = 0x06002168; -D_06005A80 = 0x06005A80; -D_06006280 = 0x06006280; -D_06006A80 = 0x06006A80; -D_06007610 = 0x06007610; -D_060079B0 = 0x060079B0; -D_06008394 = 0x06008394; -D_060096E4 = 0x060096E4; -D_0600A1C4 = 0x0600A1C4; -D_0600ACA4 = 0x0600ACA4; -D_0600B784 = 0x0600B784; -D_0600C5D4 = 0x0600C5D4; -D_0600D040 = 0x0600D040; -D_0600DE84 = 0x0600DE84; -D_060102A4 = 0x060102A4; -D_060116E4 = 0x060116E4; -D_06012A38 = 0x06012A38; -D_06013004 = 0x06013004; -D_06013FE8 = 0x06013FE8; -D_06015334 = 0x06015334; -D_06017944 = 0x06017944; - // ovl_En_Ginko_Man D_060008C0 = 0x060008C0; @@ -2390,24 +2320,24 @@ D_060079C0 = 0x060079C0; // ovl_En_Gm +D_06005028 = 0x06005028; +D_060054A8 = 0x060054A8; +D_06005CE8 = 0x06005CE8; +D_06006828 = 0x06006828; +D_06006C68 = 0x06006C68; D_06007528 = 0x06007528; D_060078B0 = 0x060078B0; - -// ovl_En_Go - -D_060003D0 = 0x060003D0; -D_06000458 = 0x06000458; -D_060008C0 = 0x060008C0; -D_06000948 = 0x06000948; -D_06000D50 = 0x06000D50; -D_06000DD8 = 0x06000DD8; -D_06001560 = 0x06001560; -D_060031A0 = 0x060031A0; -D_06003258 = 0x06003258; -D_060091A8 = 0x060091A8; -D_06011AC8 = 0x06011AC8; -D_06014CF0 = 0x06014CF0; -D_06014D00 = 0x06014D00; +D_06008090 = 0x06008090; +D_0600898C = 0x0600898C; +D_06009450 = 0x06009450; +D_06009CDC = 0x06009CDC; +D_0600A5E0 = 0x0600A5E0; +D_0600A70C = 0x0600A70C; +D_0600AD18 = 0x0600AD18; +D_0600B8B0 = 0x0600B8B0; +D_0600B990 = 0x0600B990; +D_0600BA80 = 0x0600BA80; +D_0600C03C = 0x0600C03C; // ovl_En_Goroiwa @@ -2670,10 +2600,6 @@ D_06012FC8 = 0x06012FC8; D_06013928 = 0x06013928; D_06016588 = 0x06016588; -// ovl_En_Ishi - -D_060009B0 = 0x060009B0; - // ovl_En_Ja D_0600BA30 = 0x0600BA30; @@ -2733,23 +2659,6 @@ D_0600686C = 0x0600686C; D_060081A4 = 0x060081A4; D_06000214 = 0x06000214; -// ovl_En_Kame - -D_060008B4 = 0x060008B4; -D_06000AF4 = 0x06000AF4; -D_06000B30 = 0x06000B30; -D_06001A50 = 0x06001A50; -D_06001C68 = 0x06001C68; -D_06002510 = 0x06002510; -D_060027D8 = 0x060027D8; -D_06002F88 = 0x06002F88; -D_060031DC = 0x060031DC; -D_060035EC = 0x060035EC; -D_060039C0 = 0x060039C0; -D_06004210 = 0x06004210; -D_06007C70 = 0x06007C70; -D_0600823C = 0x0600823C; - // ovl_En_Kanban D_06000C30 = 0x06000C30; @@ -3154,42 +3063,10 @@ D_06006EE8 = 0x06006EE8; D_060072E8 = 0x060072E8; D_060073E8 = 0x060073E8; -// ovl_En_Pametfrog - -D_06000994 = 0x06000994; -D_06001B08 = 0x06001B08; -D_06001E14 = 0x06001E14; -D_06001F20 = 0x06001F20; -D_060030E4 = 0x060030E4; -D_0600347C = 0x0600347C; -D_060039C4 = 0x060039C4; -D_06003F28 = 0x06003F28; -D_06004298 = 0x06004298; -D_06004680 = 0x06004680; -D_06004894 = 0x06004894; -D_06004D50 = 0x06004D50; -D_060050B8 = 0x060050B8; -D_060052EC = 0x060052EC; -D_06005694 = 0x06005694; -D_06005D54 = 0x06005D54; -D_060066B4 = 0x060066B4; -D_060070C4 = 0x060070C4; -D_0600DF98 = 0x0600DF98; -D_0600F048 = 0x0600F048; -D_0600F990 = 0x0600F990; - // ovl_En_Paper D_0600D5A0 = 0x0600D5A0; -// ovl_En_Peehat - -D_06000350 = 0x06000350; -D_060005C4 = 0x060005C4; -D_06000844 = 0x06000844; -D_060009C4 = 0x060009C4; -D_06001C80 = 0x06001C80; - // ovl_En_Pm D_06008348 = 0x06008348; @@ -3323,11 +3200,6 @@ D_06001600 = 0x06001600; D_060009C4 = 0x060009C4; D_06000F1C = 0x06000F1C; -// ovl_En_Rail_Skb - -D_06005EF8 = 0x06005EF8; -D_060064E0 = 0x060064E0; - // ovl_En_Rat D_06000174 = 0x06000174; @@ -3360,6 +3232,9 @@ D_06001384 = 0x06001384; D_06009890 = 0x06009890; D_0600A280 = 0x0600A280; D_0600AD98 = 0x0600AD98; +D_0600F8F0 = 0x0600F8F0; +D_0600FCF0 = 0x0600FCF0; +D_060100F0 = 0x060100F0; D_06011B60 = 0x06011B60; // ovl_En_Rg @@ -3384,11 +3259,6 @@ D_06009220 = 0x06009220; D_0600C700 = 0x0600C700; -// ovl_En_Ruppecrow - -D_060000F0 = 0x060000F0; -D_060010C0 = 0x060010C0; - // ovl_En_Rz D_06003A20 = 0x06003A20; @@ -3502,17 +3372,7 @@ D_06011038 = 0x06011038; // ovl_En_Ssh -D_060000D8 = 0x060000D8; D_06000304 = 0x06000304; -D_06001494 = 0x06001494; -D_06005210 = 0x06005210; -D_06005850 = 0x06005850; -D_06005F78 = 0x06005F78; -D_06006470 = 0x06006470; - -// ovl_En_St - -D_06005298 = 0x06005298; // ovl_En_Sth @@ -3535,10 +3395,6 @@ D_0600D640 = 0x0600D640; D_06006C18 = 0x06006C18; D_0600D640 = 0x0600D640; -// ovl_En_Stream - -D_06000950 = 0x06000950; - // ovl_En_Suttari D_0600071C = 0x0600071C; @@ -3622,13 +3478,6 @@ D_06009890 = 0x06009890; D_0600A280 = 0x0600A280; D_0600AD98 = 0x0600AD98; -// ovl_En_Talk_Gibud - -D_060053E8 = 0x060053E8; -D_06009298 = 0x06009298; -D_0600ABE0 = 0x0600ABE0; -D_06010B88 = 0x06010B88; - // ovl_En_Tanron2 D_06003450 = 0x06003450; @@ -3760,11 +3609,8 @@ D_0600FEF0 = 0x0600FEF0; // ovl_En_Tru -D_06001F90 = 0x06001F90; -D_060020C8 = 0x060020C8; D_0601A820 = 0x0601A820; D_0601A830 = 0x0601A830; -D_0601AA60 = 0x0601AA60; // ovl_En_Tru_Mt @@ -3807,22 +3653,6 @@ D_0600A054 = 0x0600A054; D_06000EC0 = 0x06000EC0; -// ovl_En_Water_Effect - -D_06000420 = 0x06000420; -D_06000730 = 0x06000730; -D_06000A48 = 0x06000A48; -D_06000CD8 = 0x06000CD8; -D_06000DE0 = 0x06000DE0; -D_06000E0C = 0x06000E0C; -D_06000E40 = 0x06000E40; -D_06000E58 = 0x06000E58; -D_06004260 = 0x06004260; -D_060042B0 = 0x060042B0; -D_060042F8 = 0x060042F8; -D_06004340 = 0x06004340; -D_060043E8 = 0x060043E8; - // ovl_En_Wdhand D_060000F4 = 0x060000F4; @@ -3867,18 +3697,6 @@ D_06001690 = 0x06001690; D_06005870 = 0x06005870; D_06005C64 = 0x06005C64; -// ovl_En_Wiz_Fire - -D_06000E70 = 0x06000E70; -D_06000FD8 = 0x06000FD8; -D_06002630 = 0x06002630; -D_06002B40 = 0x06002B40; -D_06003120 = 0x06003120; -D_06003640 = 0x06003640; -D_06003FC0 = 0x06003FC0; -D_06005190 = 0x06005190; -D_06005750 = 0x06005750; - // ovl_En_Wood02 D_06000700 = 0x06000700; @@ -3907,12 +3725,6 @@ D_06000D94 = 0x06000D94; D_06007650 = 0x06007650; D_0600D658 = 0x0600D658; -// ovl_En_Zog - -D_0600FC0C = 0x0600FC0C; -D_060280A8 = 0x060280A8; -D_06029170 = 0x06029170; - // ovl_En_Zoraegg D_060005D4 = 0x060005D4; @@ -4084,13 +3896,6 @@ D_06003440 = 0x06003440; D_06000158 = 0x06000158; D_06001C00 = 0x06001C00; -// ovl_Obj_Flowerpot - -D_060012E0 = 0x060012E0; -D_06001408 = 0x06001408; -D_060014F0 = 0x060014F0; -D_060015B0 = 0x060015B0; - // ovl_Obj_Funen D_060000D0 = 0x060000D0; @@ -4133,14 +3938,6 @@ D_06001D10 = 0x06001D10; D_060003B8 = 0x060003B8; D_060011B0 = 0x060011B0; -// ovl_Obj_Hugebombiwa - -D_060009E0 = 0x060009E0; -D_06001820 = 0x06001820; -D_06001990 = 0x06001990; -D_06002F60 = 0x06002F60; -D_06003110 = 0x06003110; - // ovl_Obj_Hunsui D_06000220 = 0x06000220; @@ -4149,14 +3946,6 @@ D_06000C74 = 0x06000C74; D_06000EC0 = 0x06000EC0; D_06001888 = 0x06001888; -// ovl_Obj_Iceblock - -D_060001A0 = 0x060001A0; -D_06000328 = 0x06000328; -D_06000438 = 0x06000438; -D_060007F0 = 0x060007F0; -D_060009D0 = 0x060009D0; - // ovl_Obj_Jgame_Light D_060003A0 = 0x060003A0; @@ -4175,17 +3964,6 @@ D_06000180 = 0x06000180; D_06003478 = 0x06003478; D_0600805C = 0x0600805C; -// ovl_Obj_Kibako - -D_06001180 = 0x06001180; -D_06001A70 = 0x06001A70; - -// ovl_Obj_Kibako2 - -D_06000960 = 0x06000960; -D_06000B70 = 0x06000B70; -D_06001040 = 0x06001040; - // ovl_Obj_Kzsaku D_06000040 = 0x06000040; @@ -4257,11 +4035,6 @@ D_060011E0 = 0x060011E0; D_06001C00 = 0x06001C00; -// ovl_Obj_Snowball - -D_060082D0 = 0x060082D0; -D_06008B90 = 0x06008B90; - // ovl_Obj_Snowball2 D_06008B90 = 0x06008B90; @@ -4295,26 +4068,6 @@ D_06001CB0 = 0x06001CB0; D_06001400 = 0x06001400; -// ovl_Obj_Tokeidai - -D_06009A08 = 0x06009A08; -D_0600B0C0 = 0x0600B0C0; -D_0600B208 = 0x0600B208; -D_0600BA78 = 0x0600BA78; -D_0600BEE8 = 0x0600BEE8; -D_0600C368 = 0x0600C368; -D_0600CF28 = 0x0600CF28; -D_0600D388 = 0x0600D388; -D_0600D8E0 = 0x0600D8E0; -D_0600D8E8 = 0x0600D8E8; -D_0600E818 = 0x0600E818; -D_0600F518 = 0x0600F518; - -// ovl_Obj_Tokei_Step - -D_06000088 = 0x06000088; -D_06000968 = 0x06000968; - // ovl_Obj_Tokei_Turret D_06002508 = 0x06002508; @@ -4373,7 +4126,7 @@ D_060012E8 = 0x060012E8; D_06000360 = 0x06000360; D_06001428 = 0x06001428; -// ovl_Player_Actor +// ovl_player_actor D_06008860 = 0x06008860; D_0600BDD8 = 0x0600BDD8;